﻿//-------- Region Globals --------
var m_oCurrentDragObject = null;
var m_nDeltaX = 0;
var m_nDeltaY = 0;
var m_nStartPosition = new Array();

var m_arrWrapObjects = new Array();
var m_arrDockObjects = new Array();
var m_arrTargetObjects = new Array();

//-------- Region Handlers --------

function OnObjectDrag(evt)
{
	oEvent = new MouseEvent(evt);
	m_oCurrentDragObject = oEvent.Source;
	
	if (m_oCurrentDragObject.ParentDragObject) 
	{
	    m_oCurrentDragObject = m_oCurrentDragObject.ParentDragObject;
	}
	
	SetOpacity(m_oCurrentDragObject, 0.5);
	SetZIndex(m_oCurrentDragObject, 500);
	
	m_nStartPosition = [GetX(m_oCurrentDragObject), GetY(m_oCurrentDragObject)];
	m_nDeltaX = oEvent.X - GetX(m_oCurrentDragObject);
	m_nDeltaY = oEvent.Y - GetY(m_oCurrentDragObject);
	
	MouseEvent.AddEventListener(document, "mousemove", DragMove, false);
	MouseEvent.AddEventListener(document, "mouseup", DragRelease, false);    
}

function DragMove(evt) 
{
	oEvent = new MouseEvent(evt);
	m_oCurrentDragObject.style.position = "absolute";
	SetX(m_oCurrentDragObject, oEvent.X - m_nDeltaX);
	SetY(m_oCurrentDragObject, oEvent.Y - m_nDeltaY);
	oEvent.Consume();
	
	oTargetNode = IsDroppedOnWrapArea(oEvent)
	if (oTargetNode)
	{
	    ResizeNodeOnDragOver(oTargetNode);
	}	
	else
	{
	    ResizeNodeOnDragRelease();
	}	
}

function DragRelease(evt) 
{
	oEvent = new MouseEvent(evt);
	SetOpacity(m_oCurrentDragObject, 1);
	SetZIndex(m_oCurrentDragObject, 300);
	
	MouseEvent.RemoveEventListener(document, "mousemove", DragMove, false);
	MouseEvent.RemoveEventListener(document, "mouseup", DragRelease, false);
	
	var oTargetNode = IsDroppedOnWrapArea(oEvent);
	if (oTargetNode)
	{
	    MoveObject(m_oCurrentDragObject, [GetX(oTargetNode),  GetY(oTargetNode)]);
	}
	else
	{
	    ResizeNodeOnDragRelease();
	}
	
	var oTargetNode = IsDroppedOnDockArea(oEvent);
	if (oTargetNode)
	{
	    if (!oTargetNode.DockedObjects)
	    {
	        oTargetNode.DockedObjects = new ArrayList();
	    } 
	    var nSumaricOffset = 0;
        for (var i = 0; i < oTargetNode.DockedObjects.GetCount(); i++)
        {
            if (oTargetNode.DockedObjects.Values[i] != m_oCurrentDragObject)
            {
                nSumaricOffset = nSumaricOffset + GetHeight(oTargetNode.DockedObjects.Values[i]);
            }
        }
	    oTargetNode.DockedObjects.Add(m_oCurrentDragObject);
	    if (oTargetNode.ObjectAttach)
	    {
	        oTargetNode.ObjectAttach(oTargetNode, oTargetNode.DockedObjects);
	    }
	    
	    if (m_oCurrentDragObject.DocketToObject)
	    {
	        m_oCurrentDragObject.DocketToObject.DockedObjects.Remove(m_oCurrentDragObject);
	        if (m_oCurrentDragObject.DocketToObject.ObjectAttach)
	        {
	            m_oCurrentDragObject.DocketToObject.ObjectAttach(m_oCurrentDragObject.DocketToObject, m_oCurrentDragObject.DocketToObject.DockedObjects);
	        }	        
	        
	        var nCurrentOffset = 0;
            for (var i = 0; i < m_oCurrentDragObject.DocketToObject.DockedObjects.GetCount(); i++)
            {
                MoveObject(m_oCurrentDragObject.DocketToObject.DockedObjects.Values[i], [GetX(m_oCurrentDragObject.DocketToObject),  GetY(m_oCurrentDragObject.DocketToObject) + nCurrentOffset]);
                nCurrentOffset = nCurrentOffset + GetHeight(m_oCurrentDragObject.DocketToObject.DockedObjects.Values[i]);
            }
	    }
	    m_oCurrentDragObject.DocketToObject = oTargetNode;
	    
	    ChangeObjectWidth(m_oCurrentDragObject, GetWidth(oTargetNode));
	    MoveObject(m_oCurrentDragObject, [GetX(oTargetNode),  GetY(oTargetNode) + nSumaricOffset]);
	}
	else
	{
	    MoveObject(m_oCurrentDragObject, m_nStartPosition);
	}
	m_oCurrentDragObject = null;
}    

