<!--
//////////////////
// BOXES OBJECT //
//////////////////

//Creating Boxes object to represent the Tabs in memory
var Boxes = new Object;

Boxes.Objects_IDs	= new Array; //List array for the existing Boxes objects' IDs (numeric). Contains all existing Boxes IDs
Boxes.Objects		= new Array; //Associated array for the existing Boxes objects (HTML::DIV)
Boxes.Handlers		= new Array; //Array for the existing Boxes handlers (for handling events)

Boxes.LoadedScripts	= new Array; //Array indicating which scripts were loaded to the document already (by name)

Boxes.Comm		= new Object; //Boxes communication handler - Not implemented (fully) yet - Keeps track of Boxes Ajax communications
Boxes.Comm.Statuses	= new Array; //Array for the Boxes communication channels status flags



Boxes.ActiveBoxID	= null; //Which Box (by ID) is active
Boxes.EditableBoxID	= null; //Which Box (by ID) is in title edit mode
Boxes.EditBoxDefocusInt	= null; //Used for defocusing a Box (uses timeout instead of direct call)

Boxes.DraggedBoxAnchor	= null; //The dragged Box anchor object (HTML::DIV) holder

//Boxes.DragState		= false; //Indicate if a Box is in edit mode
Boxes.EditState		= false; //Indicate if a Box is in edit mode
Boxes.CommandExecState	= false; //Indicates if the system is executing (ajax) command

Boxes.EditMode		= true; //Indicates if a boxes are in edit mode






///////////////////
// BOX FUNCTIONS //
///////////////////

Boxes.Init = function ()
{
	if (Boxes.EditMode)
	{
		Boxes.BoxTool = new YAHOO.widget.Dialog("BoxTool");
		Boxes.BoxTool.cfg.queueProperty("underlay","none");
		Boxes.BoxTool.cfg.queueProperty("constraintoviewport",true);
		Boxes.BoxTool.cfg.queueProperty("width","500px");
		Boxes.BoxTool.cfg.queueProperty("modal",true);
	}
}


//Boxes visual functions
Boxes.Hide=function() {};
Boxes.Show=function() {};
Boxes.Refresh=function() {Boxes.Hide(); Boxes.Show();};




//A function for generating Event execution funcions
Boxes._GENERATE_ExecuteEvent = function(BoxHandler,Action) {return function(){return BoxHandler[Action].apply(BoxHandler,arguments)};};




//Refresh communication indicator. Not implemented yet
Boxes.Comm.UpdateCommIndicator = function()
{
}





Boxes.GetOffset=function(BoxObject,isTop)
{// Returns the offset (X or Y) of a specific Tab object
	return GetElementOffset(BoxObject,isTop);
};






Boxes.CountBoxes=function(PageID)
{// Returns the offset (X or Y) of a specific Tab object
	var CountIndex;
	var Count=0;
	for (CountIndex=0; CountIndex<Boxes.Objects_IDs.length;CountIndex++)
	{
		if ((Boxes.Objects[Boxes.Objects_IDs[CountIndex]].PageID==PageID) && (Boxes.Objects_IDs[CountIndex]>=0)) {Count++}
	}
	CountIndex = null; //Free up memory
	return Count;
};





Boxes.PluckBox=function(Box)
{//plucks out a box from the HTML (visually only). Pushes other boxes to the left
 //Needed?
 //Attention: May need to limit to a specific container

	var CurrentHandler;
	var IndexRun;
	
	//Hard sets current offsets of all existing boxes (?)
	for(IndexRun=0;IndexRun<Boxes.Objects_IDs.length;IndexRun++)
	{
		CurrentHandler=Boxes.Handlers[Boxes.Objects_IDs[IndexRun]];
		CurrentHandler.Box.OffsetTop=Boxes.GetOffset(CurrentHandler.Box,true)
		CurrentHandler.Box.OffsetLeft=Boxes.GetOffset(CurrentHandler.Box,false);
	}
	CurrentHandler = null; //Free up memory
	
	//Runs through the following boxes and changes their offset to push them left
	var NextBox=Box.nextSibling;
	while(NextBox)
	{
		if (NextBox.Box) {NextBox.OffsetTop-=NextBox.Box.offsetHeight}; //Excludes terminator (?)
		NextBox=NextBox.nextSibling; //Moves to the next tab
	}
	
	//Free up memory
	NextBox = null;
	IndexRun = null;
};






Boxes.GetDraggedBoxAnchor=function(PageID,ContainerID,Set_Box_innerHTML)
{//Retrieves (OR creates) the dragged Box object (HTML::DIV). Can set dragged Box content to that of the original for nicer drag effect

	if (!Boxes.DraggedBoxAnchor)
	{//If dragged Box object doesn't exist yet create it
		//Boxes.DraggedBoxAnchor=CreateBoxHTML(PageID,ContainerID,-1,"Set_Box_innerHTML"); //PageID,ContainerID,BoxID,BoxName (? - deal with box name/html issue)
		
		var NewAnchor = document.createElement("DIV");
		NewAnchor.BoxID=-1; //Backup copy of the BoxID in the DOM of the box object
		NewAnchor.PageID=PageID;
		NewAnchor.ContainerID=ContainerID;
		NewAnchor.innerHTML = Set_Box_innerHTML;
		
		Boxes.DraggedBoxAnchor=NewAnchor;
		
		NewAnchor = null; //Free up memory

		Boxes.DraggedBoxAnchor.className="box box_dragged";
		
		Boxes.DraggedBoxAnchor.style.filter="alpha(opacity=60)";
		Boxes.DraggedBoxAnchor.style.opacity=0.6;
//		Boxes.DraggedBoxAnchor.style.border="1px dotted #000080";
//		Boxes.DraggedBoxAnchor.style.background="transparent url(/images/transparent40.png) repeat scroll 0 0"; //for opera	
	}
	
	if (!Set_Box_innerHTML) {return Boxes.DraggedBoxAnchor;}

	//...else - Reset HTML of dragged box
	Boxes.DraggedBoxAnchor.innerHTML = Set_Box_innerHTML;
	//Boxes.DraggedBoxAnchor.Title_Label_Main.innerHTML = Set_Box_innerHTML; 

	return Boxes.DraggedBoxAnchor;
};





Boxes.GetBoxesOrder_Str=function(PageID,ContainerID)
{//Creates the Boxes order string (for a specific page/container) according to the HTML objects' order
	var BoxesOrderStr="";
	var BoxObject;
	var IndexRun;
	for(IndexRun=0;IndexRun<=Pages.Objects[PageID].Containers[ContainerID].Container.childNodes.length-1;IndexRun++) //Excluding terminator (which is always last object [childNodes.length-1])
	{
		BoxObject=Pages.Objects[PageID].Containers[ContainerID].Container.childNodes[IndexRun];
		if(BoxObject.tagName=="DIV") //Runs only on DIVs. Other object types can not be Boxes
		{
			if (BoxObject.BoxID > 0)
			{
				BoxesOrderStr+= (BoxesOrderStr!="")?"_":"";
				BoxesOrderStr+= BoxObject.BoxID;
			}
		}
	}

	//Free up memory
	IndexRun = null;
	TabObject=null;

	return(BoxesOrderStr);
}






Boxes.GetContainingBox=function(HTMLObject)
{//Locates the BoxObject containing an HTML element
	var CurrentNode = HTMLObject;
	while(CurrentNode && CurrentNode.ObjectType != "Klostu_Box") {CurrentNode = CurrentNode.parentNode}

	return(CurrentNode);
}

Boxes.GetContainingTitle=function(HTMLObject)
{//Locates the Title (of the BoxObject) containing an HTML element
	return(Boxes.GetContainingBox(HTMLObject).Title);
}

















/////////////////////
// BOX DRAG ENGINE //
/////////////////////


var Boxes_Drag_Engine={
	BoxObject:null, //Dragged Box object container variable - filled when drag is started
	
	init:function(Box)
	{//Called upon each Box Handler's creation
		// Prepares the events for the dragged Box
		Box.onmousedown=Boxes_Drag_Engine.start;
		//Drag events are not set yet. Will be set on drag initiation
		Box.onDragStart=new Function;
		Box.onDragEnd=new Function;
		Box.onDrag=new Function

		//In case Tab has no position, seys position to 0/0 (for code safety)
		if(isNaN(parseInt(Box.style.left))) Box.style.left="0px";
		if(isNaN(parseInt(Box.style.top))) Box.style.top="0px";
	},
	
	finalize:function(Box)
	{//Free up memory - Called on tabs unload (on page closing) (?) OR upon drag_end?
		Box.onmousedown=null;
		Box.onDragStart=null;
		Box.onDragEnd=null;
		Box.onDrag=null

		Box.object=null;
	},
	
	start:function(Event)
	{
		//Do not allow drag start if in Box title edit state
		if (Boxes.EditableBoxID != null) {if (Boxes.Handlers[Boxes.EditableBoxID].EditState) {return};}
		
		//Otherwise...
		
		Event=Boxes_Drag_Engine.normalize_event(Event); //Normalizes Event object
		if(Event.which!=1) {return true}; //Drag starts only on left mouse button click
		if(!IsChildOf(Event.target,this.Title)) {return true}; //Drag starts only on the title (and its children)

		//Selectes AND SAVES the passed tab object (this - executes within )
		var SelectedBoxObject=Boxes_Drag_Engine.BoxObject=this;
		
		SelectedBoxObject.onDragStart(); //Executes drag start event on the dragged Box (Plucking box, creating anchor ...)
		
		//Saves the initial position (and in this case also last position) of the object/mouse
		SelectedBoxObject.Mouse_X_Latest=Event.clientX+document.body.scrollLeft;
		SelectedBoxObject.Mouse_Y_Latest=Event.clientY+document.body.scrollTop;
		SelectedBoxObject.Mouse_X_Original=Event.clientX+document.body.scrollLeft;
		SelectedBoxObject.Mouse_Y_Original=Event.clientY+document.body.scrollTop;
		
		//Sets the trag engine's mouse up/down events as the documents' events
		document.onmouseup=Boxes_Drag_Engine.end;
		document.onmousemove=Boxes_Drag_Engine.drag;
		
		SelectedBoxObject = null; //Free up memory
		
		return true;
	},
	
	drag:function(Event)
	{// Called during the drag
		if (Boxes.EditableBoxID != null) if (Boxes.Handlers[Boxes.EditableBoxID].EditState) {return}; //Does not take effect during tab title edit mode
		if (!Boxes_Drag_Engine.BoxObject) {return}; //Does not take effect if no Tab is selected

		//Otherwise...
		
		Event=Boxes_Drag_Engine.normalize_event(Event);//Normalizes Event object
		if(Event.which==0) {return Boxes_Drag_Engine.end()} //When mouse is released, release drag
		
		var SelectedBoxObject=Boxes_Drag_Engine.BoxObject; //Retrieves Box object
		var Mouse_X_Current=Event.clientX+document.body.scrollLeft;
		var Mouse_Y_Current=Event.clientY+document.body.scrollTop;

		//Abort if same position as last
		if(Mouse_X_Current==SelectedBoxObject.Mouse_X_Latest && Mouse_Y_Current==SelectedBoxObject.Mouse_Y_Latest) {return false};
		 
		//Calculates position of mouse in relation to original position when drag started. Do not allow drag if distance is less than 8 pixels
		var Distance;
		if (SelectedBoxObject.Mouse_X_Original != -1000) //Only if not released yet (Mouse_X_Original != -1000)
		{
			Distance = Math.sqrt(Math.pow(Mouse_X_Current-SelectedBoxObject.Mouse_X_Original,2)+Math.pow(Mouse_Y_Current-SelectedBoxObject.Mouse_Y_Original,2));//Calculates the position
			if (Distance<8) 
				{return false} //Cancels the drag even - do nothing
			else 
				{Box_Drag_Start_Execute(Boxes_Drag_Engine.BoxObject); SelectedBoxObject.Mouse_X_Original = -1000}; //Continue with the drag event - release the original position lock by setting the original mouse-X to -1000
		};

		//Retrieves the Mouse position
		var BoxY_Current=parseInt(SelectedBoxObject.style.top);
		var BoxX_Current=parseInt(SelectedBoxObject.style.left);
		
		//calculates the new Box's position based on the mouse offset from the last position
		var New_Y=BoxY_Current + Mouse_Y_Current - SelectedBoxObject.Mouse_Y_Latest;
		var New_X=BoxX_Current + Mouse_X_Current - SelectedBoxObject.Mouse_X_Latest;
		
		//Reposition the dragged Box in the new place
		SelectedBoxObject.style.top =New_Y+"px";
		SelectedBoxObject.style.left=New_X+"px";

		//Updates the Box's last mouse position
		SelectedBoxObject.Mouse_Y_Latest=Mouse_Y_Current;
		SelectedBoxObject.Mouse_X_Latest=Mouse_X_Current;

		//SelectedBoxObject.onDrag(New_X,New_Y); - Less effective/nice than basic drag/drop on the mouse position
		//SelectedBoxObject.onDrag(New_X,New_Y); + half width?
		//SelectedBoxObject.onDrag(New_X,New_Y);
		SelectedBoxObject.onDrag(Mouse_X_Current,Mouse_Y_Current); //Calling Boxes' onDrag event (commits drag changes in needed)
		
		//Free up memory
		SelectedBoxObject = null;
		BoxY_Current = null;
		BoxX_Current = null;
		New_X = null;
		New_Y = null;
		Distance = null;
		Mouse_X_Current = null;
		Mouse_Y_Current = null;
		
		return false;
	},
	
	end:function(Event)
	{//Ends drag session
		if (Boxes.EditableBoxID != null) if (Boxes.Handlers[Boxes.EditableBoxID].EditState) {return}; //Do not attempt to execute drag-end if in box title edit state (no drag was started)
		if (!Boxes_Drag_Engine.BoxObject) {return}; //Do not attempt to execute drag-end if no BoxObject exists (no drag was started)
		
		Event=Boxes_Drag_Engine.normalize_event(Event); //Normalizes Event object

		//Free up documents' mouse events (previously taken over by drag engine)
		document.onmousemove=null;
		document.onmouseup=null;
		
		var RetVal=Boxes_Drag_Engine.BoxObject.onDragEnd(); //Dropping box (Execute OnDragEnd)
		Boxes_Drag_Engine.BoxObject=null; //Releases the dragged box from the drag engine
		
		return RetVal;
	},
	
	normalize_event:function(Event)
	{//Returns a modified Event object containing cross-browser properties
		if(typeof Event=="undefined")		{Event		= window.event};
		if(typeof Event.which=="undefined")	{Event.which	= Event.button};
		if(typeof Event.target=="undefined")	{Event.target	= Event.srcElement};
		return Event;
	}
};









