/*
    Copyright (C) 2005 Lawrence Carvalho (dev@nodetraveller.com)

    This library is free software; you can redistribute it and/or 
    modify it under the terms of the GNU Lesser General Public License 
    as published by the Free Software Foundation; either version 2.1 of 
    the License, or any later version.
    This library is distributed in the hope that it will be useful, but 
    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
    License for more details.

    You should have received a copy of the GNU Lesser General Public License 
    along with this library; if not, write to the Free Software Foundation, Inc., 
    59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
    
*/
/*
	Original idea from http://blog.bitflux.ch/wiki/LiveSearch. LiveInfo is
	a completely rewritten version with support for more browsers with support
	for skins and and webservices.
	
	See www.nodetraveller.com for more info.
*/
function liveInfo(sLiveInfoURL,sLiveInfoName,sOpName,sNominatedElId) {
	if (liveInfo.arguments.length!=4)
		alert("Error constructing liveInfo Object. Must be passed 4 arguments");

	this.sLiveInfoURL = sLiveInfoURL;
	this.sLiveInfoName = sLiveInfoName;
	this.sOpName = sOpName;
	this.sPrefix= this.sLiveInfoName + this.sOpName+"_";
	this.oLInfoForm = document.getElementById(this.sPrefix+"liveInfoForm");
	this.oLInfoEl = document.getElementById(this.sPrefix+"liveInfo");
	this.oLInfoTitleEl = document.getElementById(this.sPrefix+"liveInfoTitle");;
	this.oLInfoPgControlsEl = document.getElementById(this.sPrefix+"liveInfoPageControls");
	this.oLInfoStatusTextEl = document.getElementById(this.sPrefix+"liveInfoStatusText");
	this.oLInfoResultsEl = document.getElementById(this.sPrefix+"liveInfoResults");
	this.oLInfoInput = document.getElementById(this.sPrefix+"liveInfoInput");
	this.oLInfoPrevEl = document.getElementById(this.sPrefix+"liveInfoPrev");
	this.oLInfoNextEl = document.getElementById(this.sPrefix+"liveInfoNext");
	this.oLInfoDebugLog = document.getElementById(this.sPrefix+"liveInfoDebug");
	this.oLInfoInput = document.getElementById(sNominatedElId);
	this.bDebug=false;
	this.bDoSubmitForm = false;
	//number of items to show per page
	this.iPageLength = 5;
	//data holder
	this.mData = null;
	//index to current data set
	this.iCurrPage = 0;
	this.iNumOfResults = 0;
	//xmlClient object
	this.oXmlClient = null;
	//last search keyword used
	this.sLastQuery = "";
	//String holding the state of the form when last call is made
	this.sLastQueryAll = "";
	//String holding the state of the form when call is made
	this.sCurrQueryAll = "";
	//timeout to check input
	this.iTriggerInterval = null;
	//num of millisecs to display before hiding
	this.iDisplayTimerValue=10000;
	this.iDisplayInterval = null;
	//number of characters to enter before liveInfo is triggered
	this.iEntryThreshold=3;
	//Array of definable methods to be called when liveInfo is triggered
	this.aTriggerMethods = new Array();
	this.sItemIdentifier = "liveInfoItem";
	this.iHiliteIndex=-1;
	//status text statments
	this.sStatementToken ="?";
	this.sSearchStatement = "Searching for ?";
	this.sErrorStatement = "Error with query : ?";
	this.sProgressStatement = "Receiving... ? ";
	this.sResultStatement = "Displaying ?-? of ? results ";
	this.sHelpStatement = "Interact with the form and navigate the results with the arrow keys or press the escape to close.";
	//The name of the root node in the returning xml. Used only when using iframes to retreive content
	this.sLiveInfoRootNode = "liveInfo";
	//flag denoting whether keyboard is activated
	this.bKeysActivated = true;
	this.bShowing=false;
	//flag to denote whether to show help
	this.bShowHelp = true;
	
}
/*public methods */
liveInfo.prototype.init = function() {
	this.oXmlClient = new xmlClient(this.sLiveInfoURL);
	if ((!window.XMLHTTPRequest) && (!window.ActiveXObject)) { //for iframe based comms
		this.oXmlClient.setClosureNode(this.sLiveInfoRootNode);
	}
	var oSelf = this;
	if (window.ActiveXObject) 
		this.oLInfoInput.attachEvent("onkeydown",function(event) { oSelf.keyHandler(event); });
	else 
		this.oLInfoInput.addEventListener("keypress",function(event) { oSelf.keyHandler(event); },false);
	
	this.hideLiveInfo();
	this.hidePageControls();
}