function OnWindowInitialize(evt) 
{
    // prevent IE text selection while dragging
	document.body.ondrag = function () { return false; };
	document.body.onselectstart = function () { return false; };
}	

//-------- Region Event Class --------

function MouseEvent(evt) 
{
	this.Event = 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;
}

MouseEvent.prototype.Consume = function () 
{
	if (this.Event.stopPropagation) 
	{
		this.Event.stopPropagation();
		this.Event.preventDefault();
	} 
	else if (this.Event.cancelBubble) 
	{
		this.Event.cancelBubble = true;
		this.Event.returnValue  = false;
	}
};

MouseEvent.AddEventListener = function (aTarget, aType, aFunction, aBubbles) 
{
	if (document.addEventListener) 
	{
		aTarget.addEventListener(aType, aFunction, aBubbles);
	} 
	else if (document.attachEvent) 
	{
		aTarget.attachEvent("on" + aType, aFunction, aBubbles);
	} 
	else 
	{
		aTarget["on" + aType] = aFunction;
	}
};

MouseEvent.RemoveEventListener = function (aTarget, aType, aFunction, aBubbles) 
{
	if (document.removeEventListener) 
	{
		aTarget.removeEventListener(aType, aFunction, aBubbles);
	} 
	else if (document.detachEvent) 
	{
		aTarget.detachEvent("on" + aType, aFunction, aBubbles);
	} 
	else 
	{
		aTarget["on" + aType] = null;
	}
};

//-------- Region Tools --------

function ResizeNodeOnDragOver(a_oTargetNode)
{
    if (m_oCurrentDragObject.OriginalSize == null) m_oCurrentDragObject.OriginalSize = [GetWidth(m_oCurrentDragObject), GetHeight(m_oCurrentDragObject)];

    SetWidth(m_oCurrentDragObject, GetWidth(a_oTargetNode));
    SetHeight(m_oCurrentDragObject, GetHeight(a_oTargetNode));
}

function ResizeNodeOnDragRelease()
{
    if (m_oCurrentDragObject.OriginalSize != null)
    {
        SetWidth(m_oCurrentDragObject, m_oCurrentDragObject.OriginalSize[0]);
        SetHeight(m_oCurrentDragObject, m_oCurrentDragObject.OriginalSize[1]);
    }
}	

function IsDroppedOnTarget(evt, a_arrTargets) 
{
    var nPrecision = 10;
    var oTargetNode = null;
    
	var nSourceX = GetX(m_oCurrentDragObject);
	var nSourceY = GetY(m_oCurrentDragObject);
	var nSourceWidth = GetWidth(m_oCurrentDragObject);
	var nSourceHeight = GetHeight(m_oCurrentDragObject);	    

    for (var i = 0; i < a_arrTargets.length; i++)
    {
        //m_arrWrapObjects[i];
        oTargetNode = a_arrTargets[i];
        
	    var nTargetX = GetX(oTargetNode);
	    var nTargetY = GetY(oTargetNode);
	    var nTargetWidth = GetWidth(oTargetNode);
	    var nTargetHeight = GetHeight(oTargetNode);	   
	    
	    if ((nSourceX + nSourceWidth) > (nTargetX + nPrecision) && nSourceX < (nTargetX + nTargetWidth - nPrecision) &&
	        (nSourceY + nSourceHeight) > (nTargetY + nPrecision) && nSourceY < (nTargetY + nTargetHeight - nPrecision))
	    {
	        return oTargetNode;
	    }   
    }
	return null;
}

function IsDroppedOnWrapArea(evt) 
{
    return IsDroppedOnTarget(evt, m_arrWrapObjects);
}	

function IsDroppedOnDockArea(evt)
{
    return IsDroppedOnTarget(evt, m_arrDockObjects);
}