﻿
function MoveManager( type )
{	
    var m_type = ( type == null )? "MoveManager" : type;
    
    function GetRegistrationKey()
    {
        var sRes = m_type + "_Registered";
        return sRes;
    }
    
	this.MoveStyle =
    {
        GhostCopy : 0,
        Original : 1,
        SolidOutline : 2,
        DashedOutline : 3,
        Rectangle : 4,
        None : 5
    };

	var self = this;

	var m_bIsEntityMoving = false;
	
	var m_nRegistersCount       = 0;
	var m_aRegistrantsData  	= {};	
	var c_nMoveElZIndex = 300;
	
	this.CreateMoveEffectEl = function( nStyle, oParentEl )
	{
		var oMoveEl = null;
		var nExtContHeight = 0;
		switch( nStyle )
		{
			case self.MoveStyle.Original:
				oMoveEl = oParentEl.cloneNode( true );
				oMoveEl.style.width = oParentEl.offsetWidth + "px";
				oMoveEl.style.height = oParentEl.offsetHeight + "px";
				break;
					
			case self.MoveStyle.SolidOutline:
				oMoveEl = document.createElement("div");
				oMoveEl.style.border = "#000000 2px solid";
				oMoveEl.style.height = oParentEl.offsetHeight - 4 + "px";
				oMoveEl.style.width = oParentEl.offsetWidth - 4 + "px";
				break;
					
			case self.MoveStyle.DashedOutline:
				oMoveEl = document.createElement("div");
				oMoveEl.style.border = "#000000 1px dashed";
				oMoveEl.style.height = oParentEl.offsetHeight - 2 +"px";
				oMoveEl.style.width = oParentEl.offsetWidth - 2 + "px";
				break;
				
			case self.MoveStyle.GhostCopy:
				oMoveEl = oParentEl.cloneNode( true );
				oMoveEl.style.width = oParentEl.offsetWidth + "px";
				oMoveEl.style.height = oParentEl.offsetHeight + "px";
				jQuery( oMoveEl ).css( "opacity", 0.3 );
				break;
					
			case self.MoveStyle.Rectangle:
				oMoveEl = document.createElement("div");
				oMoveEl.style.border = "#000000 2px solid";
				oMoveEl.style.height = oParentEl.offsetHeight - 4 + "px";
				oMoveEl.style.width = oParentEl.offsetWidth - 4 + "px";
				oMoveEl.style.backgroundColor = "#505050";
				jQuery( oMoveEl ).css( "opacity", 0.3 );
				break;
					
			case self.MoveStyle.None:
				oMoveEl = document.createElement("div");
				break;
		}
		return oMoveEl;
	}
	
	this.UpdateCoordinates = function( entity, oEventXY, oEventOffsetEl, oMoveEl )
	{
//	    oMoveEl.style.top = oEventXY.y + "px";
//	    oMoveEl.style.left = oEventXY.x + "px";
	}
		
	function OnEntityMoveStart()
	{
	    m_bIsEntityMoving = true;
	}
	
	function OnEntityMoveEnd()
	{
	    m_bIsEntityMoving = false;
	}
	
	this.GetIsMovingInProcess = function()
	{
	    var bRes = m_bIsEntityMoving;
	    return bRes;
	}
	
	this.RegisterToMove = function( oEl, oDoMoveEl, nMoveStyle, fnOnMoveStart, fnOnMove, fnOnMoveEnd, oMoveStartEvent, fnOnMoveBreak )	
	{
		var oElRegisterData =
		{
			El			: oEl,
			DoMoveEl	: oDoMoveEl ? oDoMoveEl : oEl,
			OnMoveStart : fnOnMoveStart,
			OnMove		: fnOnMove,
			OnMoveEnd	: fnOnMoveEnd,
			MoveStyle	: nMoveStyle,
			OnMoveBreak : fnOnMoveBreak
		};
		RegisterInternal( oElRegisterData, oMoveStartEvent );
	}
	
	this.UnRegister = function( oDoMoveEl )
	{
	    if( oDoMoveEl &&( null != oDoMoveEl[GetRegistrationKey()] ) )
	    {
	        var entity =  m_aRegistrantsData[ oDoMoveEl[GetRegistrationKey()] ];
	        
	        if( entity )
	        {	        
	            entity.OnUnRegister();
	            jQuery( oDoMoveEl ).unbind( "mousedown", entity.OnMoveStart );
		        jQuery( document.documentElement ).unbind( "mousemove", entity.OnMove );
		        jQuery( document.documentElement ).unbind( "mouseup", entity.OnMoveEnd );
		        jQuery( document.documentElement ).unbind( "keydown", entity.OnKeyDown );
/*	    
		        DOM.DetachEvent( DOM.EEventNames.MouseDown, entity.OnMoveStart, oDoMoveEl );
		        DOM.DetachEvent( DOM.EEventNames.MouseMove, entity.OnMove, null );
	            DOM.DetachEvent( DOM.EEventNames.MouseUp, entity.OnMoveEnd, null );
                DOM.DetachEvent( DOM.EEventNames.KeyDown, entity.OnKeyDown, null );		
*/		    }
	        oDoMoveEl[GetRegistrationKey()] = null;
	    }	    
	}

	function RegisterInternal( oElRegisterData, oMoveStartEvent )
	{
		var oEl = oElRegisterData.El;
		var oDoMoveEl = oElRegisterData.DoMoveEl;

		var fnOnMoveStart = oElRegisterData.OnMoveStart;
		var fnOnMove = oElRegisterData.OnMove;
		var fnOnMoveEnd = oElRegisterData.OnMoveEnd;
		
		var nMoveStyle = oElRegisterData.MoveStyle;

		var fnOnKeyDown = oElRegisterData.OnMoveBreak;
		
		if ("string" == typeof(oEl))
		{
			oEl	= document.getElementById( oEl );
		}
		if( "string" == typeof(oDoMoveEl) )
		{
			oDoMoveEl = document.getElementById( oDoMoveEl );
		}

		// the following code disables multiple registration of same element/handle pair
		if (!oDoMoveEl)
			return;
		if (null != oDoMoveEl[GetRegistrationKey()])
			return;
			
		oDoMoveEl[GetRegistrationKey()] = m_nRegistersCount;
		
		var entity = new MoveEntity( oEl, nMoveStyle, fnOnMoveStart, fnOnMove, fnOnMoveEnd, fnOnKeyDown );
		self.OnEntityCreate( entity, oDoMoveEl );
		
		jQuery( oDoMoveEl ).bind( "mousedown", entity.OnMoveStart );
		jQuery( document.documentElement).bind( "mousemove", entity.OnMove );
		jQuery( document.documentElement).bind( "mouseup", entity.OnMoveEnd );
		jQuery( document.documentElement ).bind( "keydown", entity.OnKeyDown );
/*		
		DOM.AttachEvent( DOM.EEventNames.MouseDown, entity.OnMoveStart, oDoMoveEl );
		DOM.AttachEvent( DOM.EEventNames.MouseMove, entity.OnMove, null );
	    DOM.AttachEvent( DOM.EEventNames.MouseUp, entity.OnMoveEnd, null );

        if( fnOnKeyDown )
        {
    	    DOM.AttachEvent( DOM.EEventNames.KeyDown, entity.OnKeyDown, null );
	    }
*/		
		m_aRegistrantsData[ oDoMoveEl[GetRegistrationKey()] ] = entity;		
		
		if (oMoveStartEvent)
		{
			entity.OnMoveStart( jQuery.event.fix( oMoveStartEvent ) );
		}
		
		m_nRegistersCount++;
	}
	
	this.OnEntityCreate = function( entity, oDoMoveEl )
	{
	}	

function MoveEntity( m_oEl, oMovingStyle, m_fnOnMoveStart, m_fnOnMove, m_fnOnMoveEnd, m_fnOnMoveBreak )
{
	var m_nMovingStyle	= (null != oMovingStyle) ? oMovingStyle : self.MoveStyle.Original;
	
	var m_bIsMoving		= false;
	var m_bIsStepMoving	= false;
	var m_oMoveEl			= null;
	var m_oMovingOffset	= null;

    var self_entity = this;
    
    this.GetRootEl = function()
    {
        return m_oEl;
    }

    this.OnKeyDown = function( oEv )
    {
        if( 27 == oEv.keyCode )
        {
            EscapeMoving( oEv );
        }
    }

    function EscapeMoving( oEv )
    {
		if( m_bIsMoving )
		{
		    if( m_fnOnMoveBreak)
			{
				m_fnOnMoveBreak( oEv, m_oEl, m_oMoveEl, true );
			}

			if( m_oMoveEl )
			{
			    m_oMoveEl.parentNode.removeChild( m_oMoveEl );
			}

            m_oEl.style.visibility = "";
			m_oMoveEl = null;
			
			if( m_bIsStepMoving )
			{
			    OnEntityMoveEnd();
			}
			m_bIsMoving = false;
			m_bIsStepMoving = false;				
		}
    }
    
	this.OnMoveStart = function( oEv )
	{		
		if( m_fnOnMoveStart && m_fnOnMoveStart( oEv, m_oEl ) )
		{
			if( oEv )
			{
				PrepareMoving( oEv );
				m_oMovingOffset = {x : oEv.pageX, y : oEv.pageY };
				oEv.preventDefault();
				oEv.stopPropagation();
			}
		}
		return true;
	}
	
	function GetIsStepMoved( oOffsetEvent )
	{
		var bRes = m_bIsMoving;
		if( !bRes )
		{
			bRes = ( oOffsetEvent.x != m_oMovingOffset.x )||( oOffsetEvent.y != m_oMovingOffset.y );
		}
		return bRes;
	}
	
	this.OnMove = function( oEv )
	{
//		debugger;
		if( m_oMoveEl && m_bIsMoving )
		{
			var oEventXY = {x : oEv.pageX, y : oEv.pageY };
			if( GetIsStepMoved( oEventXY ) )
			{
			    OnEntityMoveStart();
			    
				m_oMovingOffset = oEventXY;
				m_bIsStepMoving = true;	
				m_oMoveEl.style.visibility = "";
				
				UpdateCoordinates( oEventXY, m_oMoveEl.oOffsetMove, m_oMoveEl );
										
				if( m_nMovingStyle == self.MoveStyle.Original )
				{
				    m_oEl.style.visibility = "hidden";
				}
					
				if (m_fnOnMove)
				{
					m_fnOnMove( oEv, m_oEl, m_oMoveEl );
				}	
			}
			
			return false;
		}
	}
	
	this.OnMoveEnd = function( oEv )
	{		
		if( m_bIsMoving )
		{
		    if( m_fnOnMoveEnd)
			{
				m_fnOnMoveEnd( oEv, m_oEl, m_oMoveEl );
			}
			
			if( m_oMoveEl )
			{
			    m_oMoveEl.parentNode.removeChild( m_oMoveEl );
			}
			m_oEl.style.visibility = "";
			m_oMoveEl = null;
			
			if( m_bIsStepMoving )
			{
			    OnEntityMoveEnd();
			}
			
			m_bIsMoving = false;
			m_bIsStepMoving = false;				
		}
	}
	
	this.OnUnRegister = function()
	{
	    if( m_bIsMoving )
		{ 		
			if( m_oMoveEl )
			{
			    m_oMoveEl.parentNode.removeChild( m_oMoveEl );
			}
			m_oEl.style.visibility = "";
			m_oMoveEl = null;	
			
			if( m_bIsStepMoving )
			{
			    OnEntityMoveEnd();
			}
			m_bIsMoving = false;
			m_bIsStepMoving = false;
		}
	}

	function PrepareMoving( oEv )
	{
		if( m_oEl && !m_bIsMoving )
		{
			m_bIsMoving = true;
			m_bIsStepMoving = false;
			
			m_oMoveEl = GetMoveEl( oEv );			
			document.body.appendChild( m_oMoveEl );
		}
	}

	function GetMoveEl( oEv )
	{
		var oMoveEl = self.CreateMoveEffectEl( m_nMovingStyle, m_oEl, null );
		oMoveEl.style.visibility = "hidden";
					
		oMoveEl.style.position = "absolute";
		
		var oOffsetEl = jQuery(m_oEl).offset();
		
		oMoveEl.style.top = oOffsetEl.top + "px";
		oMoveEl.style.left = oOffsetEl.left + "px";
		oMoveEl.oOffsetMove = GetOffsetEventEl( m_oEl, oEv );
		oMoveEl.style.zIndex = c_nMoveElZIndex;
		oMoveEl.id = m_oEl.id+"_Move";
		return oMoveEl;
	}

	function GetOffsetEventEl( oEl, oEv )
	{
		var oOffsetEl = jQuery(oEl).offset();
		var nX = oEv.pageX - oOffsetEl.left;
		var nY = oEv.pageY - oOffsetEl.top;
		return { x: nX, y: nY };
	}
	
	function UpdateCoordinates( oEventXY, oEventOffsetEl, oMoveElStyle )
	{
	    self.UpdateCoordinates( self_entity, oEventXY, oEventOffsetEl, oMoveElStyle );
	}
}
}

window.AB_MoveManager = new MoveManager();
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();