liveInfo.prototype.setPageLength = function(iNewPageLen) {
	this.iPageLength = iNewPageLen;
}

liveInfo.prototype.setActivateKeys = function(bActKeysFlag) {
	this.bKeysActivated = bActKeysFlag;
}


liveInfo.prototype.previous = function() {
	if (this.iCurrPage>1) 
		this.iCurrPage--;
	else return;
	this.goToPage(Math.abs(Math.max(this.iCurrPage,0)));
	this.startDisplayTimer();
}
liveInfo.prototype.next =function() {
	if ((this.iCurrPage*this.iPageLength)<this.iNumOfResults) 
		this.iCurrPage++;
	else return;
	this.goToPage(Math.min(this.iCurrPage,this.iNumOfResults));
	this.startDisplayTimer();
}


liveInfo.prototype.replaceValidateMethod = function(fNewMethod) {
	this.validateForm = fNewMethod;
}


liveInfo.prototype.showHelp = function(bShowHelp) {
	this.bShowHelp=bShowHelp;
}

liveInfo.prototype.setDisplayTimeout = function(sSecs) {
	this.iDisplayTimerValue = (1000*sSecs);
}

liveInfo.prototype.submit =function() {
	return this.bDoSubmitForm;

}
liveInfo.prototype.setSubmit =function(bDoSubmit) {
	this.bDoSubmitForm = bDoSubmit;
}

liveInfo.prototype.setEntryThreshold = function(sNewThreshold) {
	this.iEntryThreshold = sNewThreshold;
}

liveInfo.prototype.setItemIdentifier = function(sItemIdentier) {
	this.sItemIdentifier = sItemIdentifier;
}
liveInfo.prototype.setSearchStatement=function (sNewStatement) {
	this.sSearchStatement = sNewStatement;
}

liveInfo.prototype.setErrorStatement=function (sNewStatement) {
	this.sErrorStatement = sNewStatement;
}
liveInfo.prototype.setProgressStatement=function (sNewStatement) {
	this.sProgressStatement = sNewStatement;
}
liveInfo.prototype.setResultStatement=function (sNewStatement) {
	this.sResultStatement = sNewStatement;
}

liveInfo.prototype.setDebug = function(sDebugStatus) {
	this.bDebug=sDebugStatus;	
}
liveInfo.prototype.setStatementToken=function (sNewToken) {
	this.sStatementToken = sNewToken;
}

