/*
These scripts are used to remember the page states
and capture the back and forward button
*/

var intStateCounter=-1;
var arrPageStates=[];Object.append


/* page states */
function pageStateRestore(strPageStateKey){
	//alert(strPageStateKey);
	/*
	Restores the state of the page if back or forward has been pressed, or the page is loaded with a hash
	*/
	dumpLog("pageStateRestore => strPageStateKey: "+strPageStateKey);

	var intKey;
	var objPageStateHistory="";
	var bolUseAjax=true;
	var arrTemp;

	// 0 - get the previous state object from the page state array
	if(arrPageStates.length>0){
		arrTemp=strPageStateKey.split('-');
		if(arrTemp.length>1){
			intKey=arrTemp[1].toInt();
			if(intKey <= (arrPageStates.length-1)){
				//set the object to an element from the internal array
				objPageStateHistory=JSON.decode(arrPageStates[intKey]);
				pageStateRestoreExecute(objPageStateHistory);
				bolUseAjax=false;
			}
		}
	}

	// 1 - if the page array attempt has failed try to recover the state using the webservice
	if(bolUseAjax){
		//alert("restoring: "+strPageStateKey);
		
		var strPageStateId=strPageStateKey;
		if(strPageStateId.indexOf('#')>-1){
			//we need to retrieve the page state object from the webservice
			strPageStateId=strPageStateId.replace(/#/, "");
		}

		var objFormData={
			pagestateid: strPageStateId, 
			mode: 'retrieve', 
			rnd: Math.random()
		};
		
		var objAjax = new Request({
			url: arrIdPath['ustate_store'],
			onSuccess: function(strResponse){
				//alert('RESTORE voor johan: \n'+strResponse);
				if(strResponse==""){
					//if the webservice cannot find the current object then default to the initial page state object
					objPageStateHistory=objPageState;
				}else{
					objPageStateHistory=JSON.decode(strResponse);
				}
				pageStateRestoreExecute(objPageStateHistory);
			}
		}).get(objFormData);



	}
}

function pageStateRestoreExecute(objPageStateHistory){
	/*
	Finds the changed objects within the objPageStateHistory object and sends them to the update function
	*/
	dumpLog("pageStateChange => new objPageStateHistory: "+ JSON.encode(objPageStateHistory));
	var objPageStateChange={};
	var bolChanged=false;
	var arrChangedObjects=[];
	//alert(JSON.encode(objPageStateHistory))
	// 1 - find delta in the page state object
	Object.each(objPageStateHistory, function(value, key){
		bolChanged=false;

		if(isDefined(objPageState[key])){

			Object.each(objPageStateHistory[key], function(valuenested, keynested){

				if(isDefined(objPageState[key][keynested])){
					//dumpLog("objPageState."+key+"."+keynested+" is IS defined in objPageState!!");
					var valuenow=objPageState[key][keynested];
					var valuehistory=objPageStateHistory[key][keynested];
					//dumpLog("valuenow: "+valuenow+" - valuehistory: "+valuehistory);


					if(objPageState[key][keynested]!=objPageStateHistory[key][keynested]){
						dumpLog("objPageState."+key+"."+keynested+" IS CHANGED!!");
						bolChanged=true;
					}


				}else{
					dumpLog("objPageState."+key+"."+keynested+" is NOT defined in objPageState!!");
				}


			});

		}else{
			dumpLog("objPageState."+key+" is NOT defined in objPageState!!");
		}

		if(bolChanged){
			//add the complete changed object to the overall objPageStateChange object
			eval("objPageStateChange."+key+"=objPageStateHistory[key]");
		}

	});

	//dumpLog("** objPageStateChange="+ JSON.encode(objPageStateChange)+" **");

	// 2 - merge changes in page state object to create a new state
	Object.append(objPageState, objPageStateChange);


	// 3 - store state object in webservice
	pageStateStore(objPageState);

	// 4 - fire functions to set the new page state (based on the delta passed)
	pageStateChangeExecute(objPageStateChange);

}

function pageStateChange(objPageStateChange){
	//alert(JSON.encode(objPageStateChange));
	dumpLog("pageStateChange => objPageStateChange: "+ JSON.encode(objPageStateChange));
	var strPageStateId=pageStateGenerateKey()

	// 1 - merge changes in page state object to create a new state
	Object.append(objPageState, objPageStateChange);
	dumpLog("pageStateChange => new objPageState: "+ JSON.encode(objPageState));

	// 2 - store the new state in an internal array
	arrPageStates.push(JSON.encode(objPageState));

	// 3 - store state object in webservice
	pageStateStore(objPageState, strPageStateId);

	// 4 - fire functions to set the new page state (based on the delta passed)
	pageStateChangeExecute(objPageStateChange);

	// 5 - update the history
	historyAdd(strPageStateId);

}

function pageStateStore(objPageState){
	/*
	Stores the current page state on the server using ajax
	*/
	dumpLog("pageStateStore => objPageState: "+ JSON.encode(objPageState));
	var strPageUrl;
	var strReferrer="";
	var strPageState= JSON.encode(objPageState);
	var strPageStateId=location.hash;
	if(pageStateStore.arguments.length==2){
		strPageStateId=pageStateStore.arguments[1];
	}

	if(strPageStateId.indexOf('#')>-1){
		//we need to retrieve the page state object from the webservice
		strPageStateId=strPageStateId.replace(/#/, "");

	}

	//the url to sent to the webservice
	strPageUrl=location.pathname;
	if(strPageUrl=="" || strPageUrl=="/")strPageUrl="/index.asp"
	if(strPageUrl.charAt(strPageUrl.length-1)=="/")strPageUrl+="index.asp";
	if(location.search!="")strPageUrl+=location.search;
	if(document.referrer!=""){
		strReferrer=escape(document.referrer);
	}		
			
	if(strPageStateId!=""){
		var objFormData={
			pagestate: strPageState, 
			pageidreferrer: strPageId, 
			pagestateid: strPageStateId, 
			mode: 'store', 
			pageurl: strPageUrl, 
			referrer: strReferrer, 
			rnd: Math.random()
		};		
		
		var objAjax = new Request({
			url: arrIdPath['ustate_store'],
			onSuccess: function(strResponse){
				//alert('voor johan: \n'+strResponse+'\n'+strPageUrl);
			}
		}).post(objFormData);
	}


}

function pageStateGenerateKey(){
	intStateCounter++;
	return strSessionId+"-"+intStateCounter;
}











/* history manager */
var strHashCurrent='', strHashOld='';
var bolStateManuallyChanged=false;

function historyInit(){
	/*
	Deal with the initial state of the page
	*/
	if (historySessionExists() == false) {
		var strHash=location.hash;
		//handle the initial state of the page
		if(strHash=="" || strHash=="#"){
			//set the initial state
			pageStateChange(objPageState)
		}else{
			//restore the page state using the information in the hash (for ie)
			if(window.ie){
				var strPageStateKey=strHash.replace(/#/, "");
				pageStateRestore(strPageStateKey)
			}

		}
	}


	historyMonitor();
	historyMonitorDump();
}

function historyAdd(strId){
	/*
	Adds an anchor link in the layer and then sets the hash (ie will then store it in it's history)
	*/
	bolStateManuallyChanged=true;
	if(window.ie){
		historySaveStateIframe(strId);
	}else{
		location.hash = strId;
	}
	//alert('*** '+strId);


	(function(){ bolStateManuallyChanged=false; }).delay((250));
}

function historyMonitor(){
	if(window.ie){
		strHashCurrent=historyGetStateIframe();
		//filter the html
		strHashCurrent=strHashCurrent.replace(/<P>(.*)<\/P>/i, "$1");
		if(strHashCurrent!=""){
			if(strHashCurrent!=strHashOld){
				if(!bolStateManuallyChanged){
					dumpLog('BACK/FORWARD BUTTON DETECTED');
					/* CALL THE FUNCTION TO RESTORE THE PAGE STATE FROM THE HISTORY */
					pageStateRestore(strHashCurrent)
				}
				dumpLog('a hash change has been detected');



				location.hash = strHashCurrent;
				strHashOld=strHashCurrent;
			}
		}

	}else{

		strHashCurrent=location.hash;
		if(strHashCurrent!=strHashOld){
				if(!bolStateManuallyChanged){
					dumpLog('BACK/FORWARD BUTTON DETECTED');
					/* CALL THE FUNCTION TO RESTORE THE PAGE STATE FROM THE HISTORY */
					pageStateRestore(strHashCurrent)
				}
				dumpLog('a hash change has been detected');

			strHashOld=strHashCurrent;
		}
	}
	var intTimerId = setTimeout('historyMonitor()',100);
}



function historyMonitorDump(){
	strHashCurrent=location.hash;
	dumpLog(strHashCurrent+" - "+bolStateManuallyChanged);

	var intTimerId = setTimeout('historyMonitorDump()',1000);
}

function historyGetIframe() {
	var history_iframe = document.getElementById("history_iframe");
	var doc = history_iframe.contentDocument;
	if (doc == undefined){
		doc = history_iframe.contentWindow.document;
	}
	return doc;
}

function historySessionExists() {
	var doc = historyGetIframe();
	try {
		if (doc.body.innerHTML == "")
			return false;
		else
			return true;
	}
	catch (exp) {
		// sometimes an exception is thrown if a value is already in the iframe
		return true;
	}
}

function historyGetStateIframe(){

	var strSession=""
	if(historySessionExists()){
		var doc = historyGetIframe();
		strSession=doc.body.innerHTML
	}
	return strSession;

}

function historySaveStateIframe(message) {
	dumpLog("!!historySaveStateIframe => "+message)
	// get our strHtmlTemplate that we will write into the history iframe
	var objDivTemplate = $("history_iframe_template");
	var objNode = objDivTemplate.firstChild;

	// loop until we get a COMMENT_NODE
	while (objNode && objNode.nodeType != 8) {
		objNode = objNode.nextSibling;
	}
	var strHtmlTemplate = objNode.nodeValue;

	// replace the templated value in the constants with our new value
	var strHtml = strHtmlTemplate.replace(/\%message\%/, message);

	// now write out the new contents
	var doc = historyGetIframe();
	doc.open();
	doc.write(strHtml);
	doc.close();
}

