function SSObject(pName,pParams)
{
	this.name=pName;
	this.params=pParams;
}

/**	
 *	pTrans:	Name of transaction in _TransactionsMethods.js. Ex; loadObject is the name of Transaction_loadObject
 *	pBID:	Name of Buffer ID (or Collection) specified in above mentioned transaction. Ex; Objects
 *	pOW:	True if this bufferitem should be loaded and replaced every time, false if loaded once only
 *	pC:		Condition that must be true for this item to be loaded
 */
function Trans(pTrans,pBID,pOW,pC)
{
	this.trans=pTrans;
	this.bufferId=pBID;
	this.overWrite=pOW;
	this.condition=pC;
}

function Win(pUrl, pName, pFeats)
{
	this.url=pUrl;
	this.name=pName;
	this.feats=pFeats;
	this.open=false;
}

function Page(pName,pDiv,pUserOnly)
{
	this.name			=	pName;		// Name of the pageset
	this.container		=	pDiv;		// Reference to the container in the DOM
	this.loaded			=	false;		// True if the pageset is loaded (structure, packages)
	this.working		=	false;		// True if the pageset is working
	this.packages		=	[];			// Package collection
	this.packagesLoaded	=	false;		// True if packages are loaded
	this.data			=	[];			// Used if packages are not loaded before the data
	this.dataLoaded		=	false;		// True if data are loaded
	this.structure		=	"";			// Structure
	this.structureLoaded=	false;		// True if structure is loaded
	this.structureMounted=	false;		// True if structure is mounted
	this.userOnly		=	pUserOnly;	// If only logged users can access this pageset
	this.params			=	[];			// Parameters to pageset. Set in openPage. Array with strings or simple values.
	this.ssObjects		=	[];
	this.ssTrans		=	[];
}

/**	load
 *	
 *	Is invoked after the frame and the packages of the pageset has been loaded
 */
Page.prototype.load=function(pParams)
{
	this.loaded=(this.packagesLoaded&&this.structureLoaded&&this.dataLoaded);
	var str="\nPage: "+this.name
		+"\nthis.packagesLoaded: "+this.packagesLoaded;
	if (!this.packagesLoaded) {
		str+="[<br>";
		for (var i=0;i<c.packages.length;i++) {
			if (!c.packages[i].loaded) {
				str+='<br>'+_arrToStr(c.packages[i],"this.packages["+i+"]","html");
			}
		}
		str+="<br>]<br>";
		ctrl.loadPackages(this);
	}
	str+="\nthis.structureLoaded: "+this.structureLoaded
	+"\nthis.dataLoaded: "+this.dataLoaded
	+"\nthis.loaded: "+this.loaded;
	//alert("Page.prototype.load str: "+str.replace(/\<br\>/g, "\n"));
	//ctrl.addToLog("Page.prototype.load","controller",str);
	//debug(""
	//	+"\nPage: "+this.name
	//	+"\nthis.packagesLoaded: "+this.packagesLoaded
	//	+"\nthis.structureLoaded: "+this.structureLoaded
	//	+"\nthis.dataLoaded: "+this.dataLoaded
	//	+"\nthis.loaded: "+this.loaded
	//	,"Page.prototype.load");
	if(this.loaded)
	{
		if(this.data!=[])
		{
			ctrl.addToBuffer(this.data);
			this.data=[];
		}
		var hasPackages=(this.packages && this.packages!="" && this.packages.length>0);
		//alert("Page.prototype.load::this.params: "+this.params);
		if (hasPackages) {
			if(typeof this.params=="object" && this.params.join){
				try{
					window[this.name+"_setState"]('open',this.params);
					//eval(this.name+"_setState('open',['"+this.params.join("','")+"']);");
				}catch(e){
					//eval(this.name+"_setState('open',['"+this.params.join("','")+"']);");
					//error("object"
					//	+"\nthis.name: "+this.name
					//	+"\n"+this.name+"_setState: "+(this.name+"_setState")
					//	+"\nthis.params.join: "+this.params.join
					//	+"\neval: "+this.name+"_setState('open',['"+this.params.join("','")+"']);"
					//	+"\ne: "+_arrToStr([e], "e")
					//	,"Page.prototype.load");
					ctrl.loadPackages(this);
				}
			}else if(typeof this.params=="string"){
				try{
					eval(this.name+"_setState('open',['"+this.params.replace(/,/g,"','")+"']);");
				}catch(e){
					error("string"
						+"\nthis.name: "+this.name
						+"\neval: "+this.name+"_setState('open',['"+this.params.replace(/,/g,"','")+"']);"
						+"\ne: "+_arrToStr([e])
						,"Page.prototype.load");
				}
			}else{
				try{
					eval(this.name+"_setState('open',['"+this.params+"']);");
				}catch(e){
					error("else"
						+"\nthis.name: "+this.name
						+"\neval: "+this.name+"_setState('open',['"+this.params+"']);"
						+"\ne: "+_arrToStr([e])
						,"Page.prototype.load");
				}
			}
		} else {
			control(this.name, "response", ["ok"]);
		}
		this.params=[];
	}
}

