/*
 * This file contain all function related to the normal layout stuff. 
 */

/**
 * This function is fired once when the page is loaded.
 * 
 *  All init of the layout should be fired from this function
 */
var layout=null;
function InitLayout()
{
	// Update the HTML tag so we can use brower spesific CSS. 
	css_browser_selector(navigator.userAgent);
	// For the moment we only call ReDraw();
	ReDrawLayout();
	ResizeLayoutDone=1;
	DoMap();
	// Call the original onload incase someone else also got
	// the idea and use onload
	if (orgOnloadInitLayout!=null)
		orgOnloadInitLayout();
	
	// Check for alarms when everything else is done...
	systemCheckAlarm(0);
}
var systemRenderMap=0;
// Initiating InitLayout on load of page
var orgOnloadInitLayout=window.onload;
window.onload=InitLayout;

/**
 * Resize the layout based on "data".
 * 
 * Data is a array of elements that shall be placed within the size 
 * given by size. Each element can be one of two types:
 * If data[i].id!='' it is a layout that shall be resized.
 * If data[i].id=='' it is a container that contains several new data elements to be drawed.
 * For each element the type can either be 0 if size is preset in pixel or 1 if size is a 
 * precentage. All elements with precentages must total up to 100.
 * Atleast one field should be precent to fill out the screen.
 * For elements that are container there is a child attribute containing a new array of 
 * elements. This will be recursively called to ReSizeLayout with the area and position
 * given to the container element. 
 * @param size This is a object containing {w,h} as width and hight of the area available for this layout.
 * @param direction The direction that the objects will be placed
 * @param data The data that shall be placed. Look at function description.
 * @param pos The absolute position that the placemant shall start.
 */
function ReSizeLayout(size,direction,data,pos)
{
	// We assume that some of the fields is based on percent and some is absoulte.
	// First we need to find out how much is reserved for the direction asked for.
	var res=0,res2=0,i,value,left,width,top,height;
	var per=100;
	var sizes=[];
	var foundSpecial=false;
	
	// We gonna run thru this twice. First: Find and calculate anything that is fixed or
	// almost fixed. Then we run thru and calc the rest. When this is done we loop thru all 
	// of them and put them out on the page.
	
	
	// Absolute fixed:
	for(i=0;i<data.length;i++)
		if (!data[i].type)
		{
			sizes[i]=data[i].size;
			res+=data[i].size;
		}
	// Whatever is left now got some sort of persentage. So now we look for any abnormalities.
	// This means anything that got min, max or step.
	for(i=0;i<data.length;i++)
		if (data[i].type && (data[i].min || data[i].max || data[i].step))
		{
			if (direction)
				value=(size.w-res)*data[i].size/100;
			else
				value=(size.h-res)*data[i].size/100;
			
			value=Math.round(value);
			
			if (data[i].step && !data[i].min) value=(Math.round(value/data[i].step))*data[i].step;
			if (data[i].step && data[i].min) value=(Math.round((value-data[i].min)/data[i].step))*data[i].step+data[i].min;
			if (data[i].min && value<data[i].min) value=data[i].min;
			if (data[i].max && value>data[i].max) value=data[i].max;
			sizes[i]=value;
			res2+=value;
			foundSpecial=true;
		}
	
	res+=res2;
	
	// If we found a abnormality (even if no adjustemts was done) then we need to recalculate the % for the rest. 
	if (foundSpecial)
	{
		per=0;
		for(i=0;i<data.length;i++)
			if (data[i].type && !data[i].min && !data[i].max && !data[i].step)
				per+=data[i].size;
	}
	// Now we find the actuall size for the rest of the fields.
	for(i=0;i<data.length;i++)
		if (data[i].type && !data[i].min && !data[i].max && !data[i].step)
		{
			if (direction)
				value=(size.w-res)*data[i].size/per;
			else
				value=(size.h-res)*data[i].size/per;
			value=Math.round(value);

			sizes[i]=value;
		}
	// Now we draw the stuff.
	for(i=0;i<data.length;i++)
	{
		if (sizes[i]<60) sizes[i]=60;
		// Value is now the width or height depend on direction.
		// Do we got a container or a content block?
		if (data[i].id!="")
		{
			var obj=document.getElementById(data[i].id);
			var objOuter=document.getElementById(data[i].id+"_outer");
			if (!obj)
			{
				alert("Fatal: Could not find object "+data[i].id);
				return;
			}
			
			top=pos.top+data[i].rmargin;
			left=pos.left+data[i].lmargin;
			width=size.w-data[i].rmargin-data[i].lmargin;
			height=size.h-data[i].rmargin-data[i].lmargin;
			
			if (direction)
			{
				left=pos.left+(i && data[i-1].lmargin?0:data[i].lmargin);
				width=sizes[i]-data[i].rmargin-(i && data[i-1].lmargin?0:data[i].lmargin);
			}
			else
			{
				top=pos.top+(i && data[i-1].lmargin?0:data[i].lmargin);
				height=sizes[i]-data[i].rmargin-(i && data[i-1].lmargin?0:data[i].lmargin);
			}
			
			updateObj=obj;
			
			if (objOuter)
			{
				obj.style.width=width+"px";
				obj.style.height=height+"px";
				obj.style.overflow="auto";
				//top-=1;
				//left-=1;
				width+=10;
				height+=10;
				objOuter.style.left=left+"px";
				objOuter.style.width=width+"px";
				objOuter.style.top=top+"px";
				objOuter.style.height=height+"px";
					
			}
			else
			{
				// No outer. We need to keep the block within the place given.
				obj.style.left=left+"px";
				obj.style.top=top+"px";
				obj.style.width=width+"px";
				obj.style.height=height+"px";
			}
			
			obj.style.display="block";
			if (objOuter)
				objOuter.style.display="block";
			// Borders get outside of area.
			// This is a hack to make the border for the menu visible.
			// Shuld have been done much better....
			if (obj.id=="sysMenu")
				sizes[i]++;
		}
		else
		{
			// We just call our self with all the childes.
			if (direction)
				ReSizeLayout({w:sizes[i],h:size.h},data[i].direction,data[i].childes,{left:pos.left, top:pos.top});
			else
				ReSizeLayout({w:size.w,h:sizes[i]},data[i].direction,data[i].childes,{left:pos.left, top:pos.top});
		}
		if (direction)
			pos.left+=sizes[i];
		else
			pos.top+=sizes[i];
	}
	
}