liveInfo.prototype.addOnTriggerMethod = function(fMethod) {
	this.aTriggerMethods[this.aTriggerMethods.length]=fMethod;

}
/*private methods*/
liveInfo.prototype.keyHandler = function(oEvent) {
	this.showLiveInfo();
	if (this.bKeysActivated) {
		var iKeyCode = oEvent.keyCode;
		//opera 7 (not 7.6) has different keycodes for arrows for some reason
		if (window.opera && !window.XMLHttpRequest){
			if (iKeyCode==57573)
				iKeyCode=38;
			else if (iKeyCode==575734)
				iKeyCode=40;
			else if (iKeyCode==57575)
				iKeyCode=37;
			else if (iKeyCode==57576)
				iKeyCode=39;
		}
	
		if (iKeyCode == 40 )
		//KEY DOWN
		{
			if((this.iNumOfResults>0) && (this.bShowing)) {
				this.oHighlight = document.getElementById(this.sPrefix+"liveInfoHighlight");
				if (!this.oHighlight) {
				this.getHiliteItem();
				} else {
					this.oHighlight.id="";
					this.oHighlight = this.oHighlight.nextSibling;
					if(this.iHiliteIndex==this.iNumOfResults-1) {
						this.goToPage(1);
						this.iHiliteIndex=0;
						if (this.oLInfoResultsEl.firstChild)
							this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
						}
						else if (this.iHiliteIndex+1 >= (this.iCurrPage*(this.iPageLength))) {
							this.next();
							this.iHiliteIndex=(this.iCurrPage*this.iPageLength)-(this.iPageLength);
							if (this.oLInfoResultsEl.firstChild)
								this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
						}
					else this.iHiliteIndex++;
				}
				if (this.oHighlight) {
					this.oHighlight.setAttribute("id",this.sPrefix+"liveInfoHighlight");
				}	 
		}
	if (oEvent && oEvent.preventDefault) oEvent.preventDefault();
	  else if (window.event) window.event.returnValue = false;
	} 
	//KEY UP
	else if (iKeyCode == 38 ) {
		if((this.iNumOfResults>0) && (this.bShowing)) {
			this.oHighlight = document.getElementById(this.sPrefix+"liveInfoHighlight");
			if (!this.oHighlight) {
				this.getHiliteItem();
			} 
			else {
				this.oHighlight.id="";
				this.oHighlight = this.oHighlight.previousSibling;
				if(this.iHiliteIndex==0) {
					this.iHiliteIndex=this.iNumOfResults-1;
					this.goToPage(Math.ceil(this.iNumOfResults/this.iPageLength));
					if (this.oLInfoResultsEl.firstChild)
						this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
				}
				else if (this.iHiliteIndex-1 < (this.iCurrPage*(this.iPageLength))-this.iPageLength) {
					this.previous();
					this.iHiliteIndex=(this.iCurrPage*this.iPageLength)-1;
					if (this.oLInfoResultsEl.firstChild)
						this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
				}
				else this.iHiliteIndex--;
			}
			if (this.oHighlight) {
					this.oHighlight.setAttribute("id",this.sPrefix+"liveInfoHighlight");
			}
		}
		//non IE
		if (oEvent && oEvent.preventDefault) oEvent.preventDefault();
	  else if (window.event) window.event.returnValue = false;
	} 
	//LEFT
	else if (iKeyCode == 37) {
		if((this.iNumOfResults>0) && (this.bShowing)) {
			this.oHighlight = document.getElementById(this.sPrefix+"liveInfoHighlight");
			if (!this.oHighlight) {
				this.getHiliteItem();
			} 
			else {
				if ((this.iCurrPage == 1) && (this.iCurrPage ==Math.ceil(this.iNumOfResults/this.iPageLength))) {//if on only page available
					return;
				}
				this.oHighlight.id="";
				this.oHighlight = this.oHighlight.previousSibling;
				if(this.iCurrPage==1) {
					this.goToPage(Math.ceil(this.iNumOfResults/this.iPageLength));
				}
				else
				this.goToPage(this.iCurrPage-1);
				this.iHiliteIndex=Math.min(this.iNumOfResults-1,(this.iCurrPage*this.iPageLength)-(this.iPageLength));
				if (this.oLInfoResultsEl.firstChild)
					this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
			}
			if (this.oHighlight) {
					this.oHighlight.setAttribute("id",this.sPrefix+"liveInfoHighlight");
			}
		}
		//non IE
		if (oEvent && oEvent.preventDefault) oEvent.preventDefault();
		  else if (window.event) window.event.returnValue = false;
	}
	//RIGHT
	else if (iKeyCode == 39) {
		if((this.iNumOfResults>0) && (this.bShowing)) {
			this.oHighlight = document.getElementById(this.sPrefix+"liveInfoHighlight");
			if (!this.oHighlight) {
				this.getHiliteItem();
			} 
			else {
				if ((this.iCurrPage == 1) && (this.iCurrPage ==Math.ceil(this.iNumOfResults/this.iPageLength))) {//if on only page available
					return;
				}
				this.oHighlight.id="";
				if(this.iCurrPage==Math.ceil(this.iNumOfResults/this.iPageLength)) {
					this.goToPage(1);
				}
				else
				this.goToPage(this.iCurrPage+1);
				this.iHiliteIndex=(this.iCurrPage*this.iPageLength)-(this.iPageLength);//0;//Math.min(this.iNumOfResults,(this.iCurrPage*(this.iPageLength-this.iPageLength)));
				if (this.oLInfoResultsEl.firstChild)
					this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
			}
			if (this.oHighlight) {
					this.oHighlight.setAttribute("id",this.sPrefix+"liveInfoHighlight");
			}
		}
			//non IE
		if (oEvent && oEvent.preventDefault) oEvent.preventDefault();
		  else if (window.event) window.event.returnValue = false;
	}
	//ESC
	else if (iKeyCode == 27) {
		highlight = document.getElementById(this.sPrefix+"liveInfoHighlight");
		if (highlight) {
			highlight.removeAttribute("id");
		}
		this.hideLiveInfo();
	} 
}
}




liveInfo.prototype.goToPage=function (iIndex) {
	this.iCurrPage=iIndex;
	this.showData();
}

