Function.implement({

	bindAsEventListener: function(bind, args){
		return this.create({'bind': bind, 'event': true, 'arguments': args});
	}

});

Element.implement({
	
	effect: function(property, options){
		return new Fx.Tween(this, $extend({property: property}, options));
	},

	//Override the normal function to fix a bug with not sending blank form fields.
	toQueryString: function(){
		var queryString = [];
		this.getElements('input, select, textarea').each(function(el){
			if (!el.name || el.disabled) return;
			var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){
				return opt.value;
			}) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value;
			$splat(value).each(function(val){
				if (val != null) queryString.push(el.name + '=' + encodeURIComponent(val));
			});
		});
		return queryString.join('&');
	},
	
	toggle: function() {
	    (this.getStyle('display') != 'none') ? this.setStyle('display', 'none') : this.setStyle('display', '');
	    return this;
    },
	hide: function() {
		this.setStyle('display', 'none');
	    return this;
	},
	show: function() {
	    this.setStyle('display', '');
	    return this;
	},
	shake: function() {
	    var begin = this.getPosition().x;
		//var begin = 10;
	    var a = begin - 10;
	    var b = begin + 10;
	    //var fx = this.effect('left', {duration: 100});
	 	var fx = new Fx.Tween(this, $extend({property: 'left'}, {duration: 100}));
	    fx.start(begin, b).chain(function() {fx.start(b, a)}).chain(function() {fx.start(a, b)}).chain(function() {fx.start(b, a)}).chain(function() {fx.start(a, b)}).chain(function() {fx.start(b,begin)});
	}
});

var Request = new Class ({	
	
	Extends: Request,
	
    send: function(options) {
        if (this.options.timeout) {
            //this.timeoutTimer = window.setTimeout(this.callTimeout.bindAsEventListener(this), this.options.timeout);
			this.timeoutTimer = window.setTimeout(this.callTimeout.create({'bind': this, 'event': true, 'arguments': ''}), this.options.timeout);
			this.addEvent('complete', this.removeTimer);
        }
        this.parent(options);
    },
    callTimeout: function() {
        this.xhr.abort();
        if (this.options.onTimeout) {
            this.options.onTimeout();
        }
    },
    removeTimer: function() {
        window.clearTimeout(this.timeoutTimer);
    }
});

//Done to set a new preventDefault value.
Drag.implement({
	options: {
		snap: 6,
		unit: 'px',
		grid: false,
		style: true,
		limit: false,
		handle: false,
		invert: false,
		preventDefault: true,
		modifiers: {x: 'left', y: 'top'}
	}
});