/**
 * 
 * @param a
 * @return
 */
function ReDrawLayout(a)
{
	screenSize=GetScreenSize();
	if (screenSize.w<700) screenSize.w=700;
	if (screenSize.h<450) screenSize.h=450;
	oldScreenSize=screenSize;
	if (layout && layout.childes)
		ReSizeLayout(screenSize,layout.direction,layout.childes,{left:0,top:0});
	
	// We do get a exception if no maps are loaded..
	try {
	if (currentMapObject) currentMapObject.CheckResize();
	} catch(e){};
	// We have done the redrawing of layout. Now we must redraw any views that got a fixed height:
	var len=BlockContentScroll.length;
	for(var i=0; i<len;i++)
		UpdateContentScroll(BlockContentScroll[i].objID,BlockContentScroll[i].titleHeight,BlockContentScroll[i].forceHScroll);
}

/**
 * This function is called deleayed after each resize.
 * 
 * Calling the resize og screen is heavy so we use a delayed trigger.
 * The idea is that for each resize the global index is increased and
 * sendt as parameter to the timed function. When this function finaly 
 * fires it will check the global index again to see if it is equal.
 * If its not we know that new resize events are comming and can safly 
 * ignore this call. When we are at the end of the line we finaly call 
 * resize and upate the layout.
 * @param index
 * @return
 */
function TimedResizeLayout(index) 
{
	if (OnResizeLayoutIndex==index) ReDrawLayout();
}

/**
 * Function that is fired on a resize of the window.
 */
function OnResizeLayout()
{
	screenSize=GetScreenSize();
	
	// We set a minimum screen size. This is primary to give mobile units
	// a chance to run this.
	if (screenSize.w<700) screenSize.w=700;
	if (screenSize.h<450) screenSize.h=450;
	
	if (screenSize.w==oldScreenSize.w && screenSize.h==oldScreenSize.h) return;
	OnResizeLayoutIndex++;
	setTimeout("TimedResizeLayout("+OnResizeLayoutIndex+")",300);
	
	// If anyone else also has hoocked into the function, we call this also.
	if (orgOnResizeLayout!=null)
		orgOnResizeLayout();
}
// Sett up the resize event
var oldScreenSize={w:-1,h:-1};
var OnResizeLayoutIndex=0;
var ResizeLayoutDone=0;
var orgOnResizeLayout=window.onresize;
window.onresize=OnResizeLayout;

var BlockContentScroll=new Array();

/**
 * Sets the high of a block in percent or absolute value.
 * 
 * Absolute values is given as negaive numbers.
 * @param height The hight of the block.
 * @param objID The ID of the block getting the size set.
 * @param titleHeight This value is removed when calculating percent size.
 * @return None
 */