Page.prototype.setPackagesLoaded=function(pLoaded)
{
	var i;

	//alert("_Pageset_setPackagesLoaded:\nname: "+this.name+"\npackagesLoaded: "+this.packagesLoaded+"\nstructureLoaded: "+this.structureLoaded);
	this.packagesLoaded=pLoaded;
	this.load();
	/*for(i=0;i<this.dataCalls.length;i++)
		if((this.dataCalls[i].loaded)&&(this.dataCalls[i].open)&&(this.dataCalls[i].tempRequest=="buffer"))
		{
			ctrl.doRequestTask(ps.dataCalls[i].tempLoader);
			this.dataCalls[i].tempRequest=null;
		}*/
}

Page.prototype.setStructureLoaded=function(pLoaded)
{
	this.structureLoaded=pLoaded;
	this.load();
}

/**	Batch
 *	Collections that are loading in the background - batch
 *	@param	i	ID of the collection (Buffer ID)
 *	@param	t	Transaction to fill the collection
 *	@param	tc	Object that holds conditions for the transaction
 *	@param	p	Priority the load collection
 */
function Batch(i,t,tc,p) {
	this.id=i;
	this.transaction=t;
	this.transCondition=tc;	/* Object */
	this.priority=p;
	this.loaded=false;
	this.firstTransCondition=this.transCondition;
}


