/* Request object, defines a request and methods on it. */
// theTarget_id : html element that needs updating, i.e. <div id="bla_bla" ...> theTarget_id=bla_bla
// theCommand : The command to execute, see AjaxServlet::AjaxMethods
// theType : Command type, must be on of : listbox, val, custom 
//     listbox : requires an array of name/value pairs see function getArrayElement() for details
//     custom :  requires one value only ( <xml><val>value</val></xml> ) see function getElement() for details
// thePreFunction  : A javascript function to call before ther request is made
// thePostFunction : A javascript function to call after the response is received
// theShowWait : Show a progress bar while eaiting for the response
// theUpdateText : Text to show next to the wait progress bar     
function PremiRequest(theTarget_id,theCommand,theMethod,theType,thePreFunction,thePostFunction,theShowWait,theUpdateText) {
	this.target_id = theTarget_id;
	this.command = theCommand; 
	this.preFunction2 = thePreFunction;
	this.postFunction2 = thePostFunction;
	this.showWait = theShowWait;
	this.type = theType;
	this.method = theMethod;
	this.param = null;
	if (theUpdateText==null) theUpdateText = "Loading";
	this.updateText  = theUpdateText;
	
	// format and return the ajax request query string
	this.getCommand = function () {
		var str="command="+this.command+"&method="+this.method;
		str += "&id="+this.target_id+"&type="+this.type;
		if (this.param!=null) 
			str+="&param="+this.param;
		return str;	
	}
	
	// Ajax response handler, called when the request has finished.
	this.handleResponse = function(theResponse,theType) {
		
		var result=true;
		// internal we can handle listbox and innerHTML updating.
		// for other types use the thePostFunction to update the DOM yourself.
		if (theType=="listbox") {
			aVal   = getArrayElement(theResponse,'listbox','option');
			logger("ListBox PremiRquest",aVal,INFO);
			result = updateListBox(aVal,this.target_id);
		}
		if (theType=="val") {
	   	    aVal   = getElement(theResponse,'val',0);			
	   	    logger("value PremiRquest",aVal,INFO);
			result = updateValue(aVal,this.target_id);
		}
		// call the postFunction, from it the user defined postFunction will be called
		this.postFunction(theResponse);

		if (result==false) 
			logger("PremiRequest","No such item  "+ this.target_id,ERROR );
	}
	
	// debug stuff
	this.toString = function() {
		return "target_id="+this.target_id+"\r\ncommand="+this.command;
	}	
	
	// Called before the request is made, you can include your own pre handler by
	// setting thePreFunction. This will insert a progress bar in the block element with id=status
	// The progress bar is only shown if theShowWait = true
	this.preFunction =function() {
		if (this.showWait) {
			this.showActivityDialog();
		}
		if (this.preFunction2!=null)
			this.preFunction2();
	}

	// Called after the request has finished, will remove the progress bar in the status element.
	this.postFunction =function(theVal) {
		this.removeActivityDialog();
	
		if (this.postFunction2!=null)
			this.postFunction2(theVal);
	}
	
	this.showActivityDialog = function() {  
	   aWidth = (window.innerWidth)?window.innerWidth:document.body.clientWidth; 
       aHeight = (window.innerWidth)?window.innerHeight:document.body.clientHeight; 
   	   removeElement("ajax_progress_dlg");
   	   var aBuf = new StringBuffer();
   	   aBuf.append("<center><table cellspacing=5 height=100%><tr><td valign=middle><img src=\"").append(toUrl("images/anim/ajax_indicator.gif"));
   	   aBuf.append("\" align=left></td><td valign=middle>Loading ...</td></center>");
   	   
	   addAbsolutPositionedElement("ajax_progress_dlg",aBuf.toString(),"ajax_progress_dlg",aWidth/2-200,aHeight/2-100);
	}
	
	this.removeActivityDialog=function() {
		removeElement("ajax_progress_dlg");
	}
	
}

/******************************************** Ajax Class ****************************************************/

