/**
 *  DivPlus Dragging accessory
 *  Part of DivPlus (http://divplus.novomancy.org/)
 *
 *  Function which makes any divPlus div draggable.
 *  Note:  Due to a problem in IE which forces text to be selected ondrag, it is recommended that
 *      onselectstart="if(browsers.ie6) return false;"
 *  be added to the body tag of any page which has dragging behavior.  Unfortunately, this prevents
 *  any text from being selected anywhere on the page, so you'll have to decide which is worse.  I don't
 *  know of a better way around this right now.
 *
 *  @author	john.bell@REMOVEME.umit.maine.edu
 *  @version 1.2.20040526
 *  @uses divplus.js
 *  @uses defined.js
 *  @uses browsers.js
 *
 *  @argument	draggedDiv			obj		DivPlus object which contains the div you want to make draggable
 *  @argument	dragConstrainsts	str		"h" or "v" to constrain movement to horizontal or vertical.
 *											"both" allows full 2D movement
 *  @argument	dragLimits			arr		Associative array with the top, left, right, and bottom px limits
 *											of the dragging area.  Optional, and if defined, each limit is also
 *											optional.
 *
 *  @returns 	nothing, but does add a new property to the DivPlus object specified:  [divPlusObject].dragger.
 *				This new property has the following externally useful methods:
 *				[divPlusObject].dragger.getLimits()							Returns the current dragLimits array
 *				[divPlusObject].dragger.setLimits(dragLimits)				As the passed argument dragLimits
 *																			Removes any limit not defined in the passed array
 *				[divPlusObject].dragger.setLimit(limit, setting)			Sets a single dragLimit without
 *																			modifying any of the others.
 *				[divPlusObject].dragger.getConstraints()					Returns the current dragConstraints setting
 *				[divPlusObject].dragger.setConstraints(dragConstraints) 	As the passed argument dragConstraints
 *				[divPlusObject].dragger.destroy()							Removes the dragging behavior
 */

function DivPlusDragger(draggedDiv, dragConstraints, dragLimits){
	draggedDiv.dragger = this;
	this.dragConstraints = dragConstraints;
	this.dragLimits = arguments.length==3 ? dragLimits : new Array();
	this.mouseOffset = {x:0, y:0};
	this.dragOn = function(e){
		draggedDiv.dragger.mouseOffset = browsers.mousePosition(e);
		draggedDiv.dragger.originalLocation = draggedDiv.getLocation();
		browsers.addEventListener("mousemove", document, draggedDiv.dragger.drag, false); 
		browsers.addEventListener("mouseup", document, draggedDiv.dragger.dragOff, false);
		return false;

	}
	this.dragOff = function(){
		browsers.removeEventListener("mousemove", document, draggedDiv.dragger.drag, false);
		browsers.removeEventListener("mouseup", document, draggedDiv.dragger.dragOff, false);
		return false;
	}
	this.drag = function(e){
		var mousePosition = browsers.mousePosition(e);
		if(dragConstraints=="v" || dragConstraints=="both"){ 
			var newTop = (mousePosition.y - draggedDiv.dragger.mouseOffset.y) + draggedDiv.dragger.originalLocation.top;
			if(defined(draggedDiv.dragger.dragLimits.top)){
				newTop = newTop < draggedDiv.dragger.dragLimits.top ? draggedDiv.dragger.dragLimits.top : newTop;
			}
			if(defined(draggedDiv.dragger.dragLimits.bottom)){
				newTop = newTop > draggedDiv.dragger.dragLimits.bottom ? draggedDiv.dragger.dragLimits.bottom : newTop;
			}
		} else var newTop = draggedDiv.dragger.originalLocation.top;
		if(dragConstraints=="h" || dragConstraints=="both"){
			var newLeft = (mousePosition.x - draggedDiv.dragger.mouseOffset.x) + draggedDiv.dragger.originalLocation.left;
			if(defined(draggedDiv.dragger.dragLimits.left)){
				newLeft = newLeft < draggedDiv.dragger.dragLimits.left ? draggedDiv.dragger.dragLimits.left : newLeft;
			}
			if(defined(draggedDiv.dragger.dragLimits.right)){
				newLeft = newLeft > draggedDiv.dragger.dragLimits.right ? draggedDiv.dragger.dragLimits.right : newLeft;
			}
		} else var newLeft = draggedDiv.dragger.originalLocation.left;
		draggedDiv.setLocation(newTop, newLeft);
		return false;
	}
	browsers.addEventListener("mousedown", draggedDiv.element, this.dragOn, false);
	
	//Methods
	this.getLimits = function(){
		return dragLimits;
	}
	
	this.getConstraints = function(){
		return dragConstraints;
	}
	
	this.setLimits = function(newLimits){
		if(defined(newLimits.top)) dragLimits.top = newLimits.top; 
		else if(defined(dragLimits.top)) delete dragLimits.top;
		if(defined(newLimits.left)) dragLimits.left = newLimits.left;
		else if(defined(dragLimits.left)) delete dragLimits.left;
		if(defined(newLimits.bottom)) dragLimits.bottom = newLimits.bottom;
		else if(defined(dragLimits.bottom)) delete dragLimits.bottom;
		if(defined(newLimits.right)) dragLimits.right = newLimits.right;
		else if(defined(dragLimits.right)) delete dragLimits.right;
	}

	this.setLimit = function(limit, setting){
		dragLimits[limit] = setting;
	}
		
	this.setConstraints = function(newConstraints){
		dragConstraints = newConstraints;
	}
	
	this.destroy = function(){
		browsers.removeEventListener("mousedown", draggedDiv.element, this.dragOn, false);
		delete draggedDiv.dragger;
	}
}