/*////////????????????????????????

Boxes.Redraw=function() {
//Refresh all current active boxes? or for a given container?
	
	//First - Freeing up the currently active Box arrays (Except terminators)
	for (var IndexRun=0;IndexRun<Boxes.Objects_IDs.length;IndexRun++)
	{
		if (Boxes.Objects_IDs[IndexRun]>=0)
		{
			var BoxObject=Boxes.Objects[Boxes.Objects_IDs[IndexRun]];
			Boxes.Objects[IndexRun] = null;
			Boxes.Handlers[IndexRun] = null;
		};
	};

	Boxes.Objects_IDs = null;
	Boxes.Objects_IDs = new Array;
	for (var IndexRun=0; IndexRun<=4; IndexRun++)
	{//Readding terminators to containers
		AddBoxToContainer(-1-IndexRun,IndexRun);
	};

	//Second - Recreates the active Box arrays for linear move through the Repository,
	//		and activating/adding all needed box to arrays and containers, while removing all unneeded ones
	for (var IndexRun=0;IndexRun<Boxes.Repository.Objects_IDs.length;IndexRun++)
	{
		if (Boxes.Repository.Objects_IDs[IndexRun]<0) {continue}; //Skips terminators
		
		var BoxObject=Boxes.Repository.Objects[Boxes.Repository.Objects_IDs[IndexRun]];

		if (BoxObject.parentNode) {BoxObject.parentNode.removeChild(BoxObject)}; //Removes object just in case. To be added in the right place soon, if needed
		
		if (BoxObject.TabID==Tabs.ActiveTabID)
		{//Object should be on the page
			AddBoxToContainer(BoxObject.BoxID,BoxObject.ContainerID);
		}
		else
		{//Box should not be on the page
		}
	};

};


///////////////??????????????????*/







/*
function unloadBoxes()
{
	for(var IndexRun=0;IndexRun<Boxes.Objects_IDs.length;IndexRun++)
	{
		Boxes.Objects[Boxes.Objects_IDs[IndexRun]] = null;
		Boxes.Handlers[Boxes.Objects_IDs[IndexRun]] = null;
	}

	for(var IndexRun=0;IndexRun<Boxes.Repository.Objects_IDs.length;IndexRun++)
	{
		Boxes.Objects[Boxes.Repository.Objects_IDs[IndexRun]] = null;
		Boxes.Handlers[Boxes.Repository.Objects_IDs[IndexRun]] = null;
	}
	
	Boxes.Objects_IDs	= null;
	Boxes.Objects		= null;
	Boxes.Handlers		= null;

	Boxes.Repository.Objects	= null;
	Boxes.Repository.Handlers	= null;
	
	Boxes.DraggedBoxAnchor = null;
}

//??????????? Implement
//RegisterEvent("unload",unloadBoxes); 
*/


















///////////////////////
// BOX EVENT HANDLER //
///////////////////////


function BoxHandler(BoxObject)
{//Creates a Box Handler - Responsible for handling Box events
	this.Box	= BoxObject; //Links Handler to the Box Object (HTML::DIV)

	//Resets state variables
	this.DragState	= false;
	this.EditState	= false;
	this.ActiveState= false;
	this.MouseDown	= false;

	Boxes_Drag_Engine.init(this.Box);

	//Associates Events list
	this._mouseup	= Box_Mouse_Up;
	this._mousein	= Box_Mouse_In;
	this._mouseout	= Box_Mouse_Out;

	this._dragStart	= Box_Drag_Start;
	this._dragEnd	= Box_Drag_End;
	this._drag	= Box_Drag;
	this._drop	= Box_Drop;

	//???
	//this._unload	= unloadBoxes;
	//this._action	= Box_Actions;
	
	//Create events into the Tab object (HTML::DIV) - Events are a simple "trigger" mechanism calling the function associated wih the above set Events list
	this.Box.onmouseup	= Boxes._GENERATE_ExecuteEvent(this,"_mouseup");
	this.Box.onmouseover	= Boxes._GENERATE_ExecuteEvent(this,"_mousein");
	this.Box.onmouseout	= Boxes._GENERATE_ExecuteEvent(this,"_mouseout");
	
	this.Box.onDragStart	= Boxes._GENERATE_ExecuteEvent(this,"_dragStart");
	this.Box.onDragEnd	= Boxes._GENERATE_ExecuteEvent(this,"_dragEnd");
	this.Box.onDrag		= Boxes._GENERATE_ExecuteEvent(this,"_drag");
}








////////////////
// BOX EVENTS //
////////////////


function Box_Drag_Start()
{//Event for starting Tab drag - OR for clicking the tab (Doesn't yet execute a drag)
	this.MouseDown = true; //Setting Handler to indicate mouse is down
}


function Box_Drag_Start_Execute(Box)
{//Event for starting Tab drag (after initial number of pixels was passed)
	
	Tabs.DragToTabID = null; //Resets drag-to-tab indicator
	
	//Disable controls visivility for the dragged Box (? taken from tab)
	Box.Controls_Edit.className = 'box_controls';
	Box.Controls_Close.className = 'box_controls';

	Boxes.PluckBox(Box); //Plucks the box out of the HTML (visually)
	Box.Handler.NextBox_Original=Box.nextSibling; //Stores the original "next tab" for later use (revert) - Not needed?
	
	var DraggedBoxAnchor=Boxes.GetDraggedBoxAnchor(Box.PageID,Box.ContainerID,Box.innerHTML); //Retreive (or create) the dragged box anchor object (HTML::DIV) placed instead of the dragged box
	DraggedBoxAnchor.style.visibility="hidden"; //Hides the achnor while the box is not yet dragged

	//retreives dragged box anchor needed height and width
	var DraggedBoxAnchor_Height=Box.offsetHeight;
	var DraggedBoxAnchor_Width=Box.offsetWidth;
	
	//Browser specific calculations for Dragged Tab Anchor width and height
	if (isGecko || isOpera)
	{//removes the borders width/height
		DraggedBoxAnchor_Width-=parseInt(DraggedBoxAnchor.style.borderTopWidth);
		DraggedBoxAnchor_Width-=parseInt(DraggedBoxAnchor.style.borderBottomWidth);
		DraggedBoxAnchor_Height-=parseInt(DraggedBoxAnchor.style.borderLeftWidth)
		DraggedBoxAnchor_Height-=parseInt(DraggedBoxAnchor.style.borderRightWidth)
	};
	
	//Gets the Box's current position (where dragging starts from)
	var Box_NewTop=Boxes.GetOffset(Box,true);
	var Box_NewLeft=Boxes.GetOffset(Box,false);
	
//	Pages.Hide(Box.PageID);
	
	//Resizing dragged Box
//	DragedBox.style.width="100%"; (?)
	DraggedBoxAnchor.style.height=DraggedBoxAnchor_Height+"px";
	DraggedBoxAnchor.style.width=DraggedBoxAnchor_Width+"px";
	//Box.style.width=DragedBox_Width+"px";

	Box.parentNode.insertBefore(DraggedBoxAnchor,Box.nextSibling); //Places the dragged box anchor before the next object - where the dragged box was

	var CurrentBoxWidth=Box.offsetWidth;

	//Moving the dragged Box to absolute position to allow dragging. Placing Box in correct position (where originally was)
	Box.style.position="absolute";
	//Box.style.zIndex=99;
	Box.style.top=Box_NewTop+"px";
	Box.style.left=Box_NewLeft+"px";
	
	//Sets the width of the box to the above saved value (so it doesn't change after moved to absolute positioning)
	Box.style.width=CurrentBoxWidth+"px";
	CurrentBoxWidth = null; //Free up memory

//	Pages.Show(Box.PageID);

	Pages.Refresh(Box.PageID); //Refreshes the Tabs to make sure visual effects take place

	Box.Handler.DragStatus=false; //Will reset on first call to event Box_Drag
	
	return false;
}







function Box_Drag_End()
{//Finalizes the Tab dragging (Happens on OnDragEnd event)
	var WasDragged = this.DragState; //May have been triggered without the Box realy dragged - storing in variable before _drop() is executed

	var Moved = this._drop(); //Drops box first. Stores "moved" flag
	//Dropping the Box. If Box was dragged, was moved (as returned from _drop()) and the new order is indeed dirrerent, saves new order to server
	if((Moved) && (WasDragged)) {Server_SaveBoxesOrder(this.Box.PageID,this.Box.ContainerID)}

	//Free up memory
	WasDragged = null;
	Moved = null;

	var DraggedBoxAnchor=Boxes.GetDraggedBoxAnchor(); //Retreive (or create) the dragged box anchor object (HTML::DIV)
	DraggedBoxAnchor.style.visibility="hidden"; //Hides the achnor when not in drag more (just in case)
	DraggedBoxAnchor = null; //Free up memory
	
	return true;
}