function SetBlockContentScroll(objID,titleHeight,forceHScroll)
{
	// If we are done resizing we will just update now, if not we will wait untill the resize is done.
	var max=BlockContentScroll.length;
	BlockContentScroll[max]={objID:objID,titleHeight:titleHeight,forceHScroll:forceHScroll};
	if (ResizeLayoutDone)
		UpdateContentScroll(objID,titleHeight,forceHScroll);
}

/**
 * IE SUCK! And this function does something desperate to do something about it.
 * @param objID
 */
function TimedIETableWidthUpdate(objID)
{
	// In IE we have the problem that a scrollbar is not considered as something that 
	// does the area inside the div the scrollbar is connected to any less.
	// In addition we got a resize problem when resizing thing up in size.
	// We just force a new width on it...
	var obj=document.getElementById(objID); 
	if (!obj) return;
	var tableObj=obj.getElementsByTagName("table");
	if (tableObj.length>0)
		tableObj[0].style.width=obj.clientWidth;
}

/**
 * Does the actual resize of a block.
 * @param height The hight of the block.
 * @param objID The ID of the block getting the size set.
 * @param titleHeight This value is removed when calculating percent size.
 * @return None
 */
function UpdateContentScroll(objID,titleHeight,forceHScroll)
{
	var obj=document.getElementById(objID);
	if (obj)
	{
		tmp=obj.parentNode;
		while(tmp && tmp.tagName!="DIV") 
			tmp=tmp.parentNode;
		tmp=tmp.parentNode;
		while(tmp && tmp.tagName!="DIV") 
			tmp=tmp.parentNode;
		tmp.style.overflow="hidden";
//		obj.parentNode.style.overflow="hidden";
		if (isIE() && !forceHScroll)
		{
			obj.style.overflowX="hidden";
			obj.style.overflowY="auto";
			obj.style.height=(tmp.offsetHeight-titleHeight)+"px";
			setTimeout("TimedIETableWidthUpdate('"+objID+"');",300);
		}
		else
		{
			obj.style.overflow="auto";
			obj.style.height=(tmp.offsetHeight-titleHeight)+"px";
		}
	}
}


/*
 * This functions is helper functions for popup pages.
 * 
 * Its IMPORTANT that when you open a dialog, you also close it this way.
 * This is to make sure you clean out the memory that is used.
 * 
 * NB! Repeated calls will reuse the element.
 */
var currentPopupZIndex=1;

/**
 * Raise the first layer containg a element with sysPopup as classname connected to the click event.
 * @param e Event
 */
function RaiseOnClick(e)
{
	var targ;
	if (!e) e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	while(targ && targ.className!="sysPopup") targ=targ.parentNode;
	if (targ) RaisePopup(targ);
	return true;
}

/**
 * Creates a popupframe and call ajax to fill it with content.
 * @param element The ID of the container. If this container does not exist then one is created.
 * @param action The action to be runned on server side.
 * @param params Array of params pair to the server side. Format is: [['param1','data1'],['param2','data2'],..]
 */
function AjaxPopup(element, action, params)
{
	var obj=document.getElementById(element);
	if (!obj)
	{
		obj=document.createElement("div");
		obj.className="sysPopup";
		obj.id=element;
		obj.onmousedown=RaiseOnClick;
		obj.isPopup=1;
		document.getElementById("popUpContainer").appendChild(obj);
	}
	RaisePopup(obj);
	// Now we just fill it with whatever this ajax call requests.
	systemAjaxPopup(element, action, params);
}

var popupDimentions={};

/**
 * Sets up the dimention for a popup.
 * @param containerID ID for the container.
 * @param blockID ID for the block.
 * @param left Left pos. Nagitive is from right. 0 is center.
 * @param top Top position. Negativ is from bottom. 0 is center.
 * @param width Width of box. Must be given.
 * @param height Height of box. If 0 then height is auto.
 */
function SetPopupDimention(containerID,ID,left,top,width,height,relateTo,counter)
{
	var blockID=ID+"Block";
	var titleID=ID+"Header";
	var contObj=document.getElementById(containerID);
	var blockObj=document.getElementById(blockID);
	var screen=GetScreenSize();
	var relateToObj=document.getElementById(relateTo);
	var xOffset=0,yOffset=0;
	
	if (counter && counter>10)
	{
		relateToObj=null;
		relateTo="NoObjectEverGonnaHaveThisID";
	}
	
	if (relateToObj)
	{
		if (!counter) counter=0;
		xOffset=relateToObj.offsetLeft;
		yOffset=relateToObj.offsetTop;
		screen.w=relateToObj.offsetWidth;
		screen.h=relateToObj.offsetHeight;
		if (screen.w<10 || screen.h<10)
		{
			setTimeout("SetPopupDimention('"+containerID+"','"+ID+"',"+left+","+top+","+width+","+height+",'"+relateTo+"',"+(counter+1)+")",100);
			return ;
		}
	}
//	if (counter && counter>0) alert(counter+","+screen.w+","+screen.h);
	if (!contObj || !blockObj) return;
	// Meep. Lets just store the stuff to later.
	popupDimentions[containerID]={blockID:blockID, titleID:titleID, left:left, top:top, width:width, height:height, relateTo: relateTo};
	RefreshPopupDimention(containerID,screen);
}

