var WINACTION_NONE=0;
var WINACTION_MOVE=1;
var WINACTION_RESIZE=2;
document.winAction=WINACTION_NONE;

var WINRESIZE_NONE=0;
var WINRESIZE_TOP=1;
var WINRESIZE_BOTTOM=2;
var WINRESIZE_LEFT=4;
var WINRESIZE_RIGHT=8;
document.winResizeMode=WINRESIZE_NONE;

var WINPOS_MAXLEFT=screen.width-10;
var WINPOS_MINLEFT=0;
var WINPOS_MINTOP=0;
var WINPOS_MAXTOP=screen.height-100;
var WINSIZE_MINWIDTH=50;
var WINSIZE_MAXWIDTH=screen.width-50;
var WINSIZE_MINHEIGHT=80;
var WINSIZE_MAXHEIGHT=screen.height-50;

var basewindowurl="window.php";

function SetupWin(winid)
{
	var thewin=document.getElementById(winid);
	if(!thewin)return;

	thewin.xInset=12;
	thewin.yInset=thewin.xInset;

	var titlebar=GetChildByClass(thewin, 'wintitlebar');
	if(titlebar) {
		titlebar.onmousedown=WinBarMouseDown;
		thewin.yInset+=titlebar.offsetHeight;
	}
	
	//We frequently need to access the inner window from a reference to the outer
	//one but if I add a reference to it from the outer one the multiple references
	//to it cause a problem for IE's garbage collection!
	thewin.contentChild=GetChildNumberByClass(thewin, 'wininner');
	
	thewin.childNodes[thewin.contentChild].style.height=(thewin.offsetHeight-thewin.yInset)+'px';
	thewin.childNodes[thewin.contentChild].style.width=(thewin.offsetWidth-thewin.xInset)+'px';
	
	//Need to allow event propagation to have resize and move!
	thewin.onmousemove=WinMouseMove;
	thewin.onmousedown=WinMouseDown;
	
	//Add to list of open windows
	if(!document.openWins)document.openWins = new Object();
	document.openWins[winid]=thewin;
	if(!document.numOpenWins) {
		document.numOpenWins=1;
	} else {
		document.numOpenWins++;
	}
	BringToFront(thewin);
}

function WinBarMouseDown(event)
{
	if(document.winAction==WINACTION_NONE) {
		document.winAction=WINACTION_MOVE;
		document.theWin=this.parentNode;
		this.parentNode.storedMousePos=new MousePosition(event);
	}
	BringToFront(this);
}

function WinMouseDown(event)
{
	if(this.potResizeMode != WINRESIZE_NONE) {
debug('starting resize');
		document.winAction=WINACTION_RESIZE;
		document.winResizeMode = this.potResizeMode;
		document.theWin=this;
		this.storedMousePos=new MousePosition(event);
		this.storedCoords=new WindowCoords(this);
	}
	BringToFront(this);
}


function WinMouseMove(event)
{
	var BAR_WIDTH=5;
	var CORNER_LENGTH=30;
	
	if(document.winAction==WINACTION_NONE) { //If we are not currently resizing, decide  whether we can start a resize from this pos and in what directions
		var mousepos=new MousePosition(event);
	
		if(mousepos.posX - this.offsetLeft < BAR_WIDTH) {
			if(mousepos.posY - this.offsetTop < CORNER_LENGTH) {
				this.style.cursor = "nw-resize";
				this.potResizeMode = WINRESIZE_LEFT | WINRESIZE_TOP;
			} else if(this.offsetTop + this.offsetHeight - mousepos.posY < CORNER_LENGTH) {
				this.style.cursor = "sw-resize";
				this.potResizeMode = WINRESIZE_LEFT | WINRESIZE_BOTTOM;
			} else {
				this.style.cursor = "w-resize";
				this.potResizeMode = WINRESIZE_LEFT;
			}
		} else if(this.offsetLeft + this.offsetWidth - mousepos.posX < BAR_WIDTH) {
			if(mousepos.posY - this.offsetTop < CORNER_LENGTH) {
				this.style.cursor = "ne-resize";
				this.potResizeMode = WINRESIZE_RIGHT | WINRESIZE_TOP;
			} else if(this.offsetTop + this.offsetHeight - mousepos.posY < CORNER_LENGTH) {
				this.style.cursor = "se-resize";
				this.potResizeMode = WINRESIZE_RIGHT | WINRESIZE_BOTTOM;
			} else {
				this.style.cursor = "e-resize";
				this.potResizeMode = WINRESIZE_RIGHT;
			}
		} else if(mousepos.posY - this.offsetTop < BAR_WIDTH) {
			if(mousepos.posX - this.offsetLeft < CORNER_LENGTH) {
				this.style.cursor = "nw-resize";
				this.potResizeMode = WINRESIZE_TOP | WINRESIZE_LEFT;
			} else if(this.offsetLeft + this.offsetWidth -mousepos.posX < CORNER_LENGTH) {
				this.style.cursor = "ne-resize";
				this.potResizeMode = WINRESIZE_TOP | WINRESIZE_RIGHT;
			} else { 
				this.style.cursor = "n-resize";
				this.potResizeMode = WINRESIZE_TOP;
			}	
		} else if(this.offsetTop + this.offsetHeight - mousepos.posY < BAR_WIDTH) {
			if(mousepos.posX - this.offsetLeft < CORNER_LENGTH) {
				this.style.cursor = "sw-resize";
				this.potResizeMode = WINRESIZE_BOTTOM | WINRESIZE_LEFT;
			} else if(this.offsetLeft + this.offsetWidth -mousepos.posX < CORNER_LENGTH) {
				this.style.cursor = "se-resize";
				this.potResizeMode = WINRESIZE_BOTTOM | WINRESIZE_RIGHT;
			} else { 
				this.style.cursor = "s-resize";
				this.potResizeMode = WINRESIZE_BOTTOM;
			}	
		} else {
			this.style.cursor = "";
			this.potResizeMode = WINRESIZE_NONE;
		}
	}
	
}