function Box_Drag(New_X,New_Y)
{//Executes during dragging
	if(!this.DragState)
	{//if Box is not yet set into dragged state
		EditBoxName_Cancel(); //Cancels title edit (if active)

		//Sets tab to be 60% transparent
		this.Box.style.filter="alpha(opacity=40)";
		this.Box.style.opacity=0.4;
		this.DragState=true; //Sets the Tab's dragged state
//		this.Action("dragstart") - DEPRECATED
	}
	
	//Checking tabs drag match
	var DragToTab=false;
	var TabClassName;
	var IndexRun;
	var TabObject;
	
	Tabs.DragToTabID = null; //Resets trag-to-tab indicator. Will flag again soon (below) if drag is to a tab.
	
	for (IndexRun=0;IndexRun<Tabs.Objects_IDs.length;IndexRun++)
	{//Runs through all the tabs
		if (Tabs.Objects_IDs[IndexRun]<=0) {continue}; //Ignores new or terminator tabs
		TabObject = Tabs.Objects[Tabs.Objects_IDs[IndexRun]];

		TabClassName = (TabObject.TabID==Tabs.ActiveTabID)?"tab tab_active":"tab";
			
		//Checks if the dragging is without the bounderies of the Tab
		if (
			((New_X>GetElementOffset(TabObject,0)) && (New_X<GetElementOffset(TabObject,0)+TabObject.offsetWidth)) &&
			((New_Y>GetElementOffset(TabObject,1)) && (New_Y<GetElementOffset(TabObject,1)+TabObject.offsetHeight))
		)
		{//If so... marks the DragToTab flag and prepares a highlighted classname for the tab
			TabClassName =TabClassName + " tab_boxdrag";
			DragToTab = true;
			Tabs.DragToTabID = Tabs.Objects_IDs[IndexRun];
		}

		//Highlights/Un-highlights the destination tab
		TabObject.className = TabClassName;
		
	};
	
	//Otherwise... not dragging into a tab...
	
	//Free up memory
	TabClassName = null;
	IndexRun = null;
	TabObject = null;
	
	if (DragToTab) 
	{//If drag is to a box, hide the dragged Box and remove it from it's container
		var DraggedBoxAnchor=Boxes.GetDraggedBoxAnchor();
		if (DraggedBoxAnchor.parentNode) {DraggedBoxAnchor.parentNode.removeChild(DraggedBoxAnchor)};
		Pages.Refresh();
		
		//Free up memory
		DraggedBoxAnchor = null;
		DragToTab = null;

		return;
	};

	//Else - move on to containers check
	DragToTab = null; //Free up memory
	

	//Finds the closest box/container (to place dragged tab next to it)
	var BoxObject;
	var Distance;
	var ClosestBox_Object=null;
	var ClosestBox_Distance=999999999;
	var IndexRun;
	
	//First determining what area of the page the drag is into
	var ActivePage = Pages.Objects[Pages.ActivePageID]; //Fetching the active page object


	var DestinationArea = "";
	if (	(New_Y<GetElementOffset(ActivePage.Containers[0].Container,1)+ActivePage.Containers[0].Container.offsetHeight) && 
		(New_Y>GetElementOffset(ActivePage.Containers[0].Container,1)-10)	)
	{DestinationArea = 0}//Header
	else if (	(New_Y>GetElementOffset(ActivePage.Containers[4].Container,1)) && 
			(New_Y<GetElementOffset(ActivePage.Containers[4].Container,1)+ActivePage.Containers[4].Container.offsetHeight+50)	)
	{DestinationArea = 4}//Footer
	else if (	(New_Y>GetElementOffset(ActivePage.Containers[0].Container,1)+ActivePage.Containers[0].Container.offsetHeight-5) &&
			(New_Y<GetElementOffset(ActivePage.Containers[4].Container,1)+5)	)
	{DestinationArea = 123};//Columns

	ActivePage = null; //Free up memory
	
	
	for(IndexRun=0;IndexRun<Boxes.Objects_IDs.length;IndexRun++) //Runs through all Box onjects (based in IDs table)
	{
		BoxObject=Boxes.Objects[Boxes.Objects_IDs[IndexRun]]; //Retrieves the box object
		if (BoxObject.PageID != Pages.ActivePageID) {continue}; //Checks only boxes within the current page
			
		Distance = ClosestBox_Distance + 1; //Sets distance to larger than current - so that if box is not matched, it wont be "closer" than the currently selected

		if ((BoxObject.ContainerID==0) && (DestinationArea==0))
		{//Matches box in header
			Distance = Math.sqrt(
				Math.pow(New_Y-(BoxObject.OffsetTop+BoxObject.offsetHeight/2),2)
			);//Calculates distance in header based on Y axis only
		}
		
		else if (
			((BoxObject.ContainerID==4) && (DestinationArea==4))
		)
		{//Matches box in footer
			Distance = Math.sqrt(
				Math.pow(New_Y-(BoxObject.OffsetTop+BoxObject.offsetHeight/2),2)
			);//Calculates distance in header based on Y axis only
		}
		
		else if (
			(BoxObject.ContainerID>0) && 
			(BoxObject.ContainerID<4) &&
			(DestinationArea==123)
		)
		{//Matches box in columns
			Distance = Math.sqrt(
				Math.pow(New_X-(BoxObject.OffsetLeft+BoxObject.offsetWidth/2-10),2)+
				Math.pow(New_Y-(BoxObject.OffsetTop+BoxObject.offsetHeight/2),2)
			);//Calculates distance in header based on both X & Y axis
		};
		
		if (BoxObject==this.box) continue; //(?)
		if (isNaN(Distance)) continue; //No box match (?)
		
		if(Distance < ClosestBox_Distance) //Checking if new distance is shorter
		{//Updating params
			ClosestBox_Distance=Distance;
			ClosestBox_Object=BoxObject;
		}
	};
	
	var DraggedBoxAnchor=Boxes.GetDraggedBoxAnchor();
	DraggedBoxAnchor.style.visibility=""; //makes sure the anchor is visible
	
	if ((ClosestBox_Object != null) && (ClosestBox_Object != DraggedBoxAnchor.nextSibling) && (ClosestBox_Object !=Boxes_Drag_Engine.BoxObject))
	{//If there is a closeby box and it is not the original place (negating the need to move the anchor) - moving the anchor
		DraggedBoxAnchor.style.width=ClosestBox_Object.offsetWidth; //Sets the width of the dragged anchor BEFORE moving the box, so the anchor adopts the width of the box (or terminator box)
		ClosestBox_Object.parentNode.insertBefore(DraggedBoxAnchor,ClosestBox_Object);
//		Debug("noving anchor before: "+ClosestBox_Object.id);
		
		if(isOpera)
		{//Attention: Refreshes Box for opera (change code)
			/*document.body.style.display="none";
			document.body.style.display=""*/
		}
	}
	
	/*else = Not needed? leave anchor where is if no match found
	{
		if ((ClosestBox_Handler==null) && (DraggedBoxAnchor.parentNode)) 
		{
			DraggedBoxAnchor.parentNode.removeChild(DraggedBoxAnchor);
			Page.Refresh();
		};
	}*/
	
	//Free up memory
	ClosestBox_Object = null;
	ClosestBox_Distance = null;
	DraggedBoxAnchor = null;
	IndexRun = null;
	BoxObject = null;
	Distance = null;
	DestinationArea = null;

}




function Box_Drop()
{//Executes in Box_Drag_End (when mouse is released and Box is dropped)

	var Moved=false; //Assuming for now Tab was not moved

//	Boxes.Hide();

	//Returns Tab to regular positioning and visualization
	this.Box.style.position="";
	this.Box.style.width="";
	//this.Box.style.zIndex="";
	this.Box.style.filter="";
	this.Box.style.opacity="";

	var DraggedBoxAnchor=Boxes.GetDraggedBoxAnchor(); //this.Box.innerHTML - not needed. Dragged box anchor already exists

	//Updates containerID
	//var NewContainerID = IdentifyContainerID(DraggedBoxAnchor.parentNode);
	
/* - Replaced with MoveBox mechanism
	if(DraggedBoxAnchor.nextSibling != this.NextBox_Original) //Only if anchor is not where the Box was originally... Tab was moved
	{
		DraggedBoxAnchor.parentNode.insertBefore(this.Box,DraggedBoxAnchor.nextSibling); //Reinserts the Box in it's new position (After the anchor)
		Moved=true; //Flags Moved state
	}

	DraggedBoxAnchor.parentNode.removeChild(DraggedBoxAnchor); //Removes the Dragged Box Anchor from the HTML document
	
//	Boxes.Show();
//	Boxes.Refresh();
*/
	
//	Debug("Put before "+DraggedBoxAnchor.nextSibling.BoxID);
	//Moving the box to the new location - Both visually and on server
	if (Tabs.DragToTabID)
	{//Dragging box to a tab
		//Attention!!!: Dragging to main container! (at the end). Assuming it is visible. Change when container invisibility is allowed
		if (MoveBox(this.Box.BoxID, Tabs.DragToTabID, 2)) //#1st Param: Box to move  ;  #2nd Param: Destination Tab/Page  ;  #3nd Param: Destination Conatainer  ;  #4th Param: Before Box..
		{
			Moved=true; //Flags Moved state
		}
		else
		{Debug("Can't move?")}
	}
	else if (DraggedBoxAnchor.nextSibling) 
	{//If anchor is positioned, move box
		if (MoveBox(this.Box.BoxID, DraggedBoxAnchor.nextSibling.PageID, DraggedBoxAnchor.nextSibling.ContainerID, DraggedBoxAnchor.nextSibling.BoxID)) //#1st Param: Box to move  ;  #2nd Param: Destination Tab/Page  ;  #3nd Param: Destination Conatainer  ;  #4th Param: Before Box..
		{
			Moved=true; //Flags Moved state
		}
	}
	else
	{//Otherwise, Anchor is nowhere - indicating dragging into illegal position. Do nothing.
	};
	
	if (DraggedBoxAnchor.parentNode) {DraggedBoxAnchor.parentNode.removeChild(DraggedBoxAnchor)}; //Removes the Dragged Box Anchor from the HTML document (if visible - not in case of tab drag for example)
	
//	Boxes.Refresh();

	/*if(isOpera) 
	{//Attention: Refreshes display (change code)
		document.body.style.display="none";
		document.body.style.display=""
	};*/

	//Reset tab's drag highlight if any was set
	var TabObject;
	var TabClassName;
	for (IndexRun=0;IndexRun<Tabs.Objects_IDs.length;IndexRun++)
	{//Runs through all the tabs
		if (Tabs.Objects_IDs[IndexRun]<=0) {continue}; //Ignores new or terminator tabs
		TabObject = Tabs.Objects[Tabs.Objects_IDs[IndexRun]];

		TabClassName = (TabObject.TabID==Tabs.ActiveTabID)?"tab tab_active":"tab";
	
		//Set tab's class
		TabObject.className = TabClassName;
		
	};
	
	Tabs.DragToTab = null; //Reset Tab-destination in case a box was dragged to the tab
	
	this.DragState=false; //Resets drag state
	
	//Free up memory
	DraggedBoxAnchor = null;
	TabObject = null;
	TabClassName = null;

	return Moved;
}


function Box_Mouse_Up()
{//When mouse button is up, assume Box was clicked - unless in Drag state, Edit state or Command execution
	if ((this.MouseDown)&&(!this.DragState)&&(!this.EditState)&&(!Boxes.CommandExecState)) {ActivateBox(this.Box.BoxID);};
	
	var IndexRun;

	for (IndexRun=0;IndexRun<Boxes.Objects_IDs.length;IndexRun++)
	{//Resets ALL Boxes' MouseDown state
		if (Boxes.Objects_IDs[IndexRun]<0) {continue};
		Boxes.Handlers[Boxes.Objects_IDs[IndexRun]].MouseDown = false;
	}
	
	IndexRun = null; //Free up memory
}


