/*
 * Elementを拡張する。
 */
Element.getLeft = function(element) {
  return parseInt(element.style.left.replace('px', ''));
}

Element.getTop = function(element) {
  return parseInt(element.style.top.replace('px', ''));
}

/*
 * Dateを拡張する。
 */
Object.extend(Date.prototype, {
  shift: function(day) {
    return new Date(this.getTime() + day * 86400000);
  },

  tomorrow: function() {
    return this.shift(1);
  },

  yesterday: function() {
    return this.shift(-1);
  },

  between: function(date) {
    return Math.floor(Math.abs(this.getTime() - date.getTime()) / 86400000);
  },

  before: function(date) {
    return this.getTime() >= date.getTime();
  },

  after: function(date) {
    return this.getTime() <= date.getTime();
  },

  getDayFromMonday: function() {
    var day = this.getDay();

    return (day == 0) ? 6 : day - 1;
  },
  
  midnight: function() {
    return new Date(this.getFullYear(), this.getMonth(), this.getDate());
  }
});

/*
 * Droppables.isAffectedを修正する。
 */
if (Droppables) {
  Droppables.isAffected = function(point, element, drop) {
    Position.prepare();

    return (
      (drop.element!=element) &&
      ((!drop._containers) ||
        this.isContained(element, drop)) &&
      ((!drop.accept) ||
        (Element.classNames(element).detect(
          function(v) { return drop.accept.include(v) } ) )) &&
      Position.withinIncludingScrolloffsets(drop.element, point[0], point[1]) );
  }
}

/*
 * Hashを拡張する。
 */
if (Hash) {
  Hash.toQueryStringForRails = function(object) {
    return new JsonParser().toQueryStringForRails(object);
  }
   
  var JsonParser = Class.create();
  
  JsonParser.prototype = {
    params: [],
    keys: [],
  
    initialize: function() {
      this.params = [];
      this.keys = [];
    },
  
    toQueryStringForRails: function(object) {
      this.parseObject(object);

      return this.params.join('&');
    },
  
    parseObject: function(object) {
      for (var key in object) {
        var value = object[key];
  
        this.addKey(key);
  
        if (value instanceof Array) {
          this.parseArray.apply(this, [value]);
        } else if (value instanceof Object) {
          this.parseObject.apply(this, [value]);
        } else {
          this.addParameter.apply(this, [value]);
        }
  
        this.removeKey();
      }
    },
  
    parseArray: function(array) {
      this.addKey();
  
      for (var i = 0, len = array.length; i < len; i++) {
        var value = array[i];
  
        if (value instanceof Array) {
          this.parseArray.apply(this, [value]);
        } else if (value instanceof Object) {
          this.parseObject.apply(this, [value]);
        } else {
          this.addParameter.apply(this, [value]);
        }
      }
  
      this.removeKey();
    },
    
    addKey: function(key) {
      var length = this.keys.length;
      
      key = key || '';
      this.keys[length] = (length > 0) ? '[' + key + ']' : key;
    },
    
    removeKey: function() {
      this.keys.length--;
    },
  
    addParameter: function(value) {
      this.params.push(this.keys.join('') + '=' + value);
    }
  };
}