liveInfo.prototype.call = function() {
	this.callTriggerMethods();
	//validate form
	if (!this.validateForm(this.oLInfoForm))
		return;
	var bPassedThreshold = false;
	//check if passed minimun requirements..
	if (this.oLInfoInput.getAttribute("type")=="text") { //is text type, check length
		if (this.oLInfoInput.value.length>=this.iEntryThreshold) 
			bPassedThreshold  = true;	
	}
	else if (this.oLInfoInput.nodeName=="SELECT") { //if select check that one option is selected
		if (this.oLInfoInput.selectedIndex>=0) 
			bPassedThreshold =true;
	}
	this.getParameters();
	var bIsNewQuery = (this.sCurrQueryAll!=this.sLastQueryAll);
	if ((bPassedThreshold ) && (bIsNewQuery)) {
		this.oXmlClient.abort();
		if (this.oLInfoInput.value == "") {
			this.hideLiveInfo();
			return false;
		}
		this.sLastQueryAll=this.sCurrQueryAll;
		
		this.oXmlClient.query(this);
		window.clearInterval(this.iTriggerInterval);
	}
}

liveInfo.prototype.getParameters = function() {
	this.sCurrQueryAll ="";
	this.oXmlClient.clearParameters();
		var aParams = this.parseForm(this.oLInfoForm);
		for(var i=0;i<aParams.length;i++) {
			this.oXmlClient.addParam(aParams[i].name,aParams[i].value);
			this.sCurrQueryAll+=aParams[i].name+","+aParams[i].value+"|";
			if(this.bDebug)
				this.oXmlClient.addParam("debug","1");
	
			if (this.oLInfoInput.getAttribute("type")=="text")
				this.sLastQuery = this.oLInfoInput.value;
		}
}

liveInfo.prototype.parseForm = function(oFrm) {
	var aParams = new Array();
	var aInputEls  = oFrm.getElementsByTagName("input");
	var iNumInputEls = aInputEls.length;
	for (var i=0;i<iNumInputEls;i++) {
		var oInputEl = aInputEls[i];
		sInputType = oInputEl.getAttribute("type");
		if (!oInputEl.disabled){
			sElId = oInputEl.getAttribute("id");
			switch (sInputType) {
				case "text":
				case "hidden":
				case "password":
					aParams[aParams.length] = {name:sElId,value:oInputEl.value}; // otherwise send as given name
					break;	
				case "checkbox":
				case "radio":
					if (oInputEl.checked) {
						aParams[aParams.length] = {name:sElId,value:oInputEl.value}; // otherwise send as given name
					}
					break;
			}
		}
	}
	aSelectEls  = oFrm.getElementsByTagName("select");
	var iNumSelEls = aSelectEls.length;
	for (var i=0;i<iNumSelEls;i++) {
		var oSelectEl = aSelectEls[i];
		if (!oSelectEl.disabled) {
			var sSelId = oSelectEl.getAttribute("id");
			
			if ((sSelId=="") || (sSelId==null))
				sSelId= oSelectEl.getAttribute("name");
			
			if ((oSelectEl.getAttribute("multiple")!=null) &&  (oSelectEl.getAttribute("multiple")!=false)){ //get multiple selections				
				var selOptions = oSelectEl.options;
				for(var j=0;j<selOptions.length;j++) {
					var selOption = selOptions[j];
					if (selOption.selected){
						 aParams[aParams.length] = {name: sSelId,value:selOption.getAttribute("value")}; // otherwise send as given name
					}
				}
			}
			else { //get single selection
					{aParams[aParams.length] = {name: sSelId,value:oSelectEl.options[oSelectEl.selectedIndex].getAttribute("value")};  // otherwise send as given name
				}
			}	
		}
	}
	//add liveInfo and sOpName parameters
	aParams[aParams.length]={name:"liveInfo",value:this.sLiveInfoName};
	aParams[aParams.length]={name:"opName",value:this.sOpName};
	
	return aParams;
}

liveInfo.prototype.reset = function () {
	this.iHiliteIndex=-1;
}