function RefreshPopupDimention(containerID,screen)
{
	var left=popupDimentions[containerID].left;
	var top=popupDimentions[containerID].top;
	var width=popupDimentions[containerID].width;
	var height=popupDimentions[containerID].height;

	var contObj=document.getElementById(containerID);
	var blockObj=document.getElementById(popupDimentions[containerID].blockID);
	var titleObj=document.getElementById(popupDimentions[containerID].titleID);
	if (!screen)
		screen=GetScreenSize();
	var relateToObj=document.getElementById(popupDimentions[containerID].relateTo);
	var xOffset=0,yOffset=0;
	
	// Just reset them before we start using the data:
	blockObj.style.height="auto";
	contObj.style.width="auto";
	
	if (relateToObj)
	{
		xOffset=relateToObj.offsetLeft;
		yOffset=relateToObj.offsetTop;
		screen.w=relateToObj.offsetWidth;
		screen.h=relateToObj.offsetHeight;
	}
	
	if (!contObj || !blockObj) return;
	
	if (contObj.offsetHeight>screen.h*0.9 && (height==0 || height>screen.h*0.9))
	{
		height=screen.h*0.9;
		// We will also have scrollbars...
		width+=16;
	}
	
	if (height>0) blockObj.style.height=height+"px";
	contObj.style.width=(width+10)+"px";
	blockObj.style.width=width+"px";
	if (titleObj)
		titleObj.style.width=width+"px";
	
	if (isIE())
	{
		var imgObj=document.getElementById("pImgH_"+containerID);
		if (imgObj) imgObj.style.width=(width-8)+"px";
		imgObj=document.getElementById("pImgV_"+containerID);
		if (imgObj) imgObj.style.height=(blockObj.offsetHeight-8)+"px";
	}
	
	// We do not want to repos the window if it allready exist. Someone might
	// have moved it with the exception that its dimentons has changed and 
	// some of the window is outside of screen...
	if (contObj.style.left!=null && contObj.style.left!='')
	{
		if (contObj.offsetHeight+contObj.offsetTop>screen.h)
			contObj.style.top=(yOffset+(screen.h-contObj.offsetHeight)/2)+"px";
		return;
	}
	if (!top) contObj.style.top=(yOffset+(screen.h-contObj.offsetHeight)/2)+"px";
	else
	if (top>0) contObj.style.top=(yOffset+top)+"px";
	else contObj.style.top=(yOffset+screen.h-contObj.offsetHeight+top)+"px";
	
	if (!left) contObj.style.left=(xOffset+(screen.w-width)/2)+"px";
	else
	if (left>0) contObj.style.left=(xOffset+left)+"px";
	else contObj.style.left=(xOffset+screen.w-width+left)+"px";
	
}

var modalPopupLayer=null;

/**
 * Removes the element if is exist. This is only to be used with popupelements.
 * @param element The ID of the conteiner.
 */
function RemovePopup(element)
{
	var obj=document.getElementById(element);
	if (obj && obj.className=="sysPopup")
	{
		if (obj.onClose)
			obj.onClose();
		obj.parentNode.removeChild(obj);
	}
	// Remove the modal layer if it exist and has the same ID that the element. 
	if (modalPopupLayer && modalPopupLayer.id==element+"Modal")
	{
		modalPopupLayer.parentNode.removeChild(modalPopupLayer);
		modalPopupLayer=null;
	}
}

function SetOnClose(element,func)
{
	var obj=document.getElementById(element);
	if (!obj) return;
	obj.onClose=func;
}
/**
 * Grabs the next zIndex and set it on the object.
 * @param obj Object to come to front.
 */
function RaisePopup(obj)
{
	currentPopupZIndex++;
	obj.style.zIndex=currentPopupZIndex;
}

/**
 * Takes the ID of an popup and do it modal.
 * @param element The id of the element.
 */