function MoveWin(win, event)
{
	var mcp=new MouseChangePosition(win.storedMousePos, event); 
	win.storedMousePos=new MousePosition(event);
	
	var newtop  = win.offsetTop + mcp.deltaY;
	var newleft = win.offsetLeft + mcp.deltaX;
	if(newtop >= WINPOS_MINTOP && newtop+win.offsetHeight <= WINPOS_MAXTOP) {
		win.style.top = newtop+"px";
	}
	if(newleft >= WINPOS_MINLEFT && newleft+win.offsetWidth <= WINPOS_MAXLEFT) {
		win.style.left = newleft+"px";
	}
}

function ResizeWin(win, event, mode)
{
	var mcp=new MouseChangePosition(win.storedMousePos, event);
	
	if(document.winResizeMode & WINRESIZE_TOP) {
		var newheight=win.storedCoords.height - mcp.deltaY;
		if(newheight >= WINSIZE_MINHEIGHT && newheight <= WINSIZE_MAXHEIGHT) {
			win.style.height = newheight+"px";
			win.style.top = (win.storedCoords.top + mcp.deltaY)+"px";
			win.childNodes[win.contentChild].style.height=(win.offsetHeight-win.yInset)+'px'; //FIX: offsetheight or newheight?
		}

	} else if (document.winResizeMode & WINRESIZE_BOTTOM) {
		var newheight=win.storedCoords.height + mcp.deltaY;
		if(newheight >= WINSIZE_MINHEIGHT && newheight <= WINSIZE_MAXHEIGHT) {
			win.style.height = newheight+"px";
			win.childNodes[win.contentChild].style.height=(win.offsetHeight-win.yInset)+'px';
		}
	}
	if(document.winResizeMode & WINRESIZE_LEFT) {
		var newwidth=win.storedCoords.width - mcp.deltaX;
		if(newwidth >= WINSIZE_MINWIDTH && newwidth <= WINSIZE_MAXWIDTH) {
			win.style.left = (win.storedCoords.left + mcp.deltaX)+"px";
			win.style.width = newwidth+"px";
			win.childNodes[win.contentChild].style.width=(win.offsetWidth-win.xInset)+'px';
		}
	} else if (document.winResizeMode & WINRESIZE_RIGHT) {
		var newwidth=win.storedCoords.width + mcp.deltaX;
		if(newwidth >= WINSIZE_MINWIDTH && newwidth <= WINSIZE_MAXWIDTH) {
			win.style.width = newwidth+"px";
			win.childNodes[win.contentChild].style.width=(win.offsetWidth-win.xInset)+'px';
		}
	}
}

//obj.posX and posY are set to the current positions or -1 for unable to determine
function MousePosition(event) 
{
	this.posX = -1;
	this.posY = -1;
	
	if (!event) var event = window.event;
	
	if (event.pageX || event.pageY) {
		this.posX = event.pageX;
		this.posY = event.pageY;
	}
	else if (event.clientX || event.clientY)
	{
		this.posX = event.clientX + document.body.scrollLeft;
		this.posY = event.clientY + document.body.scrollTop;
	}
}