/*
A simple function to validate a form. Simply checks if all text,hidden,fields are not empty and also 
if select has at least one selected index
*/
liveInfo.prototype.validateForm = function(oFrm) {
	var aInputEls  = oFrm.getElementsByTagName("input");
	var iNumInputEls = aInputEls.length;
	for (var i=0;i<iNumInputEls;i++) {
		var oInputEl = aInputEls[i];
		sInputType = oInputEl.getAttribute("type");
		if (!oInputEl.disabled){
			switch (sInputType) {
				case "text":
				case "password":
					if (oInputEl.value=="") {
						status = false;
					}
					break;	
				case "checkbox":
				case "radio":
					//do not valid these fields
					break;
			}
		}
	}
	aSelectEls  = oFrm.getElementsByTagName("select");
	var iNumSelEls = aSelectEls.length;
	for (var i=0;i<iNumSelEls;i++) {
		var oSelectEl = aSelectEls[i];
		if (!oSelectEl.disabled) {
			 if (oSelectEl.selectedIndex==-1) 
			 	return false;
		}
	}
	
	return true;
}



liveInfo.prototype.startDisplayTimer =function() {
	var oSelf = this;
	window.clearInterval(this.iDisplayInterval);
	this.iDisplayInterval = setInterval(function() { oSelf.hideLiveInfo();},this.iDisplayTimerValue);
}
liveInfo.prototype.showLiveInfo=function() {
	
	this.bShowing=true;
	
	if (this.mData==null && this.bShowHelp) {
			if(this.oLInfoEl!=null)
				this.oLInfoEl.style.display="block";
			this.showTitle();
			this.setStatus(this.sHelpStatement);
			this.showStatus;

	}
	else {
		if(this.oLInfoEl!=null)
			this.oLInfoEl.style.display="block";
		this.showTitle();
		this.showResults();
	}
		this.startDisplayTimer();
}

liveInfo.prototype.hideLiveInfo=function() {
	if(this.oLInfoEl!=null)
		this.oLInfoEl.style.display="none";
	this.bShowing=false;
	window.clearInterval(this.iDisplayInterval);
}

liveInfo.prototype.showTitle=function() {
	if(this.oLInfoTitleEl!=null)
		this.oLInfoTitleEl.style.display="block";
}
liveInfo.prototype.hideTitle=function() {
	if(this.oLInfoTitleEl!=null)
		this.oLInfoTitleEl.style.display="none";
}

liveInfo.prototype.showStatus=function() {
	if(this.oLInfoStatusTextEl!=null)
		this.oLInfoStatusTextEl.style.display="block";
}
liveInfo.prototype.hideStatus=function() {
	if(this.oLInfoStatusTextEl!=null)
		this.oLInfoStatusTextEl.style.display="none";
}

liveInfo.prototype.showResults=function() {
	if(this.oLInfoResultsEl!=null)
		this.oLInfoResultsEl.style.display="block";
}
liveInfo.prototype.hideResults=function() {
	if(this.oLInfoResultsEl!=null)
		this.oLInfoResultsEl.style.display="none";
}
liveInfo.prototype.showPageControls=function() {
	if (this.iNumOfResults>0) {
		if (this.iCurrPage==1) {
			this.showNext();
			this.hidePrev();
		}
		else { 
			this.showPrev();
			this.showNext();
		}
		if (this.iCurrPage==Math.ceil(this.iNumOfResults/this.iPageLength)) { //if not last page
			this.hideNext();
			if(this.iCurrPage!=1)
			this.showPrev();
		}
		var iStartPage = ((this.iCurrPage*this.iPageLength)-this.iPageLength);
		var iEndPage = this.iCurrPage*this.iPageLength;
		this.setStatus(this.getResultText((iStartPage+1),(Math.min(iEndPage,this.iNumOfResults)),this.iNumOfResults));
		if(this.oLInfoPgControlsEl!=null)
			this.oLInfoPgControlsEl.style.display="block";
	}
}
liveInfo.prototype.hidePageControls=function() {
	if(this.oLInfoPgControlsEl!=null)
		this.oLInfoPgControlsEl.style.display="none";
}
liveInfo.prototype.setStatus=function (sNewStatus) {
	while(this.oLInfoStatusTextEl.hasChildNodes()) {
			this.oLInfoStatusTextEl.removeChild(this.oLInfoStatusTextEl.firstChild);
	}
	if (typeof(sNewStatus)=="string") {
		if (document.importNode) {
			this.oLInfoStatusTextEl.appendChild(document.createTextNode(sNewStatus));
		}
		else 
			this.oLInfoStatusTextEl.innerHTML = sNewStatus;
	}
	else 
		this.oLInfoStatusTextEl.appendChild(sNewStatus);
}
liveInfo.prototype.showPrev=function () {
	if(this.oLInfoPrevEl!=null)
		this.oLInfoPrevEl.style.visibility="visible";
}

