/******************************************************
* DRAGABLE BOXES
******************************************************/

var oBox;
var offsetX, offsetY;

/**
 * start the drag event, set opacity, grab current location, set up event listeners
 * and disable text selection for IE.
 * This sets the global oBox and offsetX/offsetY variables. This was needed because
 * reading these each time was too slow and caused problems with dragging.
 * @param      object      event object
 */
function dragPress(evt)
{
    var oEvent = new DragEvent(evt);
    oBox = oEvent.source;
    oEvent.setOpacity(oBox, .6);
    offsetX = oEvent.x - oEvent.getX();
    offsetY = oEvent.y - oEvent.getY();
    addEventListener(document, 'mousemove', dragMove, false);
    addEventListener(document, 'mouseup', dragRelease, false);
    document.body.ondrag = function () { return false; };
    document.body.onselectstart = function () { return false; };
}

/**
 * Start new drag event and set the new location based on the global offsets, also
 * after each move eat the event so you don't get flickering.
 * @param      object      event object 
 */
function dragMove(evt)
{
    var oEvent = new DragEvent(evt);
    oEvent.setX(oBox, offsetX);
    oEvent.setY(oBox, offsetY);
    oEvent.eat();
}

/**
 * Start new drag event set opacity back to full and remove event listeners
 * also re-enable text selection in IE
 * @param      object      event object 
 */
function dragRelease(evt)
{
    var oEvent = new DragEvent(evt);
    oEvent.setOpacity(oBox, 1);
    removeEventListener(document, 'mousemove', dragMove, false);
    removeEventListener(document, 'mouseup', dragRelease, false);
    document.body.ondrag = function () { return true; };
    document.body.onselectstart = function () { return true }; 
}
    
/**
 * Drag event class   
 * @param      object      event object
 */    
function DragEvent(evt)
{
    var self    = this;
    this.evt    = evt ? evt : window.event; 
    this.source = evt.target ? evt.target : evt.srcElement;
    this.x      = evt.pageX ? evt.pageX : evt.clientX;
    this.y      = evt.pageY ? evt.pageY : evt.clientY;
    
    /**
     * return the event stats for debugging
     */
    this.debug = function () 
    {
        return 'Event [ x => ' + this.x + ', y => ' + this.y + ' ]';
    }
    
    /**
     * Stop the event propagation
     */
    this.eat = function ()
    {
        // mozilla
        if (self.stopPropagation)
        {
            self.stopPropagation();
            self.preventDefault();
        } 
        // IE
        else if (this.evt.cancelBubble)
        {
            self.cancelBubble = true;
            self.returnValue  = false;
        }
    }
    
    /**
     * set opacity
     * @param      object     object to make set transparency on
     * @param      number     .1 - 1
     */      
    this.setOpacity = function (node, val)
    {
        // IE
        if (node.filters)
        {
            try 
            {
                node.filters['alpha'].opacity = val * 100;
            } 
            catch (e) { }
        } 
        // others
        else if (node.style.opacity)
        {
            node.style.opacity = val;
        }
    }     
         
    /**
     * Get the x position of the clicked object
     */      
    this.getX = function ()
    {
        return parseInt(self.source.style.left);
    }
    
    /**
     * Get the y position of the clicked object
     */      
    this.getY = function ()
    {
        return parseInt(self.source.style.top);
    }     
      
    /**
     * set the x position of the clicked object
     * @param      object      object to set on
     * @param      int         offset amount between edge and distance clicked from edge
     */            
    this.setX = function (node, offset)
    {
        node.style.left = (self.x - offset) + 'px';
    }
    
    /**
     * set the y position of the clicked object
     * @param      object      object to set on
     * @param      int         offset amount between top and distance clicked from top
     */       
    this.setY = function (node, offset)
    {
        node.style.top = (self.y - offset) + 'px';
    }              
          
}      