function MouseChangePosition(obj, event) 
{
	var temp=new MousePosition(event);
	
	this.deltaX= temp.posX - obj.posX;
	this.deltaY= temp.posY - obj.posY;
}

function WindowCoords(win)
{
	this.left=win.offsetLeft;
	this.top=win.offsetTop;
	this.height=win.offsetHeight;
	this.width=win.offsetWidth;
}

//return true if it has successfully shown the correct windows, false otherwise
function SwitchWindows(winstring, delwinstring)
{
	var newwins;
	
	if(winstring) {
		newwins=winstring.split(':');
	}
	
	if(delwinstring) {
		var delwins=delwinstring.split(':');
	
		for(var i=0; i < delwins.length ; i++){
			CloseWin(delwins[i]);
		}
	}
	
	var i=0;
	
	while(newwins && i<newwins.length) {
		if(document.closedWins && document.closedWins[newwins[i]]) {
			ReopenWin(newwins[i]);
			newwins.splice(i,1);
		} else if(document.openWins && document.openWins[newwins[i]]) {
			BringToFront(document.openWins[newwins[i]]);
			newwins.splice(i,1);
		}else {
			i++;
		}
	}
	if(!newwins || newwins.length ==0) {
		return false; //We already have received all the windows
	}
		
	if(AJAXEnabled()) {
		var newwinstring=newwins.join(':');
		
		GetWins(newwinstring);
		return false;
	}
	return true;
}

function AJAXEnabled()
{
	if(typeof document.isAJAXEnabled =='undefined') {
		if(GetXMLHttpRequest()) {
			document.isAJAXEnabled = true;
		} else {
			document.isAJAXEnabled = false;
		}
	}
	return document.isAJAXEnabled;
}

function GetXMLHttpRequest()
{
	var xmlhttp=false;
	try {
  		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 	} catch (e) {
  		try {
   			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  		} catch (E) {
   			xmlhttp = false;
  		}
	 }
	if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  		xmlhttp = new XMLHttpRequest();
	}
	if(xmlhttp) {
		return xmlhttp;
	}
	return false;
}

function GetWins(winstring)
{
	var xmlhttp=GetXMLHttpRequest();
	var statusobj=new Object();
	statusobj.doneChars=0;
	
	var url=basewindowurl+'?win='+winstring;
	xmlhttp.onreadystatechange =function(){GotWindowResponse(xmlhttp, statusobj);};
	xmlhttp.open("GET", url, true);
	xmlhttp.send("");
}
//FIX: handle errors e.g. 300 or 404 returned
function GotWindowResponse(response, statusobj)
{
	if(response.readyState != 4) { //We have only received a partial response so far
		if(response.readyState < 3)return; 
		if(statusobj.noPartial)return;
		
		try {
			var test=response.responseText;
		} catch(e) { //IE can't read the partial response. Give up and go home
			statusobj.noPartial=true;
			return;
		}
	} else {
		//Is this an error message?
		var errormarker=response.responseText.substring(0,5).toLowerCase();
	
		if("error" == errormarker) {
			alert(response.responseText);
		}
	}
	
	var startwin_header= '\n*_dwarfwin_*:';
	var startwin_contents='\n';
	var endwin_marker='\n*_enddwarfwin_*';
	
	while(1) {
		var headerstart=response.responseText.indexOf(startwin_header, statusobj.doneChars);
		
		if(headerstart == -1) {
			//We're done for now
			break;
		}
		var headerend=response.responseText.indexOf(startwin_contents, headerstart+startwin_header.length);
		if(headerend == -1) {
			//We're done for now
			break;
		}
		var endwin=response.responseText.indexOf(endwin_marker,headerend);
		if(endwin == -1) {
			//We're done for now
			break;
		}
		var header=response.responseText.substring(headerstart, headerend);
		var colonpos=header.indexOf(':');
		
		var winname=header.substring(colonpos+1);
		var contents=response.responseText.substring(headerend, endwin);
		
		if(statusobj.existingWin) {
			AlterWin(statusobj.existingWin, winname, contents);
			statusobj.existingWin = null;
		} else {
			CreateWin(winname, contents);
		}
		statusobj.doneChars=endwin;
	} 
}

function CreateWin(name, contents)
{
	var newdiv=document.createElement('DIV');
	
	newdiv.innerHTML=contents;
	newdiv.className='dw_wincontainer';
	
	document.body.appendChild(newdiv);
	
	ExecuteScripts(contents);
	AddToHash(name);
}