function Box_Mouse_In()
{//When mouse enters a box - Show the Box controls - Unless in edit or drag state
	if ((!this.DragState)&&(!this.EditState))
	{
		//Enabled controls visivility
		if (!this.Box.Controls_Edit.Hidden) {this.Box.Controls_Edit.className = 'box_controls_active'};
		if (!this.Box.Controls_Close.Hidden) {this.Box.Controls_Close.className = 'box_controls_active'};
	}
}


function Box_Mouse_Out()
{//When mouse is out - hide the Box controls
	//Disable controls visivility
	this.Box.Controls_Edit.className = 'box_controls';
	this.Box.Controls_Close.className = 'box_controls';
}





















/////////////////////
// BOX MANAGEMENT  //
/////////////////////


function Box_UpdateLoadStatus(Box_Object,Message)
{
	if (Message.length>0)
	{
		Box_Object.LoadingProgress.style.display="";
		Box_Object.LoadingProgress.innerHTML = "<center><img width=20 height=20 src='/images/progress_20x20_w.gif' align='absbottom'/><font color=#c0c0c0><b>"+Message+"</b></font></center>";;
	}
	else
	{
		Box_Object.LoadingProgress.style.display="none";
	};
}



function EditBox(BoxID)
{//Calls box edit
	if (Boxes.EditState) {EditBoxName_Cancel(1); return(false)} //Only one box can be edited. If attempting to enter (another) box edit, cancels current edit

	var EditBox_Object = Boxes.Objects[BoxID];

	if (EditBox_Object.EditBox) {EditBox_Object.EditBox(EditBox_Object)};
}


function EditBox_Finished(BoxID)
{//Leaves box edit - Usually called from the box code itself
	var EditBox_Object = Boxes.Objects[BoxID];

	if (EditBox_Object.EditBox_Finished) {EditBox_Object.EditBox_Finished(EditBox_Object)};
}





function EditBoxName_Edit(BoxID)
{//Enters edit mode for box title
	var Box_Object = Boxes.Objects[BoxID];

	if (!Box_Object) {return false};//Aborts if not a real box
	
	//Abort if box is inactive or already being edited
	if ((!Box_Object.Handler.ActiveState) || (BoxID == Boxes.EditableBoxID) || (Boxes.CommandExecState))
	{
		Box_Object = null; //Free up memory
		return;
	};
	
	//If another box is in edit mode, cancels the other box's editing and marks new box as edited.
	if (BoxID != Boxes.EditableBoxID) {EditBoxName_Cancel()};
	Boxes.EditableBoxID = BoxID;
	
	//Cancels box's drag if about to enter drag mode
	if (Boxes_Drag_Engine.BoxObject)
	{
		document.onmousemove=null;
		document.onmouseup=null;

		Boxes_Drag_Engine.BoxObject.onDragEnd();
		Boxes_Drag_Engine.BoxObject=null;
	}
	
	//Triggering box's edit state
	Box_Object.Handler.EditState=true;
	Boxes.EditState=true;
	
	//Sets the edit box's parameters
	Box_Object.Title_Edit.value = Edit(Box_Object.Title_Label_Main.innerHTML); //Sets the edit box just in case it was changed without commining (empty value for exampe)
	var EditWidth = Box_Object.Title_Label_Main.offsetWidth;

	Box_Object.Title_Label.className = 'box_title_label_container box_title_label_container_disabled';
//	Box_Object.Title_Label_Main.className = 'box_title_label_disabled box_title_label_main';
//	if (Box_Object.Title_Label_Shadow) {Box_Object.Title_Label_Shadow.className = 'box_title_label_disabled box_title_label_shadow'};
	
	Box_Object.Title_Edit.style.width=EditWidth+"px";
	Box_Object.Title_Edit.className = 'box_title_edit_enabled';

	//Sets edit box's ZIndex
	/*
	Box_Object.zIndex = 100;
	Box_Object.Title_Label_Main.zIndex = 101;
	if (Box_Object.Title_Label_Shadow) {Box_Object.Title_Label_Shadow.zIndex = 102};
	Box_Object.Title_Edit.zIndex = 103;
	*/

	// Triggers a focus event - needed for browsers that can not yet focus on the HTML::INPUT object since it may be visually inactive at this stage (before refresh?)
	// Attention: Doesn't work right in opera
	if (!isOpera) 
		{setTimeout('Boxes.Objects['+BoxID+'].Title_Edit.focus();',1)}
	else
		{Boxes.Objects[BoxID].Title_Edit.focus();}

	//Free up memory
	Tab_Object = null;
	EditWidth = null;
}


function EditBoxName_Commit()
{//Commits box title edit
	var Box_Object = Boxes.Objects[Boxes.EditableBoxID];
	if (Trim(Box_Object.Title_Edit.value).length==0) 
	{//If title is empty - Cancel edit
		EditBoxName_Cancel(1);
		Box_Object = null; //Free up memory
		return(false);
	}

	var NewTitle = Box_Object.Title_Edit.value; //Retrieves the new title
	var OriginalTitle = Box_Object.Title_Label_Main.innerHTML; //Retrieves the original title
	Box_Object.SetTitle("<span class='box_title_disabled'>"+HTML(NewTitle)+"<img src='/images/in_progress.gif' width=7 height=1/></span>"); //Sets the new temporary title with 'in-progress' indicator
	Boxes.Refresh();  //Refresh the tabs after new title was set (temporary until server approves change)

	Box_Object.Handler.ActiveState = false; //Leaves edit mode

	Server_RenameBox(Boxes.EditableBoxID,Escape(NewTitle),OriginalTitle); //Commits new title to server

	//Free up memory
	Box_Object = null;
	NewTitle = null;
	OriginalTitle = null;
};




function EditBoxName_Cancel(CancelEdit)
{//Cancels the box's edit
	
	//Cancels defocus event
	if (Boxes.EditBoxDefocusInt != null) clearTimeout(Boxes.EditBoxDefocusInt);
	Boxes.EditBoxDefocusInt = null;
	
	//Attention!!!: Active editable box could theoretically be from another page (?)
	var Box_Object = Boxes.Objects[Boxes.EditableBoxID]; //Selects editable box object
	
	if (Box_Object)
	{
		if ((!CancelEdit) && (Edit(Box_Object.Title_Label_Main.innerHTML) != Box_Object.Title_Edit.value)) {EditBoxName_Commit()}; //Commin name change if cancel called upon blur (for example) and value of title changed
		
		//Leaves edit state
		Box_Object.Handler.EditState=false;
		Boxes.EditState=false;
		
		//Switches back to Title (disabled Input)

		Box_Object.Title_Label.className = 'box_title_label_container';
//		Box_Object.Title_Label_Main.className = 'box_title_label_enabled box_title_label_main';
//		if (Box_Object.Title_Label_Shadow) {Box_Object.Title_Label_Shadow.className = 'box_title_label_enabled box_title_label_shadow'};

		Box_Object.Title_Edit.className = 'box_title_edit_disabled';
		//Box_Object.Title_Edit.blur();
	}
	Boxes.EditableBoxID = null; //Free up editable tab indicator
	Boxes.Refresh(); //Refresh tabs
	
	Box_Object = null; //Free up memory
}






function EnableBox(BoxID,NewBoxID,NewBoxTitle)
{//Activated disabled (new) box
// BoxID is always zero. This is the BoxID for a new Box (which is the only Box that needs enabling)

//	Boxes.Hide();

	var EnableBox_Object = Boxes.Objects[BoxID]; //Retrieves the box object
	if (!EnableBox_Object)
	{//Error - not a valid BoxID for enabling
		EnableBox_Object = null; //Free up memory
		return false
	};

	EnableBox_Object.id = "box_"+NewBoxID; //Sets the new HTML object ID variable (as received from the server)
	EnableBox_Object.BoxID = NewBoxID; //Sets the BoxID parameter

	if (Boxes.ActiveBoxID == BoxID) {Boxes.ActiveBoxID = NewBoxID}; //In case enabled box was set as the active box, updates the active box with the new ID
		
	//Updates the box's title object and edit object with the new Title (received from the server)
	EnableBox_Object.Title.id = 'box_' + BoxID + '_title';
	EnableBox_Object.SetTitle(NewBoxTitle);

	//Updates the Box object and handler in the associated arrays
	Boxes.Objects[NewBoxID] = EnableBox_Object;
	Boxes.Handlers[NewBoxID] = EnableBox_Object.Handler;
	//Free up the old (Box ID# 0) from the associated array
	Boxes.Objects[BoxID] = null;
	Boxes.Handlers[BoxID] = null;

	//Update the ID in the objects IDs list array
	Boxes.Objects_IDs[Boxes.Objects_IDs.length-1] = NewBoxID; //Attention: Assuming last ID in Objects_IDs is the last Box that is pending creation

	//Sets the tab handler's active state
	EnableBox_Object.Handler.ActiveState=true;

//	Boxes.Show();
	Boxes.Refresh();

	EnableBox_Object = null; //Free up memory
}





function ActivateBox(BoxID)
{//Sets a new tab as active

	Debug("Activate?"+BoxID +"="+ Boxes.ActiveBoxID);
	
	//If second press on the tab, enters editing mode
	if (BoxID == Boxes.ActiveBoxID)
	{
		EditBoxName_Edit(BoxID);
		return false
	};

	//...otherwise

	var ActiveBox_New_Object = Boxes.Objects[BoxID]; //Retrieves the Tab object
	if (!ActiveBox_New_Object)
	{ //Error - not a valid BoxID for activation
		ActiveBox_New_Object = null; //Free up memory
		return false
	};

	//Else...

	//Cancels currect box edit if in such state
	EditBoxName_Cancel();
	
	//Activates Box
	ActiveBox_New_Object.className = "box box_active";
	
	//Disactivates currectly selected box
	//Note: Active box can be from a different page. (?)
	var ActiveBox_Current_Object = Boxes.Objects[Boxes.ActiveBoxID];
	if (ActiveBox_Current_Object) 
	{
		ActiveBox_Current_Object.className = "box";
	};
	
	//Sets selected Box indicator
	Boxes.ActiveBoxID = BoxID;
	
	//Free up memory
	ActiveBox_New_Object = null;
	ActiveBox_Current_Object = null;

}






