if ("undefined" == typeof(RadDockNamespace))
{
	RadDockNamespace = new Object();
}

/*************************************************
 *
 * Docking zone types
 *
 *************************************************/
var RadDockingZoneTypeFlags = 
{
	Vertical		: 0x01
	, Horizontal	: 0x02
	, Top			: (0x10 | 0x02)
	, Bottom		: (0x20 | 0x02)
	, Left			: (0x30 | 0x01)
	, Right			: (0x40 | 0x01)
	, All			: (0x12 | 0x22 | 0x31 | 0x41) 
	, Custom		: 0xFF
};

/*************************************************
 *
 * Docking zone auto resizing
 *
 *************************************************/
RadDockNamespace.RadDockingZoneFixedSizeFlags = 
{
	None			: 0
	, ByWidth		: 1
	, ByHeight		: 2
	, ByWidthHeight	: (1 | 2)
};

/*************************************************
 *
 * RadDockingZone_Init
 *
 *************************************************/
RadDockNamespace.RadDockingZone_Init = function(element, dockingZoneInfo)
{
	Object.Extend(element, RadDockNamespace.RadDockingZone);

	var i = 0;
	
	// docking zone properties
	element.Type = dockingZoneInfo[i++]; 
	element.DockEnabled = dockingZoneInfo[i++];
	element.HighlightedStyleText = dockingZoneInfo[i++];
	element.ServerID = dockingZoneInfo[i++];	
	var hiddenInputID = dockingZoneInfo[i++];	
	element.FixedSizeMode = dockingZoneInfo[i++];	

	element.HiddenInput = document.getElementById(hiddenInputID);
	
	if (element.tagName == "TABLE"
		&& element.rows.length
		&& element.rows[0].cells.length)
	{
		element.rows[0].cells[0].style.verticalAlign = "top";
	}
	
	RadDockNamespace.AttachEvent(window, "load", element.FixObjectSizeOnInit.Bind(element));
	
	// element.SaveState(); // call SaveState from outside after all dockable objects are initialized
};