function DoPopupModal(element)
{
	var obj=document.getElementById(element);
	if (!obj) return;
	if (modalPopupLayer) modalPopupLayer.parentNode.removeChild(modalPopupLayer);

	currentPopupZIndex++;
	
	modalPopupLayer=document.createElement("div");
	modalPopupLayer.className="sysModalBg";
	modalPopupLayer.id=element+"Modal";
	modalPopupLayer.style.zIndex=currentPopupZIndex;
	document.getElementById("popUpContainer").appendChild(modalPopupLayer);
	RaisePopup(obj);
}

/**
 * Toggles mimize status and changes the image. 
 * @param objImg The image object that shall be changed.
 * @param id The id for the block that shall be toggled.
 * @param images Images set used for the togle. 
 * @return
 */
var toggleImageSet=[["/popup/arrowd.gif","/popup/arrowr.gif"],
                    ["/frm/arrowd.gif","/frm/arrowr.gif"]];

var toggleState={};
function ToggleMinimize(objImg,id,images,path)
{
	var obj=document.getElementById(id+'Block');
	if (!obj) return;
	if (obj.style.display=='block' || obj.style.display=='')
	{
		obj.style.display='none';
		objImg.src=path+toggleImageSet[images][1];
		toggleState[id+"state"]=2;
	}
	else
	{
		obj.style.display='block';
		objImg.src=path+toggleImageSet[images][0];
		toggleState[id+"state"]=1;
	}
}

function RestoreMinimizeState(id, default_state,path)
{
	var obj=document.getElementById(id+'Block');
	var objImg=document.getElementById(id+'MiniImg');
	if (!obj) return;
	if (!toggleState[id+"state"])
		toggleState[id+"state"]=default_state;
	if (toggleState[id+"state"]==2)
	{
		obj.style.display='none';
		// We only use this for frm and not popup atm.
		objImg.src=path+toggleImageSet[1][1];
	}
	else
	{
		obj.style.display='block';
		// We only use this for frm and not popup atm.
		objImg.src=path+toggleImageSet[1][0];
	}
}

/**
 * Function that manage movement of a popupwindow.
 * 
 * The reason for hocking this thing on "document.body" is becouse every mouse 
 * event will finaly bouble down there and no mathere where I might drag the mouse
 * it will be over the body. If this is not done the window will stop getting mouse
 * move events if the mouse manage to "lag" outside the area that recieve the events.
 */

var movedPopupObj=null;

/**
 * This is a object representing current movement. 
 * @param obj Object beeing draged.
 * @param offsetX Offset of mouse inside dragging area.
 * @param offsetY Offset of mouse inside dragging area.
 */
function PopupMove(obj,offsetX,offsetY,width,height)
{
	this.obj=obj;
	this.offsetX=offsetX;
	this.offsetY=offsetY;
	this.maxHeight=height;
	this.maxWidth=width;
}

function MouseMovePopup(e)
{
	if (!movedPopupObj) return;
	if (!e) e = window.event;
	movedPopupObj.obj.style.left=((e.clientX<0?0:(e.clientX>movedPopupObj.maxWidth?movedPopupObj.maxWidth:e.clientX))-movedPopupObj.offsetX)+"px";
	movedPopupObj.obj.style.top=((e.clientY<0?0:(e.clientY>movedPopupObj.maxHeight?movedPopupObj.maxHeight:e.clientY))-movedPopupObj.offsetY)+"px";
	return false;
}
	
function StopMovePopup()
{
//	alert(movedPopupObj.obj.innerHTML);
	document.body.onmousemove=null;
	document.body.onmouseup=null;
	delete movedPopupObj;
	movedPopupObj=null;
}

function StartMovePopup(obj,event)
{
	var screen=GetScreenSize();
	movedPopupObj=new PopupMove(obj,event.clientX-obj.offsetLeft,event.clientY-obj.offsetTop,screen.w, screen.h);
	document.body.onmousemove=MouseMovePopup;
	document.body.onmouseup=StopMovePopup;
	RaisePopup(obj);
}

/* Popup windows (browser window) */
// PopupWondow function name was used (calendar)
function ShowPopupWindow(url, params, name, width, height)
{
	// Add params to url
	for (key in params) {
		url+= ((url.search(/\?/)>0)? '&':'?') + 'p['+key+']=' + params[key];
	}
	
	// Popup config
	var popupConfig = 'status=1,toolbar=0,location=0,menubar=0,directories=0,resizable=1,scrollbars=1,width='+width+',height='+height;
	
	var popupWindow=window.open(url, name, popupConfig);
	popupWindow.moveTo((screen.width-width)*0.5,(screen.height-height)*0.3);
	popupWindow.focus(); // If window (name) exist but is in the background
}


/* Test dummy: */
function DoMap(elm)
{
	if (!systemRenderMap) return;
	SystemInitMap();
}	