function CreateBoxHTML(PageID,ContainerID,BoxID,BoxName)
{//Creates new box (HTML::DIV) object

	var NewBox=document.createElement("DIV");
	NewBox.id="box_"+BoxID;
	NewBox.BoxID=BoxID; //Backup copy of the BoxID in the DOM of the box object
	NewBox.ObjectType="Klostu_Box";
	NewBox.PageID=PageID;
	NewBox.ContainerID=ContainerID;
	
	var TMP_Element;
	
	//Set function pointers
	NewBox.SetTitle = Box_SetTitle;

		var NewBox_Table=document.createElement("TABLE");
		NewBox_Table.className = 'box_table';
		
		var NewBox_Table_TopBorderRow 	= NewBox_Table.insertRow(0);
		var NewBox_Table_TitleRow 	= NewBox_Table.insertRow(1);
		var NewBox_Table_ContentRow 	= NewBox_Table.insertRow(2);
		var NewBox_Table_BottomBorderRow= NewBox_Table.insertRow(3);


		var NewBox_Table_BorderTopRight		= NewBox_Table_TopBorderRow.insertCell(0); NewBox_Table_BorderTopRight.className = 'box_border_topright';
		var NewBox_Table_BorderTop		= NewBox_Table_TopBorderRow.insertCell(0); NewBox_Table_BorderTop.className = 'box_border_top';
		var NewBox_Table_BorderTopLeft		= NewBox_Table_TopBorderRow.insertCell(0); NewBox_Table_BorderTopLeft.className = 'box_border_topleft';

		var NewBox_Table_BorderBottomRight	= NewBox_Table_BottomBorderRow.insertCell(0); NewBox_Table_BorderBottomRight.className = 'box_border_bottomright';
		var NewBox_Table_BorderBottom		= NewBox_Table_BottomBorderRow.insertCell(0); NewBox_Table_BorderBottom.className = 'box_border_bottom';
		var NewBox_Table_BorderBottomLeft	= NewBox_Table_BottomBorderRow.insertCell(0); NewBox_Table_BorderBottomLeft.className = 'box_border_bottomleft';

		var NewBox_Table_Title_BorderRight	= NewBox_Table_TitleRow.insertCell(0); NewBox_Table_Title_BorderRight.className = 'box_border_right';
		var NewBox_Table_Title			= NewBox_Table_TitleRow.insertCell(0); NewBox_Table_Title.className = 'box_title';
		var NewBox_Table_Title_BorderLeft	= NewBox_Table_TitleRow.insertCell(0); NewBox_Table_Title_BorderLeft.className = 'box_border_left';

		var NewBox_Table_Content_BorderRight	= NewBox_Table_ContentRow.insertCell(0); NewBox_Table_Content_BorderRight.className = 'box_border_right';
		var NewBox_Table_Content_Cell		= NewBox_Table_ContentRow.insertCell(0); NewBox_Table_Content_Cell.className = 'box_content';
			var NewBox_Table_Content_Table		= document.createElement("TABLE"); NewBox_Table_Content_Table.className = 'box_content_table';
			
			
			
			TempElement	= NewBox_Table_Content_Table.insertRow(0).insertCell(0);
			var NewBox_LoadingProgress = document.createElement("DIV");
			NewBox_LoadingProgress.innerHTML = "<center><img width=20 height=20 src='/images/progress_20x20_w.gif' align='absbottom'/><font color=#c0c0c0><b>Loading content</b></font></center>";
			TempElement.appendChild(NewBox_LoadingProgress);

			var NewBox_Table_Content_Table_Row	= NewBox_Table_Content_Table.insertRow(1);
			var NewBox_Table_Content_Table_Cell	= NewBox_Table_Content_Table_Row.insertCell(0);
			NewBox_Table_Content_Table_Cell.className = "box_content_cell";
			NewBox_Table_Content_Cell.appendChild(NewBox_Table_Content_Table);
		var NewBox_Table_Content_BorderLeft	= NewBox_Table_ContentRow.insertCell(0); NewBox_Table_Content_BorderLeft.className = 'box_border_left';


			var NewBox_Table_Title_Table 		= document.createElement("TABLE"); NewBox_Table_Title_Table.className 	= 'box_table_title';
			var NewBox_Table_Title_Table_Row	= NewBox_Table_Title_Table.insertRow(0);
			
			var NewBox_Table_Title_Table_Cell_Title_Left	= NewBox_Table_Title_Table_Row.insertCell(0); NewBox_Table_Title_Table_Cell_Title_Left.className = 'box_title_cell';
				var NewBox_Title_Left=document.createElement("DIV");
				NewBox_Title_Left.className='box_title_left';
				NewBox_Title_Left.id='box_'+BoxID+'_title_left';
				NewBox_Table_Title_Table_Cell_Title_Left.appendChild(NewBox_Title_Left);

				var NewBox_Table_Title_Table_Cell_Title	= NewBox_Table_Title_Table_Row.insertCell(1); NewBox_Table_Title_Table_Cell_Title.className = 'box_title_cell'; 
				NewBox_Table_Title_Table_Cell_Title.style.width="100%";
			
				var NewBox_Table_Title_Table_Cell_Tools	= NewBox_Table_Title_Table_Row.insertCell(2); NewBox_Table_Title_Table_Cell_Tools.className = 'box_tools_cell';

				var NewBox_Table_Title_Table_Cell_Title_Right	= NewBox_Table_Title_Table_Row.insertCell(3); NewBox_Table_Title_Table_Cell_Title_Right.className = 'box_title_cell';
				
				var NewBox_Title_Right=document.createElement("DIV");
				NewBox_Title_Right.className='box_title_right';
				NewBox_Title_Right.id='box_'+BoxID+'_title_right';
				NewBox_Table_Title_Table_Cell_Title_Right.appendChild(NewBox_Title_Right);

				
				
				var NewBox_Title=document.createElement("DIV");
				NewBox_Title.id='box_'+BoxID+'_title';
				NewBox_Title.className='box_title';
					
					var NewBox_Title_Label=document.createElement("DIV");
					NewBox_Title_Label.className = "box_title_label_container";
					
						var TitlePosCSS_Extra = (isOpera)?"_Opera":"";
						
						TMP_Element = document.createElement("DIV");
						if (isExplorer) {TMP_Element.className = "box_title_label_IEWrapper"};
							var NewBox_Title_Label_Shadow=document.createElement("DIV");
							NewBox_Title_Label_Shadow.className='box_title_label box_title_label_shadow box_title_label_shadow_position'+TitlePosCSS_Extra;
							NewBox_Title_Label_Shadow.innerHTML = BoxName;
							TMP_Element.appendChild(NewBox_Title_Label_Shadow);
						NewBox_Title_Label.appendChild(TMP_Element);
	
						TMP_Element = document.createElement("DIV");
						if (isExplorer) {TMP_Element.className = "box_title_label_IEWrapper"};
							var NewBox_Title_Label_Main=document.createElement("DIV");
							NewBox_Title_Label_Main.className='box_title_label box_title_label_main box_title_label_main_position'+TitlePosCSS_Extra;
							NewBox_Title_Label_Main.innerHTML = BoxName;
							TMP_Element.appendChild(NewBox_Title_Label_Main);
						NewBox_Title_Label.appendChild(TMP_Element);

					NewBox_Title.appendChild(NewBox_Title_Label);
					
					if (Boxes.EditMode)
					{
						var NewBox_Title_edit=document.createElement("INPUT");
						NewBox_Title_edit.maxLength=32;
						NewBox_Title_edit.className='box_title_edit_disabled';
						NewBox_Title_edit.value=Edit(BoxName);
		
						NewBox_Title_edit.ondblclick = function() {if (Boxes.EditBoxDefocusInt != null) {clearTimeout(Boxes.EditBoxDefocusInt);} NewBox_Title_edit.focus()}; //Needed for explorer
						NewBox_Title_edit.onblur = function() {Boxes.EditBoxDefocusInt=setTimeout('EditBoxName_Cancel()',100);}; //Delayed edit-cancel, since explorer blurs upon same object's click
						NewBox_Title_edit.onfocus = function() {if (Boxes.EditBoxDefocusInt != null) {clearTimeout(Boxes.EditBoxDefocusInt);}}; //Cancel delayed edit-cancel
		
						NewBox_Title_edit.onkeydown = function(Event) //Enables Enter/Esc
						{
							if(typeof Event=="undefined")		{Event		= window.event};
							if(typeof Event.which=="undefined")	{Event.which	= Event.keyCode};
							var CancelEdit = (Event.which==27); 
							if ((Event.which==13) || (Event.which==27)) 
								{Boxes.EditBoxDefocusInt=setTimeout('EditBoxName_Cancel('+CancelEdit+')',100)}
						};
						NewBox_Title.appendChild(NewBox_Title_edit);
					}
					
				NewBox_Table_Title_Table_Cell_Title.appendChild(NewBox_Title);
	
				if (Boxes.EditMode)
				{
					var NewBox_Table_Tools_Table=document.createElement("TABLE");
					NewBox_Table_Tools_Table.className = 'box_tools';
					var NewBox_Table_Tools_Row = NewBox_Table_Tools_Table.insertRow(0); NewBox_Table_Tools_Row.className = 'box_tools_row';
					var NewBox_Table_Tools_EditCell = NewBox_Table_Tools_Row.insertCell(0); NewBox_Table_Tools_EditCell.className = "box_tools_cell";
					var NewBox_Table_Tools_CloseCell = NewBox_Table_Tools_Row.insertCell(1); NewBox_Table_Tools_CloseCell.className = "box_tools_cell";
		
						var NewBox_Title_controls_Edit=document.createElement("DIV");
						NewBox_Title_controls_Edit.className='box_controls box_controls_edit';
						NewBox_Title_controls_Edit.innerHTML = "<img align=absbottom class='box_controls_edit' src='/images/boxes/box_tool_edit.gif' height=14px; width=14px; onmousedown='CancelBubble(event); EditBox(this.parentNode.BoxReference.BoxID); return(false);'/>";
						NewBox_Title_controls_Edit.BoxReference = NewBox;
						NewBox_Table_Tools_EditCell.appendChild(NewBox_Title_controls_Edit);
	
						var NewBox_Title_controls_Close=document.createElement("DIV");
						NewBox_Title_controls_Close.className='box_controls box_controls_close';
						NewBox_Title_controls_Close.innerHTML = "<img align=absbottom class='box_controls_close' src='/images/boxes/box_tool_delete.gif' height=14px; width=14px; onmousedown='CancelBubble(event); DeleteBox(this.parentNode.BoxReference.BoxID); return(false);'/>";
						NewBox_Title_controls_Close.BoxReference = NewBox;
						NewBox_Table_Tools_CloseCell.appendChild(NewBox_Title_controls_Close);

					NewBox_Table_Title_Table_Cell_Tools.appendChild(NewBox_Table_Tools_Table);
				}
			
			NewBox_Table_Title.appendChild(NewBox_Table_Title_Table);
				
		NewBox.appendChild(NewBox_Table);



	//Set Tab Objects' additional properties
	NewBox.Title = NewBox_Title; //NewBox_Title (HTML::DIV) object reference
	NewBox.Title_Label = NewBox_Title_Label; //NewBox_Title_label_Main (HTML::DIV) object reference
	NewBox.Title_Label_Main = NewBox_Title_Label_Main; //NewBox_Title_Label_Main (HTML::DIV) object reference
	NewBox.Title_Label_Shadow = NewBox_Title_Label_Shadow; //NewBox_Title_Label_Shadow (HTML::DIV) object reference
	NewBox.Title_Edit = NewBox_Title_edit; //NewBox_Title_edit (HTML::INPUT) object reference
	NewBox.Content = NewBox_Table_Content_Table_Cell; //NewBox_Table_Content (HTML::TD) object reference
	NewBox.LoadingProgress = NewBox_LoadingProgress; //NewBox_Table_Content (HTML::TD) object reference		

	NewBox.Controls_Close = NewBox_Title_controls_Close; //NewBox_Title_controls_Close (HTML::DIV) object reference
	NewBox.Controls_Edit = NewBox_Title_controls_Edit; //NewBox_Title_controls_Edit (HTML::DIV) object reference
	

	if (Boxes.EditMode)
	{
		NewBox.Title.style.cursor="pointer"; //Sets basic CSS properties
		NewBox.className=(BoxID<-1)?"box_terminator":"box"; //Sets the classname of the box to either "box_terminator" or "box"(or anchor) according to TabID (ID# < -1 : Terminator)
	}
	else
	{
		NewBox.className=(BoxID<-1)?"box_terminator":"box box_active"; //Sets the classname of the box to either "box_terminator" or "box box_active" - In View mode, all Boxes are active
	}

	//Free up memory
	NewBox_Table=document.createElement("TABLE");
	NewBox_LoadingProgress				= null;
	NewBox_Table_TopBorderRow 			= null;
	NewBox_Table_TitleRow 				= null;
	NewBox_Table_ContentRow 			= null;
	NewBox_Table_BottomBorderRow			= null;
	NewBox_Table_BorderTopLeft			= null;
	NewBox_Table_BorderTop				= null;
	NewBox_Table_BorderTopRight			= null;
	NewBox_Table_BorderBottomLeft			= null;
	NewBox_Table_BorderBottom			= null;
	NewBox_Table_BorderBottomRight			= null;
	NewBox_Table_Title_BorderLeft			= null;
	NewBox_Table_Title				= null;
	NewBox_Table_Title_BorderRight			= null;
	NewBox_Table_Content_BorderLeft			= null;
	NewBox_Table_Content				= null;
	NewBox_Table_Content_Cell			= null;
	NewBox_Table_Content_Table			= null;
	NewBox_Table_Content_Table_Row			= null;
	NewBox_Table_Content_Table_Cell			= null;
	NewBox_Table_Content_BorderRight		= null;
	NewBox_Table_Title_Table 			= null;
	NewBox_Table_Title_Table_Row			= null;
	NewBox_Table_Title_Table_Cell_Title		= null;
	NewBox_Table_Title_Table_Cell_Title_Left	= null;
	NewBox_Table_Title_Table_Cell_Title_Right	= null;
	NewBox_Table_Title_Table_Cell_Tools		= null;

	NewBox_Title					= null;
	NewBox_Title_Label				= null;
	NewBox_Title_Label_Main				= null;
	NewBox_Title_Label_Shadow			= null;
	NewBox_Title_edit				= null;
	CancelEdit					= null;
	NewBox_Table_Tools_Table			= null;
	NewBox_Table_Tools_Row				= null;
	NewBox_Table_Tools_CloseCell			= null;
	NewBox_Table_Tools_EditCell			= null;
	NewBox_Title_controls_Edit			= null;
	NewBox_Title_controls_Close			= null;
		
	return(NewBox);
}