liveInfo.prototype.hidePrev=function () {
	if(this.oLInfoPrevEl!=null)
		this.oLInfoPrevEl.style.visibility="hidden";
}
liveInfo.prototype.showNext=function () {
	if(this.oLInfoNextEl!=null)
		this.oLInfoNextEl.style.visibility="visible";
}

liveInfo.prototype.hideNext=function () {
	if(this.oLInfoNextEl!=null)
		this.oLInfoNextEl.style.visibility="hidden";
}

liveInfo.prototype.populateData = function (mData) {
	if (mData!=null) {
		if (document.importNode) {
			this.mData=document.importNode(mData,true);
			var aNodeList = this.mData.getElementsByTagName("li");
			var iNumItems=0;
			var oSelf = this;
			for(var i=0;i<aNodeList.length;i++){
				if (aNodeList[i].className==this.sItemIdentifier) {
					iNumItems++;
					aNodeList[i].addEventListener("mouseout",function(event) { oSelf.startDisplayTimer() },false);
				}
			}
			this.iNumOfResults=iNumItems;
		}
		if (!document.importNode)  { //ie expects text
			this.mData=mData;
			var re = new RegExp(this.sItemIdentifier,"gi");
			var aItems = this.mData.match(re);
			if (aItems==null) 
				this.iNumOfResults=0;
			else 
				this.iNumOfResults=aItems.length;
		}
		
		this.iCurrPage=1;
	}
	else {
	 	this.iNumOfResults=0;
	 	while(this.oLInfoResultsEl.hasChildNodes()) {
			this.oLInfoResultsEl.removeChild(this.oLInfoResultsEl.firstChild);
		}	
	 }
}



liveInfo.prototype.showData = function() {
	if (document.importNode) {
		while(this.oLInfoResultsEl.hasChildNodes()) {
			this.oLInfoResultsEl.removeChild(this.oLInfoResultsEl.firstChild);
		}
		this.oLInfoResultsEl.appendChild(this.mData);
	}
	else this.oLInfoResultsEl.innerHTML=this.mData;
	
	var aItems = this.oLInfoResultsEl.getElementsByTagName("li");
	var iStartPage = (this.iCurrPage*this.iPageLength)-this.iPageLength;
	var iEndPage = this.iCurrPage*this.iPageLength;
	for (var i =0;i<this.iNumOfResults;i++) {
		if (aItems[i].className==this.sItemIdentifier) {
			//if page >1
			if ((i<iEndPage) && (i>=iStartPage)) {
				aItems[i].style.display="block";
			}
			else aItems[i].style.display="none";
		}
	}
	
	this.showPageControls();
}

liveInfo.prototype.getHiliteItem = function() {
	if (this.iHiliteIndex-(this.iCurrPage*(this.iPageLength)-this.iPageLength)<=0) {
		this.iHiliteIndex=this.iCurrPage*(this.iPageLength)-this.iPageLength;
	}
	else { 
		this.iHiliteIndex=Math.min(this.iNumOfResults-1,((this.iCurrPage*this.iPageLength)-1));
	}
	if (this.oLInfoResultsEl.firstChild)
		this.oHighlight = this.oLInfoResultsEl.firstChild.childNodes[this.iHiliteIndex];
}
liveInfo.prototype.execute =function() {
	if (this.iTriggerInterval) {
		window.clearInterval(this.iTriggerInterval);
	}
	var oSelf =this;
	this.iTriggerInterval= window.setInterval(function() { oSelf.call(); },200);
	this.startDisplayTimer();
}


liveInfo.prototype.onInit= function() {
		  this.showTitle();
		  this.hideResults();
		  this.hidePageControls();
		  this.showLiveInfo();
		  this.setStatus(this.getSearchText());
    	  this.startDisplayTimer();
    }
liveInfo.prototype.onError= function(sStatus,sStatusText) {
	this.setStatus(this.getErrorText(sStatusText));
	this.startDisplayTimer();
}
liveInfo.prototype.onProgress= function(sDataLength) {
	 this.setStatus(this.getProgressText(sDataLength));
   	 this.startDisplayTimer();
}