function AlterWin(win, name,contents) 
{
	win.innerHTML=contents;
	ExecuteScripts(contents);
}

function ExecuteScripts(text)
{
	var scripts=new Array();
	
	while(1) { //would really like a case-insensitive search that took an offset to start from
		var startscript=text.search(/<script>/i);
		if(startscript==-1) {
			break;
		}
		text=text.substring(startscript+8);
		var endscript=text.search(/<\/script>/i);
		
		if(endscript==-1) {
			break;
		}
		scripts.push(text.substring(0,endscript));
		text=text.substring(endscript+9);
	}
	for(var i=0 ; i<scripts.length ; i++) {
		eval(scripts[0]);
	}
}

function CloseWin(winid)
{
	var thewin=document.getElementById(winid);
	if(!thewin)return;
	
	if(document.openWins)document.openWins[winid]=null;
	if(document.numOpenWins)document.numOpenWins--;
	if(!document.closedWins)document.closedWins=new Object();

	if(thewin.parentNode) {
		thewin.parentNode.removeChild(thewin);
	}
	document.closedWins[winid]=thewin;
	
	RemoveFromHash(winid);
}

function ReopenWin(winid)
{
	if(document.closedWins && document.closedWins[winid]) {
		document.body.appendChild(document.closedWins[winid]);
		
		document.openWins[winid]=document.closedWins[winid];
		BringToFront(document.openWins[winid]);
		
		if(document.numOpenWins)document.numOpenWins++;
		
		document.closedWins[winid]=null;
		
		AddToHash(winid);
	}
}


function SetupAjaxHash()
{
	if(!document.ajaxHash)document.ajaxHash=new Object();
	if(!document.ajaxHash.win)document.ajaxHash.win=new Array();
	if(!document.ajaxHash.delWin)document.ajaxHash.delWin=new Array();
}
function UpdateAjaxHash()
{
	var hash="#";
	
	if(document.ajaxHash.win.length > 0) {
		hash += 'win='+document.ajaxHash.win.join(':');
	}
	if(document.ajaxHash.delWin.length > 0) {
		if(hash.length >1)hash += ';';
		hash += 'delwin='+document.ajaxHash.delWin.join(':');
	}
	window.location.hash=hash;
}

function AddToHash(winid)
{
	if(!document.ajaxHash)SetupAjaxHash();
	
	if(InArray(document.ajaxHash.delWin, winid)) {
		RemoveFromArray(document.ajaxHash.delWin, winid);
	} else {
		AddToArrayIfUnique(document.ajaxHash.win, winid);
	}
	UpdateAjaxHash();
}

function RemoveFromHash(winid)
{
	if(!document.ajaxHash)SetupAjaxHash();
	
	if(InArray(document.ajaxHash.win,winid)) {
		RemoveFromArray(document.ajaxHash.win, winid);
	} else {
		AddToArrayIfUnique(document.ajaxHash.delWin, winid);
	}
	UpdateAjaxHash();
}

function ParseAjaxHash()
{
	if(window.location.hash && window.location.hash.substring(1)) {
		var args=window.location.hash.substring(1).split(';');
		var winstring;
		var delwinstring;
		
		for(var i=0; i<args.length; i++) {
			var tosplit=args[i].indexOf('=');
			
			if(tosplit != -1) {
				var name = args[i].substring(0,tosplit);
				var value= args[i].substring(tosplit+1);
				
				if(name=='win' && winstring == null) {
					winstring=value;
				} else if(name=='delwin' && delwinstring == null) {
					delwinstring=value;
				} 
			}
		}
		SwitchWindows(winstring, delwinstring);
	}
}

function BringToFront(win)
{
	if(!document.maxWinZIndex)document.maxWinZIndex=0;
	document.maxWinZIndex++;
	win.style.zIndex=document.maxWinZIndex;
}

//Fix: not yet finished.
function SwitchContentURL(winid, url)
{
	if(!AjaxEnabled()) {
		window.location=url; //for the moment give up later the server should support this too.
	} else {
		var thewin=document.getElementById(winid);
		
		if(thewin) {
			var xmlhttp=GetXMLHttpRequest();
			var statusobj=new Object();
			statusobj.doneChars=0;
			statusobj.existingWin=thewin;
			
			var url=basewindowurl+'?winurl='+winstring;
			xmlhttp.onreadystatechange =function(){GotWindowResponse(xmlhttp, statusobj);};
			xmlhttp.open("GET", url, true);
			xmlhttp.send("");
		}
	}
}
