/*
*
* Zone 1 Media Web Application Programming Interface
* --------------------------------------------------
*
* Date: 28-07-2007
* File: zapi_freemove
* Language: Javascript
*
* Description: Allow for draggable DOM elements,
* free or constrained within another element.
*
* Usage:
* Set onmouseover="initiateFreemove(this,constraintElement,handle)"
*
* constraintElement (element object) is optional
*
* handle (element object, child of fm_element) is optional, 
* specifying this will cause the handle to drag the entire
* element, the rest of fm_element will not be directly draggable.
*
* Once initiated, you may call an element's drag methods from 
* any other part of the script. 
*
* For example you could call 
* element1.stop onmouseover for element2. or start the move of 
* ele1 when ele2 is clicked:
*  
* window.document.getElementById('ele1').drag._moving=true; 
* window.document.getElementById('ele1').drag.move
*
* Note: IT IS IMPORTANT that the element is NOT positioned 
* itself - only it's parent
*
* Todo: If objects are strings rather than elements, try to get them using getElementById
*
*/

	function initiateFreemove(fm_element, fm_constrained, fm_handle) {		
		if(!fm_handle) { fm_handle = fm_element; }
		
		/* Give it some styles */
		fm_handle.style.cursor="move";
		fm_element.style.position="absolute";
		fm_element.style.zIndex="100";
	
		/* The freemove class is assigned to the element here so that it is not lost onmouseout */
		fm_handle.onmousedown=function(event){fm_element.drag = new zapi_freemove(fm_element,fm_constrained);fm_element.drag.initiateDrag(event)};

	}

	function zapi_freemove(fm_element, fm_constrained) {
		/* Initialize parameters */
		this._fm_element = fm_element;
		this._fm_constrained = fm_constrained;
		this._moving=false;
		document.onmouseup=function(event){fm_element.drag._moving=false};
	}

	/* Initiate the drag */
	zapi_freemove.prototype.initiateDrag = function(e) {
	
		var evn_move=window.event? window.event : e
		this._moving=true;
		
		/* If this element is to be constrained it must be positioned */
		if(this._fm_constrained) { 
			if(this._fm_constrained.style.position!="absolute" && this._fm_constrained.style.position!="relative") {this._fm_constrained.style.position="relative";}
		}
		
		/* Set the initial position of the element */
		this.getPosition();
		if(isNaN(parseInt(this._fm_element.style.left))){ this.fm_int_loc_x = this.int_left; } else { this.fm_int_loc_x = parseInt(this._fm_element.style.left); }
		if(isNaN(parseInt(this._fm_element.style.top))){ this.fm_int_loc_y = this.int_top; } else { this.fm_int_loc_y = parseInt(this._fm_element.style.top); }
		
		/* Set event coords so that the mouse position can be kept in the same loc within the element */
		this.fm_rel_x=evn_move.clientX
		this.fm_rel_y=evn_move.clientY

		/* Prevent default actions and move the element */
		if (evn_move.preventDefault) { evn_move.preventDefault(); }
		element = this._fm_element;
		/* 
		* Use window.document.onmousemove so that the drag is not stopped when
		* the the mouse moves out of the element, due to the javascript latency.
		* return false to cancel default action in MSIE 
		*/
		window.document.onmousemove=function(event){ element.drag.move(event); return false; };
	
	}
	
	/* Parse the mouse move */
	zapi_freemove.prototype.move = function(e) {
	
		var evn_move=window.event? window.event : e
			
		/* Stop the move if _moving is set to false - as onmouseup */
		if(this._moving!=false) {
			this._fm_move_left = this.fm_int_loc_x+evn_move.clientX-this.fm_rel_x;
			this._fm_move_top = this.fm_int_loc_y+evn_move.clientY-this.fm_rel_y;
		
			this.constrain();
			
			/* do the move */
			this._fm_element.style.left=this._fm_move_left+"px"
			this._fm_element.style.top=this._fm_move_top+"px";
		}
		
	}

	/* Set the constraints */
	zapi_freemove.prototype.constrain = function() {

		if(this._fm_constrained) {
			fm_max_x = this._fm_constrained.scrollWidth;
			fm_max_y = this._fm_constrained.scrollHeight;
			
			/* constrain top left */
			if(this._fm_move_left < 0) { this._fm_move_left = 0; }
			if(this._fm_move_top < 0) { this._fm_move_top = 0;}

			/* .. and bottom right */
			theX = fm_max_x-this._fm_element.scrollWidth;
			theY = fm_max_y-this._fm_element.scrollHeight;

			if(this._fm_move_left > theX) { this._fm_move_left = theX; }
			if(this._fm_move_top > theY) { this._fm_move_top = theY; }
			
		}
		
	}
	
	/* Get the current position of any element. */
	zapi_freemove.prototype.getPosition = function() {
		if (this._fm_element.offsetParent) {
			this.int_top = this._fm_element.offsetLeft
			this.int_left = this._fm_element.offsetTop
		} else {
			this.int_top = 0;
			this.int_left = 0;
		}
	}