/***********************************************************************
 *  Filename: mod25_dragDrop.js                                        *
 *  Date Created: 11MAY06                                              *
 *  Date Last Modified: 16JUL06                                        *
 *  Package: mod25                                                     *
 *  Type: Class definition                                             *
 *  Copyright © 2006 Mod25 Solutions, LLC. All Rights Reserved         *
 *  Notes: This class can be added to other classes to allow them to   *
 *	easily implement drag and drop capabilities.                       *
 **********************************************************************/

/***********************************************************************
 * Requirements:                                                       *
 *     mod25_events                                                    *
 *     mod25_misc                                                      *
 **********************************************************************/

// Declare class
var mod25_dragDrop = new Object();

// Holds the object reference to the currently draggin element
mod25_dragDrop.currDrag = null;

// Add dragging capability to an element
// Arguments: obj - Element to add dragging capability to
mod25_dragDrop.addDrag = function(obj) {
	//if (obj.addEventListener) {
		// Add the event handler to the object
		mod25_events.addEvent(obj, 'mousedown', mod25_dragDrop.startDrag, false);
	//} else {
		// Work on internet explorer
	//	obj.onmousedown = mod25_dragDrop.startDrag;
	//}
	
	// Enable dragging for the object
	obj.draggable = true;
	
	obj.style.left = getElementStyle(obj, 'left', 'left');
	obj.style.top = getElementStyle(obj, 'top', 'top');

	return true;
};

// Start the dragging of an object
// Arguments: e - the event object
mod25_dragDrop.startDrag = function(e, currObj, x, y, width, height) {
	// Get the event object on all platforms
	e = mod25_events.processEvent(e);
	
	var obj = currObj || e.currentTarget || e.target;
	
	// Get the element on internet explorer
	if (!e.currentTarget) {
		// Check if a drag parent exists
		if (!obj.dragParent) {
			obj.dragParent = mod25_dragDrop.findParent(obj);
		}
		
		obj = obj.dragParent;
	}
	
	// Save the dragging object
	mod25_dragDrop.currDrag = obj;
	
	// Check if the object has been made draggable
	if (!obj.draggable || obj.draggable == undefined || obj.draggable != true) {
		// Check if the element was given a draggable attribute
		if (obj.hasAttribute('mod25_draggable') == false)
			return false;
		else
			// Make the object draggable
			obj.draggable == true;
	}
	
	// Get the location of the mouse click
    obj.clickX = e.clientX;
	obj.clickY = e.clientY;

	// Get the original coords of the element
	//obj.startX = parseInt(getElementStyle(obj, 'left', 'left'));
	//obj.startY = parseInt(getElementStyle(obj, 'top', 'top'));
	obj.startX = parseInt(obj.style.left);
	obj.startY = parseInt(obj.style.top);
	
	// Setup the boundaries for the dragging
	obj.minX = (x || obj.minX) || 0;
	obj.minY = (y || obj.minY) || 0;
	obj.maxX = (obj.maxX != undefined) ? obj.maxX : (x + width) || getWindowWidth();
	obj.maxY = (obj.maxY != undefined) ? obj.maxY : (y + height) || getWindowHeight();
	
	// Try and call the event handler function
	if (obj._on_startDrag) {
		if (obj._on_startDrag(obj, obj.startX, obj.startY) == false)
			return;
	}

	// Add the events to respond to the mouse move and mouse button release
    mod25_events.addEvent(document, "mousemove", mod25_dragDrop.doDrag, true );
    mod25_events.addEvent(document, "mouseup",   mod25_dragDrop.endDrag,  true );
	
	// Stop the event from bubbling up the DOM tree
    e.stopPropagation();
};

// Do the dragging action of the object
// Arguments: e - event object
mod25_dragDrop.doDrag = function(e) {
	// Get the event object on all platforms
	e = mod25_events.processEvent(e);
	
	// Make sure there is a currently dragging element
    if (!mod25_dragDrop.currDrag) return;
	
	// Get the currently dragging element
    var obj = mod25_dragDrop.currDrag;
	
	// Calculate the new coords for the element
    var nx = obj.startX + e.clientX - obj.clickX;
    var ny = obj.startY + e.clientY - obj.clickY;
	
	// Make sure the element can't be dragged outside the boundries
    nx = Math.min( Math.max( obj.minX, nx ), obj.maxX);
    ny = Math.min( Math.max( obj.minY, ny ), obj.maxY);

	// Set the new coords of the dragging element
    obj.style.left = nx + "px";
	
	obj.style.top = ny + "px";
	
	
	// Try and call the event handler function
	if (obj._on_drag)
		obj._on_drag(obj, nx,ny);

    return false;
};

// End the dragging of an object
mod25_dragDrop.endDrag = function() {
	// Remove the events to handle the mouse movement and mouse button release
	mod25_events.removeEvent(document, "mousemove", mod25_dragDrop.doDrag, true );
    mod25_events.removeEvent(document, "mouseup",   mod25_dragDrop.endDrag,  true );
	
	// Make sure there is a currently dragging element
    if ( !mod25_dragDrop.currDrag ) return;
	
	// Get the currently dragging object
	var obj = mod25_dragDrop.currDrag;
	
	// Try and call the event handler function
	if (obj._on_drop)
		obj._on_drop(obj, parseInt(obj.style.left), parseInt(obj.style.top) );

	// Clear the currently dragging object
    mod25_dragDrop.currDrag = null;
};

// Find the element that has dragging enabled
//  This is done because when an event is called in IE there is no way to
// determine which element actually contains the event handler.
// 	Dear Mr. William Gates,
//		We understand that you and the Internet Explorer development team would like to help
//	innovate the internet with new advances in browser technology but in all actuality your so called
//	advances are mostly useless and only supported by Internet Explorer which leads to little use.
//	Also you seem to completely ignore the standards that are issued by the W3C.
//	Please do all of the web developers a favor and start supporting the standards.  It's really
//	annoying when you are trying to develope a site that will work the same across many browsers
//	only to find that Internet Explorer does not support the functionality.  This only succedes to
//	confirm my hatred for the browser that has more holes than a brothel.  Maybe you guys could
//	take a page from the Mozilla book.  I would love to remove Internet Explorer from my computer
//	but there is no way to do that without breaking the windows operating system.  If you would just
//	write better code and support the standards you might find people to be more receptive to your
//	browser...uhh probably not, never mind.  Anyway I can't wait to see IE7 err I mean I can't wait
//	to see all the holes in it.  Hope you can keep up with Google and Mozilla Firefox,  ha.
//																	-- Crossbrowser web developers
mod25_dragDrop.findParent = function(obj) {
	var tmpObj = obj.parentNode;
	
	// Loop looking for a parent that has dragging enabled
	while(tmpObj.tagName != "BODY" || tmpObj.tagName != "HTML") {
		// Check if the object has dragging enabled
		if (tmpObj.draggable != undefined && tmpObj.draggable != false) {
			return tmpObj;
		} else {
			tmpObj = tmpObj.parentNode;
		}
	}
	
	return null;
};