function AppendBox(PageID,ContainerID,BoxID,BoxName,BoxContent_HTMLOverride,BoxType_NewBox)
{//Appends a new tab
 // (?) BoxHTML?

 //	BoxID= 0 : New Box;
 //	BoxID< -1 : Terminator Box;
 //	TabID= -1 : Anchor Box;

	//Checks if this Box ID exists already
	if (Element_ByID("box_"+BoxID)) 
	{//Box with this ID already exists. Abort AppendBox.
		if (BoxID == 0)
			{window.alert("Please wait till the creation of the first box is completed, before trying to create another Box.");}
		else
			{window.alert("Unexpected error: box by this ID already exists");}
		return (false);
	}
	else
	{//Purges existing box object if still exists for some reason
		Boxes.Objects[BoxID]==null;
	};


	var NewBox=CreateBoxHTML(PageID,ContainerID,BoxID,BoxName);

	if (Boxes.EditMode)
	{
		var NewHandler = new BoxHandler(NewBox); //Creates a new Handler for the new Box
		NewBox.Handler = NewHandler; //Sets Box Objects' Handler property
		Boxes.Handlers[BoxID] = NewHandler; //Adds Box Handler to Boxes.Handlers associated array
	}
	
	////Adds box to document and array
	if (Pages.Objects[PageID].Containers[ContainerID].TerminatorBox) 
		{Pages.Objects[PageID].Containers[ContainerID].Container.insertBefore(NewBox,Pages.Objects[PageID].Containers[ContainerID].TerminatorBox)} 
	else 
		{Pages.Objects[PageID].Containers[ContainerID].Container.appendChild(NewBox)};
	
	Boxes.Objects[BoxID] = NewBox; //Adds Box (HTML::DIV) Object to Boxes.Objects associated array
	Boxes.Objects_IDs[Boxes.Objects_IDs.length] = BoxID; //Adds Box ID# (numeric) to Boxes.Objects_IDs ordered list array
	


	
	if (BoxID>0) 
	{//If box is an existing tab (ID# > 0), creates the tab as Active already
		if (Boxes.EditMode)
		{
			NewBox.Handler.ActiveState = true;
			if (Boxes.ActiveBoxID == null) {ActivateBox(BoxID)}; //Activates Box if no box is active
			Server_LoadBoxContent(BoxID); //Loading box content from server
		}
		else
		{
			if (BoxContent_HTMLOverride) 
			{
				Box_UpdateLoadStatus(NewBox,"");
				NewBox.Content.innerHTML = UnXML(BoxContent_HTMLOverride); 
			};
		}
	}
	else if (BoxID==0) 
	{//If the box is a new box (ID# = 0) - Calling server with Append command. Sets box state as inactive (until server approves addition)
		if (Boxes.EditMode)
		{
			NewBox.Handler.ActiveState = false;
			Server_AppendBox(BoxType_NewBox,PageID,ContainerID);
		}
	}


	
	//Free up memory
	NewHandler=null;

	return (NewBox);
}






function NewBox_OpenTool()
{//Shows the new box tool
	Boxes.BoxTool.cfg.queueProperty("fixedcenter",true);
	Boxes.BoxTool.render();
	Boxes.BoxTool.cfg.queueProperty("fixedcenter",false);
	Boxes.BoxTool.render();
	
	Boxes.BoxTool.show();
}



function NewBox(TypeID)
{//Calls Append box - Adds box in the main container - Attention!!!: Change since container may be hidden (?)
	AppendBox(Pages.ActivePageID,2,0,"<span class='box_title_disabled'>New Box<img src='/images/in_progress.gif' width=7 height=1/></span>","",TypeID);
}






Box_SetTitle = function (NewTitleHTML)
{
	//Debug("Setting title: "+NewTitleHTML + " ("+typeof NewTitleHTML+")");
	this.Title_Label_Main.innerHTML = NewTitleHTML;
	this.Title_Edit.value = Edit(NewTitleHTML);
	if (this.Title_Label_Shadow) {this.Title_Label_Shadow.innerHTML = NewTitleHTML};
}




function DeleteBox(BoxID,ForceDelete,SkipServer)
{//Deletes a box

	if (Boxes.EditState) {EditBoxName_Cancel(1); return(false)} //Can not delete a box it Edit title mode. Disable edit first

	Boxes.CommandExecState = true; //Sets command execution mode (To avoid drag?)

	var DeleteIndex;
	var IndexRun;
	var OriginalTitle;
	
	var DeleteBox_Object = Boxes.Objects[BoxID]; //Retreive the deleted box object

	// First time delete call requires verification (window message)
	if (ForceDelete)
	{//Force delete - execute to server
		if (SkipServer)
		{//Delete without notfying server - Used for deletion during revert on add new box or when server gives an ok on delete
			DeleteBox_Object.parentNode.removeChild(DeleteBox_Object); //Removes the Box object from the HTML document
			Boxes.Objects[BoxID] = null; //Free up object in associated array
			Boxes.Handlers[BoxID] = null; //Free up handler in associated array
			
			//Locates the objectID location to delete in the List array
			DeleteIndex=-1;
			for (IndexRun=0;IndexRun<Boxes.Objects_IDs.length;IndexRun++) {if (Boxes.Objects_IDs[IndexRun]==BoxID) {DeleteIndex=IndexRun}};
			if (DeleteIndex != -1) {Boxes.Objects_IDs.splice(DeleteIndex,1)}; //Removes cell from array
	
			Boxes.Refresh(); //Refresh boxes
			
			//if ((Boxes.ActiveBoxID == BoxID) && (Boxes.Objects_IDs.length>0)) {ActivateBox(Boxes.Objects[Boxes.Objects_IDs[0]].BoxID);}

			Boxes.CommandExecState = false; //Leaves command state (allow drag?)			
		}
		else
		{//Execute delete on server
			//Calls server box deletion
			DeleteBox_Object.Handler.ActiveState = false; //Disables the tab's active state (allow drag?)
			//Updates the title to indecate a deletion process is running
			OriginalTitle = DeleteBox_Object.Title_Label_Main.innerHTML; //Backing up title
			DeleteBox_Object.SetTitle("<span class='box_title_disabled'>"+OriginalTitle+"<img src='/images/in_progress.gif' width=7 height=1/></span>");
			Server_DeleteBox(BoxID,OriginalTitle); //Calls server side delete
		}
	}
	else
	{//Prompting user for deletion verification
		if (confirm("Are you sure you want to delete the box - "+Edit(DeleteBox_Object.Title_Label_Main.innerHTML))) //Asks for deletion confirmation
		{ 
			DeleteBox(BoxID,1); //Delete the box
			Boxes.CommandExecState = false; //Leaves command state if was active (allow drag?)
		}
		else
		{
			EditBoxName_Cancel(1); //Cancels box deletion
			Boxes.CommandExecState = false; //Leaves command state if was active (allow drag?)
		}
	}

	//Free up memory
	DeleteBox_Object = null; 
	DeleteIndex = null;
	IndexRun = null;
	OriginalTitle = null;
}




function RenameBox(BoxID,NewBoxTitle)
{//Renames a box (visually)

//	Boxes.Hide();
	var RenamedBox_Object = Boxes.Objects[BoxID]; //Retrieves Tab onject
	RenamedBox_Object.SetTitle(NewBoxTitle); //Set new tab Title
	RenamedBox_Object.Handler.ActiveState = true; //Makes sure the tab is active

//	Boxes.Show();
//	Boxes.Refresh();

	RenamedBox_Object = null; //Free up memory
}




function MoveBox(BoxID, NewPageID, NewContainerID, BeforeBoxID)
{//Mores a box to a new location (page/container/box-position)

	//Finds the box to add new moved before
	var BeforeBox = Boxes.Objects[BeforeBoxID];
	if (!BeforeBox) {BeforeBox = Pages.Objects[NewPageID].Containers[NewContainerID].TerminatorBox;};
	
	var BoxObject = Boxes.Objects[BoxID]; //Retrieves the Box Object
	if ((BoxObject.PageID == NewPageID) && (BoxObject.ContainerID==NewContainerID) && (BoxObject.Handler.NextBox_Original==BeforeBox)) {return false}; //No need to move. Already in place
	
	//Otherwise...
	
	if (BoxObject.PageID == Pages.ActivePageID)
	{//Box is on currently active page - removing
		RemoveBox_Document(BoxObject);
	};
	
	//if (NewPageID == Pages.ActivePageID)
	{//Moving box to currently active container
		AddBoxBeforeObject_Document(BoxObject,BeforeBox)
	};
	
	BoxObject.PageID=NewPageID;
	BoxObject.ContainerID=NewContainerID;
	
	//Free up memory
	BoxObject = null;
	BeforeBox = null;
	
	return true;
}


function RemoveBox_Document(BoxObject)
{
	BoxObject.parentNode.removeChild(BoxObject);
}


function AddBoxBeforeObject_Document(BoxObject,BeforeBox)
{
	BeforeBox.parentNode.insertBefore(BoxObject,BeforeBox);
}































/////////////////////
// AJAX OPERATIONS //
/////////////////////


//////// BOXES REORDER /////////

var BoxesReorder_Handler = new XMLHTTPEngine("BoxesReorder",""); //Creates BoxesReorder Ajax Handler


BoxesReorder_Handler.onLoad = function(Handler) 
{//Function executed upon response from server
	
	function BoxesReorder_Revert(Reason)
	{//In case of failure to reorder box - Revert/Alert about box reorder failure
		window.alert(Reason); //Alerting the failure reason
		//Attention: Revert boxes order? - or notify to reload Box
		Boxes.Comm.Statuses['BoxesReorder']=0; //Free up TabsReorder communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
	}
	

	var Response = Handler.getXML();
	if (!Response) 
	{//Invalid result retuned
		BoxesReorder_Revert("No server response");
		Response = null; //Free up memory
		return(false);
	} 
	
	var XMLroot = Response.getElementsByTagName('root').item(0);
	if (!XMLroot)
	{//Invalid result retuned
		BoxesReorder_Revert("Invalid server XML response");
		XMLroot = null; //Free up memory		
		return(false);
	} 
	
	var Status = XMLroot.getElementsByTagName('status').item(0);
	if (!Status)
	{//Invalid result retuned
		BoxesReorder_Revert("No status reported");
		Status = null; XMLroot = null; //Free up memory		
		return(false);
	} 

	var StatusID = Status.getElementsByTagName('status_id').item(0); 
	StatusID = StatusID?StatusID.childNodes.item(0).data:0;
	
	var StatusMessage = Status.getElementsByTagName('status_message').item(0); 
	StatusMessage = StatusMessage?StatusMessage.childNodes.item(0).data:'Unknown';

	if (StatusID != 1)
	{//Returrned Status indicated Box reorder failure - Reverting reorder
		BoxesReorder_Revert(StatusMessage);
		StatusID = null; StatusMessage = null; Status = null; XMLroot = null; //Free up memory
		return(false);
	}
	
	//Free up memory
	StatusMessage = null;
	StatusID = null;
	Status = null;
	XMLroot = null;

	//Else - All done

	Boxes.Comm.Statuses['BoxesReorder']=0; //Free up BoxesReorder communication channel
	Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
};