function Controller()
{
	var folder="";
	var topAnchor="";
	var currPage=-1;
	/**	
	 *	hideNewPageWhileLoading is true if a page should be hidden by 
	 *	the controller whlie loading data into the very same page
	 */
	this.messages={
		carregando: "Carregando...",
		carregandoTit: "Carregando<br>",
		montaPagina: "Monta página...",
		pelaPrimeriaVez: "•&nbsp;A página pela primeira vez<br>",
		oConteudo: "•&nbsp;O conteúdo da página<br>"
	};
	this.pages=new Object();		//  PUBLIC
	this.batches=[];				//  PUBLIC
	this.windows=new Object();		//  PUBLIC
	this.urls=new Object();			//  PUBLIC
	var hideNewPageWhileLoading=true;
	var minimumPageHeight=300;
	var userOnlyRedirect="";
	var useNewRequestObj = false;
	var dataScript=null;			/* Script element used to download data in the background */
	var batchInited=false;			/* Flag set to true after first batch */
	var batchesLoaded=false;
	var firstBatchFrequence=5000;	/* After how many milliseconds the first batch should start */
	var batchFrequence=1500;		/* After how many milliseconds a new batch should start */
	var batchWorking=false;			/* True when a batch is working */
	var batchHanged=0;				/* Timer if the batches hangs */
	var batchHangedAfterTime=25000;	/* After how many milliseconds the batch is considered as hanged */
	var log=new Log();
	var activateLog=false;			/* True if log should be activated */
	var events={					/* Contains events occuring within the controller. Each event has an array of listeners. */
			onBatchesLoaded:[],		/* params: */
			onBatchLoaded:[],		/* params: batchID, batchIndex */
			onBatchFractionLoaded:[]/* params: dataLoadedInFraction */
				};

	/**
	 *	
	 */
	this.getCurrPage=function() {
		return currPage;
	}
	this.getSerializedServerObject=function(pObj) {
		if (useNewRequestObj) {
			return strObj=getRequestObject2(pObj);
		} else {
			return strObj=getRequestObject(pObj);
		}
	}

	this.setMessages=function(pMsg) {
		for (var prop in pMsg) {
			this.messages[prop]=pMsg[prop];
		}
	}
	this.setUseNewRequestObj=function(pBool) {
		useNewRequestObj = pBool;
	}
	this.setHideNewPageWhileLoading=function(bHide) {
		hideNewPageWhileLoading=bHide;
	}
	this.setMinimumPageHeight=function(h) {
		minimumPageHeight=h;
	}
	this.setActivateLog=function(bActivate) {
		activateLog=bActivate;
	}
	this.setBatchFrequence=function(bf,fbf) {
		this.batchFrequence=bf;
		this.firstBatchFrequence=(isUndefined(fbf) ? bf : fbf);
	}

	/**	
	 *	@param pTopAnchor	String with id of the top anchor element
	 */
	this.setTopAnchor=function(pTopAnchor)
	{
		this.topAnchor=pTopAnchor;
	}

	this.setUserOnlyRedirect=function(pPage)
	{
		this.userOnlyRedirect=pPage;
	}

	this.getPageset=function(pPageName)
	{
		var prop;
		for(prop in this.pages) {
			if(prop==pPageName) {
				return this.pages[prop];
			}
		}
		alert("Controller::getPageset Could not find page: "+pPageName);
		return -1;
	}

	this.isWorking=function(){
		for(var prop in this.pages)
			if(this.pages[prop].working){
				alert("working: "+prop);
				return true;
			}
		return false;
	}

	this.addToBuffer2=function(pData)
	{
	/*				type:string,		Type of item. Values: "objArr", "objObj", "string"
	 *				data:object,		Contains data (also: array, string)
	 *				bufferId:string,	Id in the Buffer
	 *				objClass:class,		Predefined class of the objects
	 *				collExists:string,	Action if the item already exists. Values: "replace", "remove", "append"
	 *				key:string			Property serving as unique key
	 */
		for(var i=0;i<pData.length;i++){
			Buffer.add(pData[i].type,pData[i].data,pData[i].collection,pData[i].objClass,pData[i].isCollection);
		}
	}
	this.addToBuffer=function(pData)
	{
		//alert(_viewObj(pData));
		for(var i=0;i<pData.length;i++){
			Buffer.add(pData[i].type,pData[i].dataString,pData[i].collection,pData[i].objClass,pData[i].isCollection);
		}
	}

	this.displayDummy=function(show) {
		var div=document.getElementById("divDummy");	/* Make sure the dummy is hidden and the page is visible */
		if(div)
			div.style.display=(show ? "block" : "none");
	}

	this.initPage=function(pParams)
	{
		if(currPage.userOnly 
				&& (!user.isUser||user.isUser==0)){		/* If the page is user only and no user login was done */
			pParams[2]=[pParams[0],pParams[1],pParams[2]];
			pParams[1]=[-1];
			pParams[0]=this.userOnlyRedirect;
			this.openPage(pParams);
			return;
		}
		document.getElementById("iLoader").style.display = "none";
		//this.addToLog("initPage","controller",pParams);
		var div;
		var newPage=(currPage.name!=pParams[0]);
		use_form=false;
		if (newPage) {									/* If the current page is different from the new */
			this.setWaitMsg(this.messages.montaPagina);			/* Show the dummy div and a message about mounting the page */
			currPage=this.getPageset(pParams[0]);
			for(prop in this.pages){
				div=document.getElementById("div"+prop);
				if(new String(div)!="null"&&currPage!=prop)
					div.style.display="none";
			}
			setTimeout('ctrl.displayDummy(false);'
						+'div=document.getElementById("div'+pParams[0]+'");'
						+'if(new String(div)!="null")'
						+	'div.style.display="block";',1);
		}else{											/* Else if the page is the same as the new */
			this.displayDummy(false);
			div=document.getElementById("div"+pParams[0]);
			if(new String(div)!="null")
				div.style.display="block";
		}
		var data=iLoader.data;
		if(currPage.packagesLoaded){				/* If the packages are loaded */
			this.addToBuffer(data);
		}else{
			currPage.data=data;
		}
		if(pParams[1]==1 && currPage!=-1){			/* If the structure was loaded */
			// Create div on demand and set height to variable: minimumPageHeight
			div=document.getElementById(currPage.container);
			if(new String(div)!="null")
				div.innerHTML=window.frames["iLoader"].document.getElementById("structure").innerHTML;
			currPage.setStructureLoaded(true);
			currPage.structureMounted=false;
		}
		if(new String(pParams[2])!="undefined"){		/* If there are page parameters */
			currPage.params=pParams[2];
		}

		if(currPage!=-1){
			var el=document.getElementById(this.topAnchor);
			if(new String(el)!="null"){
				el.scrollIntoView();
			}
			currPage.dataLoaded=true;
			currPage.load();
		}
	};

	this.initASPPage=function () {
		this.displayDummy(false);
		for(prop in this.pages){
			div=document.getElementById("div"+prop);
			if(new String(div)!="null"&&currPage!=prop)
				div.style.display="none";
		}
		var el=document.getElementById(this.topAnchor);
		if(new String(el)!="null"){
			el.scrollIntoView();
		}
		document.getElementById("iLoader").style.display = "inline";
		this.resizeILoader(self.frames["iLoader"].document);
		currPage="static";
	}

	this.resizeILoader = function(doc){
		//if (!document.all) {
		//	document.getElementById("iLoader").style.height = minimumPageHeight+"px";
		//}
		document.getElementById("iLoader").style.height = (minimumPageHeight>doc.body.scrollHeight ? minimumPageHeight : doc.body.scrollHeight)+"px";
	}


	/**	
	 *	openPage
	 *	
	 *	Mount data to be sended to the server and sends it
	 *	@param pParams:[page,[objectIDs],[pageParams]]
	 */
	this.openPage=function(pParams){
		//this.addToLog("openPage","controller",pParams);
		if(new String(pParams)=="undefined"){										/* If it is a dummy invokation */
			//error("pParams is undefined"
			//	+"\npParams: "+pParams
			//	+"\narguments.caller:\n"+arguments.caller
			//	+"\narguments.caller:\n"+_objToStr(arguments.caller)
			//	,"Controller.prototype.openPage");
			return;
		}
		this.setWaitMsg(this.messages.carregando);											/* Start open page process */
		var msg=this.messages.carregandoTit;
		var i;
		document.getElementById("iLoader").style.display = "none";
		if(this.hideNewPageWhileLoading
				|| currPage.name!=pParams[0]){									/* If a new page is opened (not the current) */
			for(prop in this.pages)													/* Hide all page divs */
				document.getElementById("div"+prop).style.display="none";
			this.displayDummy(true);
			var el=document.getElementById(this.topAnchor);
			if(new String(el)!="null"){
				el.scrollIntoView();
			}
		}
		currPage=this.getPageset(pParams[0]);
		//alert(pParams[0]+"\n"+currPage);


		var strPage=pParams[0];														/* Set request variable - page */
		if(currPage.userOnly 
				&& (!user.isUser||user.isUser==0)){									/* If the page is user only and no user login was done */
			pParams[2]=[pParams[0],pParams[1],pParams[2]];
			pParams[1]=[-1];
			pParams[0]=this.userOnlyRedirect;
			//alert(_arrToStr(pParams))
			this.openPage(pParams);
			return;
		}
		if(!currPage.packagesLoaded){											/* If packages were loaded */
			this.loadPackages(currPage);
		}

		if(!currPage.structureLoaded){											/* If structure should be loaded */
			msg+=this.messages.pelaPrimeriaVez;
			var strStruct="0";														/* Set request variable - structLoaded */
		}else 
			var strStruct="1";														/* Set request variable - structLoaded */

		/* Objects */
		if (useNewRequestObj) {
			var strObj=getRequestObject2(pParams[1]);
		} else {
			var strObj=getRequestObject(pParams[1]);
		}
		//alert(strObj);
		var strTrans=getTransactions();
		if (strTrans!="") {
			msg+=this.messages.oConteudo;
		}

		currPage.dataLoaded=false;
		if(new String(pParams[2])!="undefined"){
			/*debug("Before:"
				+"\npParams: "+pParams
				+"\npParams[2].length: "+pParams[2].length
				+"\npParams[2]: "+pParams[2]
				+"\ntypeof pParams[2]: "+typeof pParams[2]
				+"\npParams[2][0]: "+pParams[2][0]
				,"Controller.prototype.openPage");*/
			if(pParams[2].length && typeof pParams[2]=="object")
				currPage.params=pParams[2];
			else if(typeof pParams[2]=="string")
				currPage.params=[pParams[2].replace(/,/g,"','")];
			else 
				currPage.params=[pParams[2]];
			var strParams=currPage.params.join("','");							/* Set request variable - params */
		}
		var str="";
		str="Response.asp?page="+strPage+"&structLoaded="+strStruct;
		str+="&Trans="+strTrans;
		str+="&params="+strParams;
		if(!use_form && strObj.length<1500)											/* If querystring is to be used */
		{
			str+="&Objects="+strObj;
			//self.frames['iLoader'].location="";
			//self.frames['iLoader'].open();
			//if (self.frames['iLoader'].document) {
			//	self.frames['iLoader'].document.write ("<html><\/html>");
			//}
			//self.frames['iLoader'].close();
			self.frames['iLoader'].location=this.folder+str;
			//alert(this.folder+str
			//	+"\n\n"+self.frames('iLoader').location);
			//return;
		}else{																		/* Else if a form with a post method is to be used */
			self.frames['iLoader'].document.getElementById("iLoaderForm").action=str;
			self.frames['iLoader'].document.getElementById("iLoaderForm")["Objects"].value=strObj;
			self.frames['iLoader'].document.getElementById("iLoaderForm").submit();
		}

		this.setWaitMsg(msg);														/* Notify user about the loading process */
	}

	/**	Controller.prototype.getRequestObject PRIVATE
	 *	
	 *	Returns a string containing the request objects
	 *	@param pObjects	Objects containing data to be sent to the server
	 */
	var getRequestObject=function(pObjects){
		var strObj="";																/* Set request variable - Objects */
		if(0<currPage.ssObjects.length)
		{
			for(i=0;i<currPage.ssObjects.length;i++){							/* Use Parser.getSerialized(pArray) to convert an array of objects to string */
				/*debug("Before:"
					+"\npParams: "+pParams
					+"\npParams[0]: "+pParams[0]
					+"\npParams[0][0]: "+pParams[0][0]
					+"\npParams[1]: "+pParams[1]
					+"\ntypeof pParams[1]: "+(typeof pParams[1])
					+"\npParams[1].length: "+pParams[1].length
					+"\npParams[1][0]: "+pParams[1][0]
					+"\npParams[2]: "+pParams[2]
					,"Controller.prototype.openPage");*/
				if((pObjects.length==currPage.ssObjects.length)
						&&(pObjects.length!=0)
						&&(typeof pObjects=="object") 
						&& (pObjects[0]!=-1) && (pObjects[0]!="")) {			/* If params is an array with the same length as the objects, set params for each object */
					if(new String(pObjects[i]).indexOf("[[")==-1 					/* If pObjects misses brackets or is a number */
							|| !isNaN(pObjects[i])){
						pObjects[i]="[['"+pObjects.join("','")+"']]";			/* Surround simple values with [[ value ]] to serialize an object */
					}
					currPage.ssObjects[i].params=pObjects[i];	
				} else if(pObjects.length!=0) {									/* Otherwise use same params for all objects */
					if((new String(pObjects).indexOf("[[")==-1) 
							&& (typeof pObjects=="object")) {						/* If pObjects misses brackets and is an array */
						pObjects="[['"+pObjects.join("','")+"']]";				/* Surround simple values with [[ value ]] to serialize an object */
					} else if ((new String(pObjects).indexOf("[[")==-1) 
							&& (typeof pObjects=="string")) {						/* Else if pObjects misses brackets and is a string */
						pObjects="[['"+pObjects.replace(/,/g,"\',\'")+"']]";	/* Surround simple values with [[ value ]] to serialize an object */
					} else if ((new String(pObjects).indexOf("[[")==-1) 
							|| (!isNaN(pObjects))) {								/* Else if pObjects misses brackets or is a number */
						pObjects="[['"+pObjects+"']]";							/* Surround simple values with [[ value ]] to serialize an object */
					}
					
					currPage.ssObjects[i].params=pObjects;
				}else{
					pObjects="[[]]";												/* Surround simple values with [[ value ]] to serialize an object */
					currPage.ssObjects[i].params=pObjects;
				}
				strObj+="["+currPage.ssObjects[i].name+","+currPage.ssObjects[i].params+"],";
			}
			if(strObj.charAt(strObj.length-1)==",")
				strObj=strObj.slice(0,strObj.length-1);
		}
		return strObj;
	}

	/**	Controller.prototype.getRequestObject v.2 PRIVATE
	 *	
	 *	Returns a string containing the request objects
	 *	@param pObjects	Objects containing data to be sent to the server
	 */
	var getRequestObject2=function(pObjects){
		var str="";
		if (typeof pObjects=="object" && typeof pObjects.length == "undefined") {
			//alert();
			pObjects=[pObjects];
		}
		if(0<pObjects.length){
			for (var i=0;i<pObjects.length;i++) {
				if (typeof pObjects[i]!="object") {
					error("Item "+i+"; "+pObjects[i]+" is not an object."
						+"\nctrl.currPage.name: "+currPage.name
						,"Controller.prototype.getRequestObject");
				}

				/* If not an array put this object into one */
				if (typeof pObjects[i]=="object" && typeof pObjects[i].length == "undefined") {
					pObjects[i] = [pObjects[i]];
				}
				constr=Object.getConstructorName(pObjects[i][0]);
				//var ind=currPage.getRequestDataIndex(constr);
				//if (ind!=-1) {
				//	str=currPage.requestData[ind].getSerialized(pObjects[i]);
				//}else {
					str+="[\""+constr+"\","+Parser.getSerializedObjectLiteral(pObjects[i])+"]";
				//}
				if (i<pObjects.length-1) {
					str+=",";
				}
			}
		}
		return str;
	}

	/**	Controller.prototype.getTransactions PRIVATE
	 *	
	 *	Returns a string containing the transactions to be performed
	 */
	var getTransactions=function(){
		var strTrans="";											/* Set request variable - Trans */
		if(0<currPage.ssTrans.length){
			for(i=0;i<currPage.ssTrans.length;i++){
				if(eval(currPage.ssTrans[i].condition) 
						&& (Buffer.getRefByCollection(currPage.ssTrans[i].bufferId)==-1
							|| currPage.ssTrans[i].overWrite))	/* If the transaction condition is true and collection not loaded */
					strTrans+=currPage.ssTrans[i].trans+",";	/*  or the collection should be refreshed */
			}
			if(strTrans.charAt(strTrans.length-1)==",")
				strTrans=strTrans.slice(0,strTrans.length-1);
		}
		//alert("getTransactions: "+strTrans);
		return strTrans;
	}

	this.showServerResponse=function(){
		if(document.getElementById('iLoader').style.display=='block'){
			document.getElementById('iLoader').style.display='none';
		}else{
			document.getElementById('iLoader').style.display='block';
		}
		window.resizeBy(0,1);
		window.resizeBy(0,-1);
		//setTimeout("document.body.fireEvent('onResize');",10);
	}

	this.showPrinter=function(){
		if(document.getElementById('iPrinter').style.display=='block'){
			document.getElementById('iPrinter').style.display='none';
		}else{
			document.getElementById('iPrinter').style.display='block';
		}
		window.resizeBy(0,1);
		window.resizeBy(0,-1);
		//setTimeout("document.body.fireEvent('onResize');",10);
	}

	this.showLog=function(pCont){
		if (pCont.style.display=='block') {
			pCont.style.display='none';
		}else {
			log.sortBy('time',false);
			log.printLog(pCont,true);
			pCont.style.display='block';
		}
	}

	this.addToLog=function(pLink,pPage,pDebug){
		if (activateLog) {
			log.addItem(pLink,pPage,pDebug);
		}
	}

	this.addEventListener=function(pEvent,pHandler){
		return events[pEvent].push(pHandler);
	}

	this.removeEventListener=function(pEvent,pIndex){
		return events[pEvent].splice(pIndex,1);
	}

	/**	Controller.prototype.loadData PRIVATE
	 *	Loads data using a script-tag
	 *	Uses getRequestData and getTransactions
	 *	@param	pTrans		Transaction to be executed
	 *	@param	pObjects	Specifies the objects
	 */
	this.loadData=function(pTrans,pObjects){
		this.addToLog("loadData","controller","dataScript: "+dataScript+", this.batchesLoaded: "+this.batchesLoaded+", this.batchWorking: "+this.batchWorking);
		if (dataScript) {
			return;
		}
		//alert(""
		//	+"\npObjects: "+_viewObj(pObjects)
		//	+"\ngetRequestObject(pObjects): "+getRequestObject2(pObjects)
		//	);
		str="Data.asp?Trans="+pTrans;
		str+="&Objects="+getRequestObject2(pObjects);
		dataScript = document.createElement('script');
		//debug("this.folder+str: "+this.folder+str
		//	,"Controller.prototype.loadData");
		if (false) {
			iLoader.location=this.folder+str;
		}else {
			dataScript.src = this.folder+str;
			dataScript.type = 'text/javascript';
			document.getElementsByTagName('head')[0].appendChild(dataScript);
			this.addToLog("loadData","batch url",this.folder+str);

			// Enables the batch to continue after packet loss.
			var batchHanged=setTimeout("ctrl.batchWorking=false;ctrl.removeDataScript();ctrl.startBatch();",batchHangedAfterTime);
		}
	}

	/**	Controller.prototype.initData 
	 *	
	 *	Append the loaded data to the Buffer
	 */
	this.initData=function(pData){
		this.addToLog("initData","controller","pData: "+pData+", this.batchesLoaded: "+this.batchesLoaded);
		this.addToBuffer(pData);
		if (this.batchesLoaded){
			var data=Buffer.getRefByCollection("Ingredients")
			//alert(_arrToStr(data));
		}
		setTimeout('ctrl.dataLoaded()',50);
		return;
	}

	/**	Controller.prototype.dataLoaded
	 *	Removes the data scripttag, and put the the dataloader on idlemode
	 */
	this.dataLoaded=function(){
		this.addToLog("dataLoaded","controller","this.batchWorking: "+this.batchWorking+", this.batchesLoaded: "+this.batchesLoaded);
		this.removeDataScript();
		if (!this.batchesLoaded) {
			this.startBatch();
		}
		return;
	}

	this.removeDataScript=function() {
		if (dataScript) {
			document.getElementsByTagName('head')[0].removeChild(dataScript);
			dataScript = null;
		}
	}

	var killBatchHanged=function () {
		if (batchHanged) {
			clearTimeout(batchHanged);
			batchHanged=0;
		}
	};

	/**	Controller.prototype.setBatchLoaded
	 *	Set the stated batch to loaded
	 */
	this.setBatchLoaded=function(pId,pIsIndex){
		var listeners=events.onBatchLoaded;
		function fireEvent(pCtrl,pId,pIndex) {
			if (listeners.length>0) {
				var i=listeners.length-1;
				do {
					if (typeof(listeners[i]) == "function") {
						listeners[i](pId,pIndex);
					}
				} while (0>i--);
			}
		}
		if (pIsIndex) {
			this.batches[pId].loaded=true;
			fireEvent(this,this.batches[pId].id,pId);
			return true;
		}
		for (var i=0;i<this.batches.length;i++) {
			if (this.batches[i].id==pId) {
				this.batches[i].loaded=true;
				fireEvent(this,pId,i);
				return true;
			}
		}
		return false;
	}

	/**	Controller.prototype.getBatchIndex
	 *	Returns the index of the wanted batch
	 */
	this.getBatchIndex=function(pId){
		var i=0;
		if (0<this.batches.length)
			do {
				if (this.batches[i].id==pId)
					return i;
			} while (this.batches.length>++i);
		return -1;
	}

	/**	Controller.prototype.sortBatches
	 *	Sorts batches by priority
	 */
	this.sortBatches=function(){
		this.batches.propSort("priority");
	}

	this.unloadBatch=function(id) {
		for (var i=0;i<this.batches.length;i++) {
			if (this.batches[i].id==id) {
				Buffer.removeCollection(id);
				this.batches[i].loaded=false;
				this.batches[i].transCondition=this.batches[i].firstTransCondition;

				this.batchesLoaded=false;
			}
		}
	}

	/**	Controller.prototype.startBatches
	 *	Starts a new Batch
	 */
	this.startBatch=function(){
		killBatchHanged();
		//debug(""
		//	+"\nthis.batchWorking: "+this.batchWorking
		//	+"\ndataScript: "+dataScript
		//	+"\nthis.isWorking(): "+this.isWorking()
		//	+"\n(this.batchWorking || dataScript!=null || this.isWorking()): "+(this.batchWorking || dataScript!=null || this.isWorking())
		//	,"Controller.prototype.startBatch");
		this.addToLog("startBatch","controller","this.batchWorking: "+this.batchWorking+", dataScript: "+dataScript);
		if (this.batchWorking || dataScript!=null || this.isWorking()) {
			if (this.isWorking()) {
				clearTimeout(batchQueue);
				batchQueue=setTimeout("ctrl.startBatch();",200);
			}
			//debug("return false"
			//	+"\nthis.batchWorking: "+this.batchWorking
			//	+"\ndataScript: "+dataScript
			//	+"\nthis.isWorking(): "+this.isWorking()
			//	,"Controller.prototype.startBatch");
			return;
		}
		this.batchWorking=true;
		if (!this.batchesLoaded) {
			var i=-1;
			do {
				i++;
				//debug(""
				//	+"\nthis.batches["+i+"].transCondition: "+_arrToStr(this.batches[i].transCondition)
				//	,"Controller.prototype.startBatch");
				if (!this.batches[i].loaded) {
					if (!this.batchInited) {
						setTimeout("ctrl.loadData(ctrl.batches["+i+"].transaction,ctrl.batches["+i+"].transCondition);",this.firstBatchFrequence);
						this.batchInited=true;
					}else{
						setTimeout("ctrl.loadData(ctrl.batches["+i+"].transaction,ctrl.batches["+i+"].transCondition);",this.batchFrequence);
					}
					break;
				}
				if (this.batches[i].loaded && this.batches.length>i+1) {
					this.batchesLoaded=true;
				}
			} while (this.batches[i].loaded && this.batches.length>i+1);
		}
	}

	/**	Controller.prototype.startBatches
	 *	Starts a new Batch
	 *	@param	pParams	{data:[object],transCondition:[object]});
	 */
	this.batchFractionLoaded=function(pParams){
		killBatchHanged();
		this.batchWorking=false;
		var bufferId="collection";
		var data="dataString";
		var ind=this.getBatchIndex(pParams.data[0][bufferId]);
		//debug(""
		//	+"\npParams.data[0][bufferId]: "+pParams.data[0][bufferId]
		//	+"\nind: "+ind
		//	+"\npParams.transCondition.greaterThan: "+pParams.transCondition.greaterThan
		//	,"Controller.prototype.batchFractionLoaded");
		this.addToLog("batchFractionLoaded","controller","this.batchWorking: "+this.batchWorking+", pParams.data[0].collection: "+pParams.data[0].collection);
		this.batches[ind].transCondition=pParams.transCondition;
		this.initData(pParams.data);
		for (var i=0;i<events.onBatchFractionLoaded.length;i++) {
			//alert("batchFractionLoaded\nevent: "+events.onBatchFractionLoaded[i]);
			events.onBatchFractionLoaded[i](pParams.data[0].dataString);	/* Fire onBatchFractionLoaded */
		}
		if (this.batches[ind].transCondition.top > pParams.data[0][data].length) {
			this.setBatchLoaded(ind,true);
			this.batches[ind].loaded=true;
			if (ind == this.batches.length-1) {
				batchesLoaded=true;
				for (var i=0;i<events.onBatchesLoaded.length;i++) {			/* Fire onBatchesLoaded */
					events.onBatchesLoaded[i]();
				}
				//alert("Batch loaded!");
			}
		}
		//debug(""
		//	+"\npParams.data: "+pParams.data
		//	+"\npParams.data[0]."+bufferId+": "+pParams.data[0][bufferId]
		//	+"\nthis.batches["+ind+"].transCondition.top > pParams.data[0]."+data+".length: "+this.batches[ind].transCondition.top+" > "+pParams.data[0][data].length
		//	+"\npParams.transCondition: "+_arrToStr(pParams.transCondition)
		//	+"\nthis.batchesLoaded: "+this.batchesLoaded
		//	,"Controller.prototype.batchFractionLoaded");
		try {
		} catch (e) {
			error("Something went wrong when trying to read the batch collection"
				+"\n- Does this batch exist? - "+pParams.data[0][bufferId]
				//+"\nError: "+_arrToStr(e)
				,"Controller.prototype.batchFractionLoaded")
		}
	}

	this.release=function(){
	}

	this.getUrl=function(pUrl,pId)
	{
		var i,url=new String(pUrl);
		if(url.indexOf(".")==-1)		// If it's a reference to the urls collection
			url=this.urls[url];
		if(new String(pId)=="undefined")
			pId="";
		if(typeof pId=="object")		// If it's an array
		{
			for(i=0;i<pId.length;i++)
				if(isNaN(pId[i]))		// If item is a string
					pId[i]="'"+pId[i]+"'";
			pId=pId.join(",");
		}
		pId=new String(pId);
		if(pId.indexOf("[[")==-1)		// If id doesn't contain brackets
			pId="[["+pId+"]]";
		//debug(
		//	"\npUrl: "+pUrl
		//	+"\nurl: "+url
		//	+"\npId: "+pId
		//	+"\nurl.replace(/<>/, pId): "+url.replace(/<>/, pId)
		//	,"Controller.prototype.getUrl");
		return url.replace(/<>/, pId);	// Add id to url
	}

	this.openWin=function(pWin, pId)
	{
		var h,w,f=this.windows[pWin].feats.split(",");
		for (var i=0;i<f.length;i++) {
			f[i]=f[i].split("=");
			if (f[i][0]=="height") {
				h=f[i][1];
			}else if (f[i][0]=="width") {
				w=f[i][1];
			}
		}
		var t=Screen.getCentralizedTop(h);
		var l=Screen.getCentralizedTop(w);
		var url=this.getUrl(this.windows[pWin].url,pId);
		this.open=true;
		self.open(url,this.windows[pWin].name,this.windows[pWin].feats+",left="+l+",top="+t);
		//return this.winRef;
	}

	this.closeWins=function()
	{
		//var prop;
		//for(prop in this.windows)
		//{
		//	alert("this.windows["+prop+"].winRef: "+this.windows[prop].winRef);
		//	if(isDefined(this.windows[prop].winRef))
		//		this.windows[prop].winRef.close();
		//}
	}


	/**	setPSPackages
	 *	
	 *	1.	pPageset is a reference to the pageset instance
	 *		pLoaded is a boolean, true if the packages are loaded
	 */
	this.setPSPackages=function(pPageset,pLoaded)
	{
		try {
			pPageset.setPackagesLoaded(pLoaded);
		} catch (e) {
			//error("pPageset: "+pPageset
			//	,"ctrl.setPSPackages");
		}
	}

	/**	loadPackages
	 *	
	 *	Is invoked when the frame of the pageset is to be loaded
	 *	If there are no packages in the current pageset - set packages to loaded
	 */
	this.loadPackages=function(pPageset)
	{
		//debug(""
		//	+"\npPageset.name: "+pPageset.name
		//	+"\npPageset.packages: "+pPageset.packages
		//	,"_Controller_loadPackages");
		//alert(pPageset);
		if(pPageset.packages && (pPageset.packages!="")&&(pPageset.packages.length>0))
		{
			c.loadPackages(pPageset,pPageset.packages);
		}else{
			this.setPSPackages(pPageset, true);
		}
	}


	this.loadPrinter=function(pParams){
		var url="wPrinter.asp?Objects="+pParams[0]+"&Trans="+pParams[1];
		open(url);
		//self.frames("iPrinter").location=url;
	}

	/**	setPrint
	 *	
	 *	Deprecated - use doPrint
	 */
	this.setPrint=function(pStr)
	{
		this.doPrint(pStr);
	}

	/**	doPrint
	 *	
	 *	1.	Prepare to print using the iPrinter frame
	 */
	this.doPrint=function(pStr)
	{
		self.frames("iPrinter").printHTML(pStr);
		//self.frames("iPrinter").divContainer.innerHTML=pStr;
		//self.frames("iPrinter").print();
	}

}


Controller.prototype=new Page();