RadDockNamespace.RadDockingZone = {
	
	IsDockingZone			: true,	
	Type					: null, 
	DockEnabled				: null,
	HighlightedStyleText	: null,
	ServerID				: null,	
	FixedSizeMode			: null,	
	HiddenInput				: null,
	
	Dispose : function ()
	{
		this.HoveredElement = null;
		this.Manager = null;
		this.HiddenInput = null;
	},

	// RadDockingZone_GetContainer returns the object that is
	// the placeholder for all docked objects.
	//
	// NOTE: For UNKNOWN browsers (for ASP.NET; by default -- all instead of IE)
	// docking zones are rendered as TABLEs instead of DIVs. 
	// For TABLE-based docking zones all dockable objects are placed into
	// rows[0].cells[0].
	GetContainer : function ()
	{
		return ((this.tagName == "TABLE") ? this.rows[0].cells[0] : this);
	},
	
	// Returns an array of dockable objects docked into the zone
	GetDockedObjects : function ()
	{
		var arr = new Array();
		
		var child;
		var container = this.GetContainer();
		var childNodes = container.childNodes;
		
		for (var i = 0; i < childNodes.length; i++)
		{
			child = childNodes[i];
			if (!child.IsDockableObject)
				continue;
			arr[arr.length] = child;
		}
		
		return arr;
	},

	//
		SetAtPosition : function (dockableObject, position)
	{
		if (!dockableObject)
			return;
			
		if (dockableObject.ParentDockingZone != this)
			return;
			
		var child;
		var container = this.GetContainer();
		var childNodes = container.childNodes;
		
		var arrDockedObjects = new Array();
		var currentPos = -1;
		for (var i = 0; i < childNodes.length; i++)
		{
			child = childNodes[i];
			if (!child.IsDockableObject)
				continue;
			
			if (child == dockableObject)
			{
				currentPos = arrDockedObjects.length;
			}			
			arrDockedObjects[arrDockedObjects.length] = child;
		}
		
		var offset = position - currentPos;
		if (1 == offset)
		{
			position += 1;
		}
		
		if (arrDockedObjects.length == position)
		{
			container.appendChild(dockableObject);
		}
		else
		{
			var insertBefore = arrDockedObjects[position];
			var insertAfter = arrDockedObjects[position-1];
			
			if (insertBefore)
			{
			    var prev = undefined;
			    var incdec = offset < 0 ? -1 : 1;
			    var pos = position;// + incdec;
			    
			   if (
			   (insertBefore.className == "RadDockableStaticObject" && offset < 0) ||
			   (offset > 0 && insertAfter && insertAfter.className == "RadDockableStaticObject"))
			   {
			        
			        while(pos>=0 && pos < arrDockedObjects.length)
			        {
			           prev = arrDockedObjects[pos];
			           if(prev && prev.className != "RadDockableStaticObject")
			                break;
			           pos+=incdec;
			        }
			        
			        if(prev)
			        {
			           container.insertBefore(dockableObject,prev);
			           
			           insertBefore = arrDockedObjects[currentPos+1];
			           
			           if(insertBefore)
			           {
			                container.insertBefore(prev, insertBefore);
			           }
			           else
			           {
			                container.appendChild(prev);
			           }
			        }
			    }
			    else
				    container.insertBefore(dockableObject, insertBefore);
			}
		}
		
		this.SaveState();
	},

	//
	GetPosition : function (dockableObject)
	{
		if (!dockableObject)
			return -1;
			
		if (dockableObject.ParentDockingZone != this)
			return -1;
		
		var child;
		var pos = -1;
		
		var childNodes = this.GetContainer().childNodes;
		for (var i = 0; i < childNodes.length; i++)
		{
			child = childNodes[i];
			if (!child.IsDockableObject)
			{
				continue;
			}
			pos++;
			if (child == dockableObject)
			{
				break;
			}
		}
		return pos;
	},

	Dock : function (dockableObject, insertBefore)
	{
		if (!dockableObject)
			return;
			
		this.AdjustObjectSize(dockableObject);
			
		dockableObject.ParentDockingZone = this;
		dockableObject.parentNode.removeChild(dockableObject);
		
		var container = this.GetContainer();
		
		if (this.HoveredElement 
			&& this.HoveredElement != this)
		{
			if (!insertBefore)
			{
				insertBefore = this.HoveredElement;
			}		
			container.insertBefore(dockableObject, insertBefore);
		}
		else
		{
			container.appendChild(dockableObject);
		}
		
		this.Highlight(false);		

		container = null;	
		
		this.SaveState();
	},

	AdjustObjectSize : function (dockableObject)
	{
		if (this.FixedSizeMode)
		{
			var rc = dockableObject.GetRect();
			if (!dockableObject.FloatingWidth)
			{
				dockableObject.FloatingWidth = rc.width;
			}
			
			if (dockableObject.Expanded)
			{	
				if (!dockableObject.FloatingHeigth)
				{
					dockableObject.FloatingHeigth = rc.height;
				}
			}
				
			if (!this.FixedWidth || !this.FixedHeight)
			{		
				var rect = this.GetRect();
				this.FixedWidth = rect.width;
				this.FixedHeight = rect.height;
			}
		}
		else if (dockableObject.FloatingWidth || dockableObject.FloatingHeigth)
		{
			dockableObject.SetSize(dockableObject.FloatingWidth, dockableObject.FloatingHeigth);
			dockableObject.FloatingWidth = null;
			dockableObject.FloatingHeigth = null;
		}

		var widthSet = false;
		if ((this.FixedSizeMode & RadDockNamespace.RadDockingZoneFixedSizeFlags.ByWidth) > 0)
		{
			widthSet = true;
			dockableObject.style.width = (this.FixedWidth + "px");
			//dockableObject.style.height = "";
		}	
		if ((this.FixedSizeMode & RadDockNamespace.RadDockingZoneFixedSizeFlags.ByHeight) > 0)
		{
			if (dockableObject.Expanded)
			{
				dockableObject.style.height = (this.FixedHeight + "px");
				//if (!widthSet)
				//{
				//	dockableObject.style.width = "";
				//}
			}
			else
			{
				dockableObject.ExpandedHeight = (this.FixedHeight + "px");
			}
		}
	},
	
	FixObjectSizeOnInit : function()
	{
		var arr = this.GetDockedObjects();
		for (var i = 0; i < arr.length; i++)
		{
			this.AdjustObjectSize(arr[i]);
		}
	},

	GetRect : function (element)
	{
		return RadGetElementRect(element || this);
	},

	HitTest : function (dockableObject, eventArgs, dockableObjectRect)
	{
		this.HoveredElement = null;
		if (!this.DockEnabled)
		{
			return false;
		}
		
		var rect = this.GetRect();
		
		if (!dockableObjectRect)
			dockableObjectRect = dockableObject.GetRect();
		
		var x = RadDockNamespace.GetScrollLeft() + eventArgs.clientX;
		var y = RadDockNamespace.GetScrollTop() + eventArgs.clientY;
		
		// Different hit test methods:
		//	1. rect intersection
		//	2. mouse in rect
		
		// Method 1
		//var zoneHit = rect.Intersects(dockableObjectRect) && dockableObject.CanDockTo(this);	
		// Method 2
		var zoneHit = rect.PointInRect(x, y) && dockableObject.CanDockTo(this);	
		if (zoneHit)
		{
			this.HoveredElement = this;
			
			var container = (this.tagName == "TABLE") ? this.rows[0].cells[0] : this;
			var node, objHit;
			for (var i = 0; i < container.childNodes.length; i++)
			{
				node = container.childNodes[i];
				if (node.IsDockableObject
					&& node.IsDockingEnabled
					&& dockableObject != node)
				{
					// Method 1
					//objHit = (node.GetRect().Intersects(dockableObjectRect));
					// Method 2
					objHit = (node.GetRect().PointInRect(x, y));
					if (objHit)
					{
						this.HoveredElement = node;
						break;
					}
				}
			}
			container = null;
		}
		return zoneHit;
	},

	Highlight : function (highlight)
	{
		var container = (this.tagName == "TABLE") ? this.rows[0].cells[0] : this;
		
		highlight = (highlight != false);
		if (highlight)
		{
			// highlight hoverd element
			var hoveredElement = this.HoveredElement;
			
			this.HighlightElement(this, this == hoveredElement);
			var node;
			for (var i = 0; i < container.childNodes.length; i++)
			{
				node = container.childNodes[i];
				if (node.Undock)
				{
					this.HighlightElement(node, node == hoveredElement);
				}
			}
		}
		else if (!highlight && this.IsHighlighted)
		{
			// remove highlighting of previously highlighted zone	
			this.HighlightElement(this, false);
			var node;
			for (var i = 0; i < container.childNodes.length; i++)
			{
				node = container.childNodes[i];
				if (node.Undock)
				{
					this.HighlightElement(node, false);
				}
			}
		}
			
		this.IsHighlighted = highlight;
		container = null;
	},

	HighlightElement : function (element, highlight)
	{
		highlight = (highlight != false);
		
		if (highlight && null == element.oldStyleText)
		{
			element.oldStyleText = element.style.cssText;
			
			element.style.cssText += (";" + this.HighlightedStyleText);
		}
		else if (!highlight && null != element.oldStyleText)
		{
			element.style.cssText = element.oldStyleText;		
			element.oldStyleText = null;
		}
	},

	SaveState : function ()
	{
		var values = new Array();
		var childNodes = this.GetContainer().childNodes;
		var child;
		
		for (var i = 0; i < childNodes.length; i++)
		{
			child = childNodes[i];
			if (!child.IsDockableObject)
				continue;
			values[values.length] = child.ServerID;
		}
			
		this.HiddenInput.value = values.join(",");
	},

	ExpandAll : function (expanded)
	{
		var container = this.GetContainer();
		var node;
		for (var i = 0; i < container.childNodes.length; i++)
		{
			node = container.childNodes[i];
			if (node.IsDockableObject
				&& node.CanCollapse())
			{
				node.Expand(expanded);
			}
		}
	},

	CollapseAllObjects : function ()
	{
		this.ExpandAll(false);
	},

	ExpandAllObjects : function ()
	{
		this.ExpandAll(true);
	}
};

//BEGIN_ATLAS_NOTIFY
if (typeof(Sys) != "undefined")
{
    if (Sys.Application != null && Sys.Application.notifyScriptLoaded != null)
    {
        Sys.Application.notifyScriptLoaded();
    }
}
//END_ATLAS_NOTIFY
