var Resizable = new Class({
	
	Extends: Drag,

		options: {
			/* onSet: $empty, */
			limit: {
				x:[0,null],
				y:[0,null]
			},
			mode: 'horizontal',
			addToResizableLimits: true,
			cookie: false
		},

	initialize: function(element,options){
		this.parent(element,options);
		this.parentElement = this.element.getParent();
		if(this.options.mode == 'horizontal'){
			this.isHorizontal = true;
			this.options.modifiers.y = false;
			this.firstProperty = 'width';
			this.handleSize = this.element.getSize().x;
			if(this.options.invert){
				this.first = this.element.getNext();
				this.second = this.element.getPrevious();
				this.secondProperty = 'right';
				this.options.modifiers.x = 'right';
			} else {
				this.first = this.element.getPrevious();
				this.second = this.element.getNext();
				this.secondProperty = 'left';
				this.options.modifiers.x = 'left';
			}
		} else {
			this.isHorizontal = false;
			this.options.modifiers.x = false;
			this.firstProperty = 'height';
			this.handleSize = this.element.getSize().y;
			if(this.options.invert){
				this.first = this.element.getNext();
				this.second = this.element.getPrevious();
				this.secondProperty = 'bottom';
				this.options.modifiers.y = 'bottom';
			} else {
				this.first = this.element.getPrevious();
				this.second = this.element.getNext();
				this.secondProperty = 'top';
				this.options.modifiers.y = 'top';
			}
		}
		
		if(this.options.addToResizableLimits){
			(this.isHorizontal) ? ResizableLimits.horizontal.include(this) : ResizableLimits.vertical.include(this);	
		}
		
		if(this.options.cookie){
			this.setFromCookie();
			this.addEvent('complete',this.setCookie.bind(this));
		}
		
	},
	
	drag: function(event){
		this.parent(event);
		if(this.isHorizontal){
			this.distance = (this.options.invert) ? 
				this.parentElement.getSize().x - this.element.getPosition(this.parentElement).x - (this.handleSize * 2) :
				this.element.getPosition(this.parentElement).x - this.handleSize;
		} else {
			this.distance = (this.options.invert) ?
				this.parentElement.getSize().y - this.element.getPosition(this.parentElement).y - this.handleSize :
				this.element.getPosition(this.parentElement).y;
		}
		this.set(this.distance,true);
		return this;
	},
	
	set: function(distance,fromDrag){
		this.first.setStyle(this.firstProperty, distance);
		this.second.setStyle(this.secondProperty, distance + this.handleSize);
		if(!fromDrag) this.element.setStyle(this.secondProperty, distance);
		this.fireEvent('set');
		return this;
	},
	
	setFromCookie: function(){
		var cookie = Cookie.read(this.options.cookie);
		if(cookie) this.set(cookie.toInt());
		return this;
	},

	setCookie: function(){
		Cookie.write(this.options.cookie, this.distance, { duration: 30});
		return this;
	}

});

var ResizableLimits = new Hash({

	horizontal: [],
	vertical: [],
	
	setLimits : {
		all: function(){
			ResizableLimits.setLimits.vertical();
			ResizableLimits.setLimits.horizontal();
			return ResizableLimits;
		},
		
		horizontal: function(){
			ResizableLimits.horizontal.each(function(instance,index){
				if(instance.options.invert){
					var previous = ResizableLimits.horizontal[index - 1];
					var limit = (previous) ? instance.parentElement.getSize().x - previous.element.getPosition(instance.parentElement).x - (instance.handleSize * 3) : false;
				} else {
					var next = ResizableLimits.horizontal[index + 1];
					var limit = (next) ? next.element.getPosition(instance.parentElement).x - (instance.handleSize * 2) : false;
				}
				if(limit) instance.options.limit.x[1] = limit;
			});
			return ResizableLimits
		},
		
		vertical: function(){
			ResizableLimits.vertical.each(function(instance,index){
				if(instance.options.invert){
					var previous = ResizableLimits.vertical[index - 1];
					var limit = (previous) ? instance.parentElement.getSize().y - previous.element.getPosition(previous.parentElement).y - (instance.handleSize * 2) : false;
				} else {
					var next = ResizableLimits.vertical[index + 1];
					var limit = (next) ? next.element.getPosition(next.parentElement).y - instance.handleSize : false;
				}
				if(limit) instance.options.limit.y[1] = limit;
			});
			return ResizableLimits;
		}
	},
		
	attach: function(){
		ResizableLimits.setLimits.all();
		ResizableLimits.horizontal.each(function(instance){
			instance.addEvent('complete',ResizableLimits.setLimits.horizontal);
		});
		ResizableLimits.vertical.each(function(instance){
			instance.addEvent('complete',ResizableLimits.setLimits.vertical);
		});
		window.addEvent('resize',ResizableLimits.setLimits.all);
		return ResizableLimits
	}
	
});