function Server_SaveBoxesOrder(PageID,ContainerID)
{//Call server to with Box Order command via Ajax
	if (Boxes.Comm.Statuses['BoxesReorder']) {window.alert('Error - only one box positioning should run at a given time. Aborting box positioning call.')};

	//Otherwise...
	
	var BoxesOrderStr=Boxes.GetBoxesOrder_Str(PageID,ContainerID); //Fetches the tags order string
	
	try 
	{
		Boxes.Comm.Statuses['BoxesReorder']=1; //Flags TabsReorder communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator

		BoxesReorder_Handler.URL='/cgi-bin/profile/boxes.pl?usk='+USK+'&act=ord&pid='+PageID+'&cid='+ContainerID+'&order='+BoxesOrderStr;
		//Debug("Calling reorder boxes @ "+BoxesReorder_Handler.URL);
		BoxesReorder_Handler.Execute(); //Execute server call
	}
	catch (e)
	{//Error - Could not call server
		Boxes.Comm.Statuses['BoxesReorder']=0; //Free up TabsReorder communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
	};
	
	BoxesOrderStr = null; //Free up memory
};

















//////// APPEND BOX /////////

var AppendBox_Handler = new XMLHTTPEngine("AppendBox","");
AppendBox_Handler.onLoad = function(Handler) 
{
	function AppendBox_Revert(Reason)
	{
		window.alert(Reason);
		DeleteBox(0,true,true);
		Boxes.Comm.Statuses['AppendBox']=0;
		Boxes.Comm.UpdateCommIndicator();
	}
	
	Debug ("[AppendBox] Message received from server");
	var Response = Handler.getXML();
	if (!Response) {AppendBox_Revert("No server response"); return(false);} //Invalid result retuned 
	
	var XMLroot = Response.getElementsByTagName('root').item(0);
	if (!XMLroot) {AppendBox_Revert("Invalid server XML response"); return(false);} //Invalid result retuned 
	
	var Status = XMLroot.getElementsByTagName('status').item(0);
	if (!Status) {AppendBox_Revert("No status reported"); return(false);} //Invalid result retuned 

	var StatusID = Status.getElementsByTagName('status_id').item(0); 
	StatusID = StatusID?StatusID.childNodes.item(0).data:0;
	
	var StatusMessage = Status.getElementsByTagName('status_message').item(0); 
	StatusMessage = StatusMessage?StatusMessage.childNodes.item(0).data:'Unknown';

	Debug ("[AppendBox] Status: "+StatusID+" :"+StatusMessage);
	
	if (StatusID != 1) {AppendBox_Revert(StatusMessage); return(false);}
	
	//Else
	var DataSet = XMLroot.getElementsByTagName('data').item(0);
	if (!DataSet) {AppendBox_Revert("No data reported"); return(false);}
	
	var NewBoxID = DataSet.getElementsByTagName('box_id').item(0);
	NewBoxID = (NewBoxID.childNodes)?parseInt(NewBoxID.childNodes.item(0).data):false;

	var NewBoxTitle = DataSet.getElementsByTagName('box_title').item(0);
	NewBoxTitle = (NewBoxTitle.childNodes)?NewBoxTitle.childNodes.item(0).data:false;

	var BoxContent = DataSet.getElementsByTagName('box_content').item(0);
	BoxContent = MergeChildrenItems(BoxContent.childNodes);

	var BoxScript = DataSet.getElementsByTagName('box_script').item(0);
	BoxScript = MergeChildrenItems(BoxScript.childNodes);

	var BoxPrerequisiteScripts = DataSet.getElementsByTagName('box_prerequisitescripts').item(0);
	BoxPrerequisiteScripts = (BoxPrerequisiteScripts.childNodes.item(0))?BoxPrerequisiteScripts.childNodes.item(0).data:"";

	var BoxScriptCode = DataSet.getElementsByTagName('box_scriptcode').item(0);
	BoxScriptCode = MergeChildrenItems(BoxScriptCode.childNodes);

	Debug ("[AppendBox] BoxID: "+NewBoxID+" :"+NewBoxTitle);

	if (!NewBoxTitle || !NewBoxID)
	{AppendBox_Revert("Missing new Box details"); return(false);}
	else
	{
		//?? both enable and append?
		EnableBox(0,NewBoxID,Unescape(NewBoxTitle));
		ActivateBox(NewBoxID);

		Handler.BoxObject = Boxes.Objects[NewBoxID]; //Assigning BoxObject to Handler based on the new BoxID

		if (BoxContent)
		{
			Box_UpdateLoadStatus(Handler.BoxObject,"");
			Handler.BoxObject.Content.innerHTML=UnXML();
		}

		
		var BoxScriptsArray = new Array;
		if (BoxPrerequisiteScripts.length > 0) {BoxScriptsArray = BoxPrerequisiteScripts.split(";")};
		BoxScriptsArray[BoxScriptsArray.length] = BoxScript; //Adding BoxScript as last script to be loaded
		var RunIndex;
		var NewScript;
		
		for (RunIndex=0; RunIndex<BoxScriptsArray.length; RunIndex++)
		{
			BoxScript = BoxScriptsArray[RunIndex];
			if ((BoxScript) && (!Boxes.LoadedScripts[BoxScript]))
			{
				Debug("Dynamically loading ["+BoxScript+"]");
				Boxes.LoadedScripts[BoxScript] = new Object;
				Boxes.LoadedScripts[BoxScript].StatusID=2; //Marking script as load-pendin
				Boxes.LoadedScripts[BoxScript].DelayedCommands = "";
	
				NewScript=document.createElement("script");
				NewScript.language="javascript";
				NewScript.src="/boxes/"+BoxScript+".js";
				document.body.appendChild(NewScript);
				//Debug("Added script - " + NewScript.src);
			}
		}
		
		if (Boxes.LoadedScripts[BoxScript].StatusID==1)
		{//Can execute code
			//Debug("Loading in - ready mode");
			Box_UpdateLoadStatus(Handler.BoxObject,"");
			eval(BoxScriptCode);
		}
		else
		{//In pending mode - Add to delayed queue
			//Debug("Loading in - delayed mode");
			//Debug(BoxScript+":"+BoxScriptCode);
			Boxes.LoadedScripts[BoxScript].DelayedCommands += BoxScriptCode+"\n";
		};


		Boxes.BoxTool.cancel() //No need for the New BoxTool
		EditBoxName_Edit(NewBoxID);
	};
	
	Boxes.Comm.Statuses['AppendBox']=0;
	Boxes.Comm.UpdateCommIndicator();
		
	
};
function Server_AppendBox(BoxType,PageID,ContainerID)
{
	if (Boxes.Comm.Statuses['AppendBox']) {window.alert('Error - only one box creation should run at a given time. Aborting box creation call.')};
	
	try 
	{
		Boxes.Comm.Statuses['AppendBox']=1;
		Boxes.Comm.UpdateCommIndicator();

		AppendBox_Handler.URL='/cgi-bin/profile/boxes.pl?usk='+USK+'&act=new&type='+BoxType+"&pid="+PageID+"&cid="+ContainerID;
		Debug("Calling append box @ "+AppendBox_Handler.URL);
		AppendBox_Handler.Execute();
	}
	catch (e)
	{
		Boxes.Comm.Statuses['AppendBox']=0;
		Boxes.Comm.UpdateCommIndicator();
	};
};






















//////// DELETE BOX /////////


var DeleteBox_Handler = new XMLHTTPEngine("DeleteBox",""); //Creates DeleteBox Ajax handler


DeleteBox_Handler.onLoad = function(Handler) 
{//Function executed upon response from server
	
	function DeleteBox_Revert(Reason)
	{//In case of failure to delete box - Revert box deletion
		window.alert(Reason);
		DeleteBox_Handler.CurrectBoxObject.SetTitle(DeleteBox_Handler.BoxTitle_Original); //Sets back box title
		DeleteBox_Handler.CurrectBoxHandler.ActiveState = true; //Reactivating box
		Boxes.Comm.Statuses['DeleteBox']=0; //Free up DeleteBox communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
		Boxes.Refresh(); //Refresh Boxes
	}


	var Response = Handler.getXML();
	if (!Response) 
	{//Invalid result retuned
		DeleteBox_Revert("No server response");
		Response = null; //Free up memory
		return(false);
	} 
	
	var XMLroot = Response.getElementsByTagName('root').item(0);
	if (!XMLroot)
	{//Invalid result retuned
		DeleteBox_Revert("Invalid server XML response");
		XMLroot = null; //Free up memory		
		return(false);
	} 
	
	var Status = XMLroot.getElementsByTagName('status').item(0);
	if (!Status)
	{//Invalid result retuned
		DeleteBox_Revert("No status reported");
		Status = null; XMLroot = null; //Free up memory		
		return(false);
	} 

	var StatusID = Status.getElementsByTagName('status_id').item(0); 
	StatusID = StatusID?StatusID.childNodes.item(0).data:0;
	
	var StatusMessage = Status.getElementsByTagName('status_message').item(0); 
	StatusMessage = StatusMessage?StatusMessage.childNodes.item(0).data:'Unknown';

	if (StatusID != 1)
	{//Returrned Status indicated Box addition failure - Reverting addition
		DeleteBox_Revert(StatusMessage);
		StatusID = null; StatusMessage = null; Status = null; XMLroot = null; //Free up memory
		return(false);
	}
	
	//Free up memory
	StatusMessage = null;
	StatusID = null;
	Status = null;

	//Else	

	var DataSet = XMLroot.getElementsByTagName('data').item(0);
	if (!DataSet)
	{//Failed to receive data from server regarding the deletion box - Unexpected error - Reverting deletion
		DeleteBox_Revert("No data reported");
		DataSet = null; XMLroot = null; //Free up memory
		return(false);
	}
	
	var BoxID = DataSet.getElementsByTagName('box_id').item(0);
	BoxID = (BoxID.childNodes)?parseInt(BoxID.childNodes.item(0).data):false;

	if (!BoxID) 
	{//Bad BoxID - Unexpected error - reverts deletion
		DeleteBox_Revert("Missing Box details in response"); 
		BoxID = null; DataSet = null; XMLroot = null; //Free up memory
		return(false);
	}
	else
		{DeleteBox(BoxID,1,1)}; //Finalizes Tab deletion
		
	Boxes.Comm.Statuses['DeleteBox']=0; //Free up DeleteTab communication channel
	Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator

	//Free up memory
	BoxID = null;
	DataSet = null;
	XMLroot = null;
};


function Server_DeleteBox(BoxID,OriginalBoxTitle)
{//Calling server with DeleteTab command via Ajax
	if (Boxes.Comm.Statuses['DeleteBox']) {window.alert('Error - Please delete one box at a time. Aborting..')}; //Can not execute multiple deletes simultaniously
	
	try 
	{
		Boxes.Comm.Statuses['DeleteBox']=1; //Flags DeleteTab communication channel as busy
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator

		DeleteBox_Handler.URL='/cgi-bin/profile/boxes.pl?usk='+USK+'&act=del&id='+BoxID;
		//Debug("Calling delete tag @ "+DeleteBox_Handler.URL);
		//Storing delete info backup
		DeleteBox_Handler.CurrectBoxHandler = Boxes.Handlers[BoxID];
		DeleteBox_Handler.CurrectBoxObject = Boxes.Objects[BoxID];
		DeleteBox_Handler.BoxTitle_Original = OriginalBoxTitle;
		DeleteBox_Handler.Execute(); //Executing server call
	}
	catch (e)
	{//Failed to call server
		Boxes.Comm.Statuses['DeleteBox']=0; //Free up DeleteTab communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
	};
};