function Ajax() {

	// add a new request, takes a premiRequest as argument
	this.addRequest = function(theRequest) {
		var i = findFirstEmptyPos(AjaxReqArray);
		AjaxReqArray[i] = theRequest;
	}
	
	
	this.handleErrorResponse = function (status,errorText) {
	   aWidth = (window.innerWidth)?window.innerWidth:document.body.clientWidth; 
       aHeight = (window.innerWidth)?window.innerHeight:document.body.clientHeight; 
   	   removeElement("ajax_error");
   	   removeElement("ajax_progress_dlg");   	   
   	   var aBuf = new StringBuffer();
   	   aBuf.append("<h1>Could not contact Performance Guard server</h1>");
   	   aBuf.append("<center><Input type='button' value='close' onClick=removeElement(\"ajax_error\");></center>");
   	   
	   addAbsolutPositionedElement("ajax_error",aBuf.toString(),"ajax_error_message",aWidth/2-200,aHeight/2-100);
	}

	// run the given request with the specified param
	// theTarget_id : Ajax request identifier, see premiRequest constructor
	// param : list of params, each param must be seperated by "::"
	this.runRequest = function(theTarget_id,param) {
		var aPremiRequest = getRequest(theTarget_id);
		if (aPremiRequest==null) {
			logger("AJAX","Ajax Request "+theTarget_id+" does not exist!",ERROR);
		}
		else {
			logger("AJAX","Ajax Request:<i> "+theTarget_id+"</i> with params:<i> "+param+"</i>",INFO);
		}
		if (param!=null) 
			aPremiRequest.param = param;
		
		// prepare the request
		aPremiRequest.preFunction();
		
		aHttpRequest = getHTTPRequest();
		aUrl = toUrl("AjaxServlet")+'?'+aPremiRequest.getCommand();
		// call the AjaxServlet, this.update will be called when the response is received.
		aHttpRequest.open("GET",aUrl, true);
		aHttpRequest.onreadystatechange = this.update;
		aHttpRequest.send(null);
	}
	
	// Handle the response from the AjaxServlet.
	this.handleResponse = function(theResponse,theXml) {
	    removeElement("ajax_error");
		if (theResponse==null)
			logger("AJAX","Malformed XML response received\n"+theXml,ERROR);
		else 
		{
			// get the request identifier.
			// a wellformed response always looks like :
			// <?xml version=\"1.0\" encoding=\"ISO-8859-1\"  standalone=\"yes\"?>
			// <response>
			// <value|listbox|[custom]> (one of the predefined types or [custom] ) 
			// ... actual response	...
			// if type==val then it must be a single value
			// if type==listbox then it must be 
			//    <option name="name1" value="value1"/>
			//    <option name="name2" value="value2"/>   etc..
			// </value|listbox|[custom]> (one of the predefined types or [custom]) 
			// <identifier>request/html identifier (premiRequest.theTarget_id)</identifier>
			// <type>type (value|listbox|custom) (premiRequest.theType)</type>
			// <status>Status code</status>
			// </response>
			var aStatus = getElement(theResponse,'status',0);
			var aId = getElement(theResponse,'identifier',0); 
			var aPremiRequest = getRequest(aId);
			if (aPremiRequest==null)  {
				logger("AJAX","Ajax Request "+aId+" does not exist",ERROR);
				return;
			}

			if (aStatus!="OK") {
				aPremiRequest.postFunction();
				logger("AJAX",aStatus,INFO);
				return;
			}
			var aType =getElement(theResponse,'type',0);
			aPremiRequest.handleResponse(theResponse,aType);
		}
	}

	this.update = function() {
		if (aHttpRequest.readyState == 4) 
		{
			if (aHttpRequest.status == 200) {
				logger("AJAX","<div style='width:90%;height:150px;overflow:auto'><xmp>"+aHttpRequest.responseText+"</xmp></div>",INFO,"#7a7");
				var aXml = aHttpRequest.responseXML; 
				Ajax.handleResponse(aXml.documentElement,aXml);

			}
			else {
				// let the user know an error occured.	
				Ajax.handleErrorResponse(aHttpRequest.status, aHttpRequest.statusText);				
				logger("AJAX","Status = "+aHttpRequest.status,INFO);
			}
		}
	}
}

/********************************* Utility functions ************************************************/

/*
 Keep a list of all currently running requests.
 Which id that corresponds to which request is handled internally. 
*/
var	AjaxReqArray = Array();
var Ajax = new Ajax();

/************************** AjaxReqArray array helper methods ****************************************/
function getRequest(target_id) {
	for(i=0;i<AjaxReqArray.length;i++) 
		if (AjaxReqArray[i]!=null && AjaxReqArray[i].target_id == target_id)
			return AjaxReqArray[i];
	return null;		
}

function findFirstEmptyPos(theArray) {
	for(i=0;i<theArray.length;i++) 
		if (theArray[i] == null) return i;
	
	return theArray.length;	
}

	



/************************************ XML stuff **********************************************/

function getUpdatedTime(theXml) {
	return getCData(theXml,"updated",0);
}

function getServerTime(theXml)
{
    var aParent = theXml.getElementsByTagName("ServerTime");
    if (aParent.length!=1)
		return "UNKNOWN";

    return aParent[0].getAttribute("val");
}

function getElement(theXml, theElement,theIndex) {
	var aElem = theXml.getElementsByTagName(theElement);
	if (aElem==null || aElem[theIndex]==null || aElem[theIndex].firstChild==null) {
		logger("XML stuff",theElement +" does not exist"+" index="+theIndex,INFO);	
		return null;
	}
	logger("XML STUFF",theElement +"= "+aElem[theIndex].firstChild.nodeValue,INFO);	
	return aElem[theIndex].firstChild.nodeValue;
}

// get an array element from the xml 
// <namevalues>
//	 <nv_1 name="t1" value="v1" selected="false" />
//	 <nv_2 name="t2" value="v2" selected="true" />
// </namevalues>
function getArrayElement(theXml,theParent,theElement) {
	var listArray = new Array();
	var aParent = theXml.getElementsByTagName(theParent)[0];
	var aList = aParent.childNodes;
	for(i=0;i<aList.length;i++) {
		var aListTag = aList[i];
		listArray[i] = new nameValue( 
		 	 aListTag.attributes[0].nodeValue,
			 aListTag.attributes[1].nodeValue,
			 aListTag.attributes[2].nodeValue);		 		 
			 
		logger("List Array values",	 aListTag.attributes[0].nodeValue+":"+aListTag.attributes[1].nodeValue+":"+aListTag.attributes[2].nodeValue,INFO);
	}	
	return listArray;
}

function getHTTPRequest() {
	var xmlhttp;
/*@cc_on
@if (@_jscript_version >= 5)
	try {
		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			xmlhttp = false;
		}
	}
@else
	xmlhttp = false;
@end @*/
	if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
			xmlhttp = new XMLHttpRequest();
		} catch (e) {
			xmlhttp = false;
		}
	}
	return xmlhttp;
}