liveInfo.prototype.onLoad= function(mResult) {
		 if(mResult==null)
		 	return;
		 
		 this.reset();

		//Moz and opera etc
		if (document.importNode) {
			if (this.bDebug) {
				oDebugNode = mResult.getElementById("liveInfoDebug");
				if (oDebugNode!=null)
					this.debugLog(document.importNode(oDebugNode,true).firstChild,true);	
			}
			if (oResultNode = mResult.getElementById("liveInfoResult")) {
				this.populateData(oResultNode.firstChild);
				this.goToPage(1);
  			  	this.showResults();
		  	  	this.showPageControls();
			  	this.showTitle();
			}
			else if (oFaultNode = mResult.getElementById("liveInfoFault")) {
				this.populateData(null);
				this.hideResults();
				this.hidePageControls();
				this.setStatus(document.importNode(oFaultNode.firstChild,true));
			}
			else if (oNoResultNode = mResult.getElementById("liveInfoNoResult")) {
				this.populateData(null);
				this.hideResults();
				this.hidePageControls();
				this.setStatus(document.importNode(oNoResultNode.firstChild,true));
			}
			else { 
				this.hideTitle();
				if (this.bDebug) {
				  	this.setStatus("Received unexpected data from server. Please view debug log to view data");
				}
		  	}
		}
		else if (document.all){
			if (this.bDebug) {
				this.debugLog(this.extractTag("liveInfoDebug",mResult),true);	
			}
			if (mResultText = this.extractTag("liveInfoResult",mResult)) {
				this.populateData(mResultText);
				this.goToPage(1);
  			  	this.showResults();
		  	  	this.showPageControls();
			  	this.showTitle();
			}
			else if (sFaultText = this.extractTag("liveInfoFault",mResult)) {
				this.populateData(null);
				this.hideResults();
				this.hidePageControls();
				this.setStatus(sFaultText);
			}
			else if (sNoResultText = this.extractTag("liveInfoNoResult",mResult)) {
				this.populateData(null);
				this.hideResults();
				this.hidePageControls();
				this.setStatus(sNoResultText);
			}
			else { 
			  	this.hideResults();
				this.hideTitle();
				this.hidePageControls();
				if (this.bDebug) {
				  	this.setStatus("Received unexpected data from server. Please view debug log to view data");
				}
		  	}
		}
}	

liveInfo.prototype.extractTag = function(sTagName,sData) {
	var iPos = sData.indexOf('<'+sTagName+' id="'+sTagName+'">');
	if (iPos!=-1) {
		var iTagNameLength = sTagName.length;
		var sTagValue = sData.slice(iPos+((iTagNameLength*2)+8),sData.indexOf("</"+sTagName+">"));
		return sTagValue;
	}
	else return null;
}


liveInfo.prototype.getSearchText= function() {
	return this.sSearchStatement.replace(this.sStatementToken,this.sLastQuery);
}

liveInfo.prototype.getErrorText=function(sErrorText) {
	return this.sErrorStatement.replace(this.sStatementToken,sErrorText);
}

liveInfo.prototype.getProgressText=function(sProgressText) {
	return this.sProgressStatement.replace(this.sStatementToken,sProgressText += (sProgressText>1000) ? "k" : "b");
}
liveInfo.prototype.getResultText=function(sItemStart,sItemEnd,sItemTotal) {
	var aTokens = this.sResultStatement.split(this.sStatementToken);
	aTokens[0] += sItemStart;
	aTokens[1] += sItemEnd;
	aTokens[2] += sItemTotal;
	return aTokens.join("");
}


liveInfo.prototype.debugLog= function(obj,replace) {
	if (replace) {
		while(this.oLInfoDebugLog.hasChildNodes()) {
			this.oLInfoDebugLog.removeChild(this.oLInfoDebugLog.firstChild);
		}
	}
	if(this.oLInfoDebugLog!=null) {
		if (typeof(obj)=="string") {
			if (document.importNode)
				this.oLInfoDebugLog.appendChild(document.createTextNode(obj));
			else this.oLInfoDebugLog.innerHTML = obj;
		}
		else this.oLInfoDebugLog.appendChild(obj);
	}
	else alert("You've turned debug mode on but there is no element to which to output the debug text.\rPlease insert an element with the id '"+this.sPrefix+"liveInfoDebug'")		
}


liveInfo.prototype.callTriggerMethods = function() {
	for (var i=0;i<this.aTriggerMethods.length;i++) {
		var f = this.aTriggerMethods[i];
		eval("f()");
	}
}