//////// RENAME BOX /////////

var RenameBox_Handler = new XMLHTTPEngine("RenameBox",""); //Creates RenameTab Ajax Handler

RenameBox_Handler.onLoad = function(Handler)
{//Function executed upon response from server
	function RenameBox_Revert(Reason)
	{//In case of failure to rename box - Revert box rename
		window.alert(Reason); //Alerting the failure reason
		RenameBox_Handler.CurrectBoxObject.SetTitle(RenameBox_Handler.BoxTitle_Original); //Sets back tab title
		RenameBox_Handler.CurrectBoxHandler.ActiveState = true; //Reactivating Box
		Boxes.Comm.Statuses['RenameBox']=0; //Free up RebnameBox communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
		//Boxes.Refresh();
	}
	
	var Response = Handler.getXML();
	if (!Response)
	{//Invalid result retuned
		RenameBox_Revert("No server response");
		Response = null; //Free up memory
		return(false);
	}
	
	var XMLroot = Response.getElementsByTagName('root').item(0);
	Response = null; //Free up memory

	if (!XMLroot)
	{//Invalid result retuned
		RenameBox_Revert("Invalid server XML response");
		XMLroot = null; //Free up memory
		return(false);
	} 
	
	var Status = XMLroot.getElementsByTagName('status').item(0);
	if (!Status)
	{//Invalid result retuned
		RenameBox_Revert("No status reported");
		Status = null; XMLroot = null; //Free up memory
		return(false);
	} 

	var StatusID = Status.getElementsByTagName('status_id').item(0); 
	StatusID = StatusID?StatusID.childNodes.item(0).data:0;
	
	var StatusMessage = Status.getElementsByTagName('status_message').item(0); 
	StatusMessage = StatusMessage?StatusMessage.childNodes.item(0).data:'Unknown';
	
	if (StatusID != 1)
	{
		RenameBox_Revert(StatusMessage);
		StatusID = null; StatusMessage = null; Status = null; XMLroot = null; //Free up memory
		return(false);
	}
	
	//Free up memory
	StatusID = null;
	StatusMessage = null;
	Status = null;

	//Else

	var DataSet = XMLroot.getElementsByTagName('data').item(0);
	if (!DataSet)
	{//Failed to receive data from server regarding the renaming box - Unexpected error - Reverting rename
		RenameBox_Revert("No data reported");
		DataSet = null; Response = null; //Free up memory
		return(false);
	}
	
	var BoxID = DataSet.getElementsByTagName('box_id').item(0);
	BoxID = (BoxID.childNodes)?parseInt(BoxID.childNodes.item(0).data):false;

	var BoxTitle = DataSet.getElementsByTagName('box_title').item(0);
	BoxTitle = (BoxTitle.childNodes)?BoxTitle.childNodes.item(0).data:false;

	if (!BoxTitle || !BoxID)
	{//Bad/missing BoxID or title - Unexpected error - reverts rename
		RenameBox_Revert("Missing Box details in response");
		BoxID = null; BoxTitle = null; DataSet = null; XMLroot = null; //Free up memory
		return(false);
	}
	else
		{RenameBox(BoxID,BoxTitle);};
		
	Boxes.Comm.Statuses['RenameBox']=0;
	Boxes.Comm.UpdateCommIndicator();
	
	//Free up memory
	BoxID = null;
	BoxTitle = null;
	DataSet = null;
	XMLroot = null;
};


function Server_RenameBox(BoxID,BoxTitle,OriginalBoxTitle)
{
	if (Boxes.Comm.Statuses['RenameBox']) {window.alert('Error - only one box rename should run at a given time. Aborting box rename call.')};
	
	try 
	{
		Boxes.Comm.Statuses['RenameBox']=1;
		Boxes.Comm.UpdateCommIndicator();

		RenameBox_Handler.URL='/cgi-bin/profile/boxes.pl?usk='+USK+'&act=ren&id='+BoxID+'&title='+BoxTitle;
		//Debug("Calling rename box @ "+RenameBox_Handler.URL);
		RenameBox_Handler.CurrectBoxHandler = Boxes.Handlers[BoxID];
		RenameBox_Handler.CurrectBoxObject = Boxes.Objects[BoxID];
		RenameBox_Handler.BoxTitle_Original = OriginalBoxTitle;
		RenameBox_Handler.Execute();
	}
	catch (e)
	{
		Boxes.Comm.Statuses['RenameBox']=0;
		Boxes.Comm.UpdateCommIndicator();
	};
};















//////// LOAD BOX CONTENT /////////



LoadBoxContent_onLoad = function(Handler)
{//Function executed upon response from server
	function LoadBoxContent_Revert(Reason)
	{//In case of failure to rename box - Revert box rename
		window.alert(Reason); //Alerting the failure reason
		Box_UpdateLoadStatus(Handler.BoxObject,"");
		Handler.BoxObject.Content.innerHTML=Handler.Content_Original; //Sets back tab title
		Boxes.Comm.Statuses['LoadBoxContent']-=1; //Free up RebnameBox communication channel
		Boxes.Comm.UpdateCommIndicator(); //Updates communication indicator
		//Boxes.Refresh();
	}
	
	var Response = Handler.getXML();
	if (!Response)
	{//Invalid result retuned
		LoadBoxContent_Revert("No server response");
		Response = null; //Free up memory
		return(false);
	}
	
	var XMLroot = Response.getElementsByTagName('root').item(0);
	Response = null; //Free up memory

	if (!XMLroot)
	{//Invalid result retuned
		LoadBoxContent_Revert("Invalid server XML response");
		XMLroot = null; //Free up memory
		return(false);
	} 
	
	var Status = XMLroot.getElementsByTagName('status').item(0);
	if (!Status)
	{//Invalid result retuned
		LoadBoxContent_Revert("No status reported");
		Status = null; XMLroot = null; //Free up memory
		return(false);
	} 

	var StatusID = Status.getElementsByTagName('status_id').item(0); 
	StatusID = StatusID?StatusID.childNodes.item(0).data:0;
	
	var StatusMessage = Status.getElementsByTagName('status_message').item(0); 
	StatusMessage = StatusMessage?StatusMessage.childNodes.item(0).data:'Unknown';
	
	if (StatusID != 1)
	{
		LoadBoxContent_Revert(StatusMessage);
		StatusID = null; StatusMessage = null; Status = null; XMLroot = null; //Free up memory
		return(false);
	}
	
	//Free up memory
	StatusID = null;
	StatusMessage = null;
	Status = null;

	//Else

	var DataSet = XMLroot.getElementsByTagName('data').item(0);
	if (!DataSet)
	{//Failed to receive data from server regarding the renaming box - Unexpected error - Reverting rename
		LoadBoxContent_Revert("No data reported");
		DataSet = null; Response = null; //Free up memory
		return(false);
	}
	
	var BoxID = DataSet.getElementsByTagName('box_id').item(0);
	BoxID = (BoxID.childNodes.item(0))?parseInt(BoxID.childNodes.item(0).data):false;

	var BoxContent = DataSet.getElementsByTagName('box_content').item(0);
	BoxContent = MergeChildrenItems(BoxContent.childNodes);

	var BoxScript = DataSet.getElementsByTagName('box_script').item(0);
	BoxScript = MergeChildrenItems(BoxScript.childNodes);

	var BoxPrerequisiteScripts = DataSet.getElementsByTagName('box_prerequisitescripts').item(0);
	BoxPrerequisiteScripts = (BoxPrerequisiteScripts.childNodes.item(0))?BoxPrerequisiteScripts.childNodes.item(0).data:"";

	var BoxScriptCode = DataSet.getElementsByTagName('box_scriptcode').item(0);
	BoxScriptCode = MergeChildrenItems(BoxScriptCode.childNodes);

	if (!BoxID)
	{//Bad/missing BoxID or title - Unexpected error - reverts rename
		LoadBoxContent_Revert("Missing Box details in response");
		BoxID = null; NewBoxTitle = null; DataSet = null; XMLroot = null; //Free up memory
		return(false);
	}
	else
	{
		if (BoxContent)
		{
			Box_UpdateLoadStatus(Handler.BoxObject,"");
			Handler.BoxObject.Content.innerHTML=UnXML(BoxContent); 
		};
		
		var BoxScriptsArray = new Array;
		if (BoxPrerequisiteScripts.length > 0) {BoxScriptsArray = BoxPrerequisiteScripts.split(";")};
		BoxScriptsArray[BoxScriptsArray.length] = BoxScript; //Adding BoxScript as last script to be loaded
		var RunIndex;
		var NewScript;
		
		for (RunIndex=0; RunIndex<BoxScriptsArray.length; RunIndex++)
		{
			BoxScript = BoxScriptsArray[RunIndex];
			
			if ((BoxScript) && (!Boxes.LoadedScripts[BoxScript]))
			{
				Debug("Dynamically loading ["+BoxScript+"]");
				Boxes.LoadedScripts[BoxScript] = new Object;
				Boxes.LoadedScripts[BoxScript].StatusID=2; //Marking script as load-pendin
				Boxes.LoadedScripts[BoxScript].DelayedCommands = "";
	
				NewScript=document.createElement("script");
				NewScript.language="javascript";
				NewScript.src="/boxes/"+BoxScript+".js";
				document.body.appendChild(NewScript);
				//Debug("Added script - " + NewScript.src);
				
			}
		}
		
		if (Boxes.LoadedScripts[BoxScript].StatusID==1)
		{//Can execute code
			//Debug("Loading in - ready mode");
			Box_UpdateLoadStatus(Handler.BoxObject,"");
			eval(BoxScriptCode);
		}
		else
		{//In pending mode - Add to delayed queue
			//Debug("Loading in - delayed mode");
			//Debug(BoxScript+":"+BoxScriptCode);
			Boxes.LoadedScripts[BoxScript].DelayedCommands += BoxScriptCode+"\n";
		};

	};
		
	Boxes.Comm.Statuses['LoadBoxContent']-=1;
	Boxes.Comm.UpdateCommIndicator();
	
	//Free up memory
	NewScript = null;
	BoxID = null;
	BoxContent = null;
	BoxScript = null;
	BoxPrerequisiteScripts = null;
	BoxScriptsArray = null;
	BoxScriptCode = null;
	RunIndex = null;
	DataSet = null;
	XMLroot = null;
};


function Server_LoadBoxContent(BoxID)
{
	var Box_Object = Boxes.Objects[BoxID];
	if (Box_Object.LoadBoxContent_Handler) {window.alert("Already loading content for this box..."); return(false)};
	
	//Else
	Box_Object.LoadBoxContent_Handler = new XMLHTTPEngine("LoadBoxContent",""); //Creates LoadBoxContent Ajax Handler for the current box
	Box_Object.LoadBoxContent_Handler.onLoad = LoadBoxContent_onLoad;
	try 
	{
		Boxes.Comm.Statuses['LoadBoxContent']+=1;
		Boxes.Comm.UpdateCommIndicator();

		Box_Object.LoadBoxContent_Handler.URL='/cgi-bin/profile/boxes.pl?usk='+USK+'&act=load&id='+BoxID;
		//Debug("Calling load box content @ "+Box_Object.LoadBoxContent_Handler.URL);
		Box_Object.LoadBoxContent_Handler.BoxObject = Box_Object;
		Box_Object.LoadBoxContent_Handler.BoxHandler = Box_Object.Handler;
		Box_Object.LoadBoxContent_Handler.Content_Original = Box_Object.Content.innerHTML; 
		Box_UpdateLoadStatus(Box_Object,"Loading content");
		
		Box_Object.LoadBoxContent_Handler.Execute();
	}
	catch (e)
	{
		Boxes.Comm.Statuses['LoadBoxContent']-=1;
		Boxes.Comm.UpdateCommIndicator();
	};
};
-->

