/**
 *
 * @auther Adam Brill adam@solutionset.com
 * @date 20070122
 *
 * @see prototype.js v1.6
 * @see SS.Base.js for v1.6
 */

SS.Resizeable = Class.create(SS.Base, {
	/**
	 * Object used to store settings. Extends the parent class settings
	 * @var Object
	 */
	s: {
		held: false,
		pickupCoords: {
			x: null,
			y: null
		},
		pickupSize: {
			width: null,
			height: null
		},
		minSize: {
			width: null,
			height: null
		},
		maxSize: {
			width: null,
			height: null
		},
		boundOnHandleMouseUp: null,
		boundOnHandleMouseMove: null
	},
	
	/**
	 * Object used to store nodes. Extends the parent class nodes
	 * @var Object
	 */
	n: {
		element: null,
		handle: null
	},
	
	/**
	 * @param function $super
	 * @param DOM Element element
	 * @param object options
	 * @return void
	 */
	initialize: function($super, element, options) {
		$super(options);
		
		this.n.element = $(element);
		
		if (Object.isElement(this.n.handle)) {
			this.n.handle = $(this.n.handle);
		} else {
			this.n.handle = this.n.element;
		}
		
		this._captureEvents();
	},
	
	/**
	 * @param DOM Event e
	 * @return void
	 */
	onHandleMouseDown: function(e) {
		e.stop(e);
		this.pickup({x: e.pointerX(), y: e.pointerY()});
	},
	
	/**
	 * @param DOM Event e
	 * @return void
	 */
	onHandleMouseUp: function(e) {
		e.stop(e);
		this.drop();
	},
	
	/**
	 * @param DOM Event e
	 * @return void
	 */
	onHandleMousemove: function(e) {
		e.stop(e);
		if (this.s.held) {
			this.updateSize({x: e.pointerX(), y: e.pointerY()});
		}
	},
	
	/**
	 * @param Object coords
	 * @return void
	 */
	pickup: function(coords) {
		this.s.held = true;
		this.s.pickupCoords = coords;
		this.s.pickupSize = this.n.element.getDimensions();
		
		this.boundOnHandleMouseUp = this.onHandleMouseUp.bindAsEventListener(this);
		this.boundOnHandleMouseMove = this.onHandleMousemove.bindAsEventListener(this);
		
		Event.observe(document, "mouseup", this.boundOnHandleMouseUp);
		Event.observe(document, "mousemove", this.boundOnHandleMouseMove);
	},
	
	/**
	 * @param void
	 * @return void
	 */
	drop: function() {
		this.s.held = false;
		
		Event.stopObserving(document, "mouseup", this.boundOnHandleMouseUp);
		Event.stopObserving(document, "mousemove", this.boundOnHandleMouseMove);
	},
	
	/**
	 * @param Object coords
	 * @return void
	 */
	updateSize: function(coords) {
		
		var height = this.s.pickupSize.height + (coords.y - this.s.pickupCoords.y),
		width = this.s.pickupSize.width + (coords.x - this.s.pickupCoords.x);
		
		if (this.s.maxSize.height !== null && height > this.s.maxSize.height) {
			height = this.s.maxSize.height;
		} else if (this.s.minSize.height !== null && height < this.s.minSize.height) {
			height = this.s.minSize.height;
		} else if (height < 0) {
			height = 0;
		}
		
		if (this.s.maxSize.width !== null && width > this.s.maxSize.width) {
			width = this.s.maxSize.width;
		} else if (this.s.minSize.width !== null && width < this.s.minSize.width) {
			width = this.s.minSize.width;
		} else if (width < 0) {
			width = 0;
		}
		
		this.n.element.setStyle({
			height: height + "px",
			width: width + "px"
		});
		this.n.element.fire('Resizeable::onresize');
	},
	
	/**
	 * @param void
	 * @return void
	 */
	_captureEvents: function() {
		this.n.handle.observe('mousedown', this.onHandleMouseDown.bindAsEventListener(this));
	}
});
