function clsEMLib(objTop)
{
	using("helperLib")
	using("XMLLib")
	var bDologinActive  = false;
	var top             = window.top
	if(objTop != undefined)
	{
		top = objTop;
	}
	
	var objWin ;
	initWindow();
	
	//callable functions
    this.wsfMapPath         = wsfMapPath;
	this.doLogin            = doLogin;
	this.sessionExpired     = _sessionExpired;
	this.readUserProfile    = readUserProfile;
	
	this.login = login;
	this.initialiseDBData   = initialiseDBData;
	
	//privelege check on record
    this.returnObjectStatus = _returnObjectStatusFromPermissions;
	
	//fetch object properties
	this.getObjectBFU       = _getObjectBFU;
	this.getObjectDefaultImage = _getObjectDefaultImage;
	this.getObjectDef       = _getObjectDefFromBrokerId;
	this.getObjectName      = _getObjectNameFromBfu;
	this.getBrokerID        = _getBrokerIdFromBfu;
	this.isPluginActive     = _isPluginActive
	
	//general utility functions
	this.escapeSpecialChars = escapeSpecialChars;
	this.GetApplicationID   = GetApplicationID;

    //combo related
	this.GetSourceCombo     = _getSourceCombo;
	this.linkObject         = linkObject;
	this.getDirectCombo     = _getDirectCombo;
	this.populateCombos     = _populateCombos;
	this.reloadCombo        = _reloadCombo;
	
	
	this.deserialise        = deserialise;
	this.getEnvironData     = getEnvironData;
	
	this.getTopWCT          = _getTopWCT;
	
	this.openObject         = openObject;
	this.openForm           = openForm;         //to be used from external application placing the form on their web page. This will do the necessary initialisations before calling the openobejct.
	
	this.resetWindowRef     = resetWindowRef;
	this.getLookupResult    = _getLookupResult;

	//objects definitions
	this.clsMainContext     = clsMainContext;   //used as top.context
	this.clsCombos          = clsCombos;        //used as top.context.combos
	this.clsObjectsCreated  = clsObjectsCreated; 
	this.clsWCT             = clsWCT;           //used as top.wct
	this.clsObjectLookup    = clsObjectLookup;
	this.clsDeserialise     = clsDeserialise;
	
	
	
	//moved to chartlib.js
	//this.clsChart = clsChart
	
	this.loadObjectHeader   = loadObjectHeader;
	this.loadObjectInstance = loadObjectInstance;
	this.loadObjectInstanceFromXml = loadObjectInstanceFromXml;
	this.InitDependentLists = _initDependentLists;
	this.ProcessDynamicList = _processDynamicList;
	this.prepareWCTForChild = prepareWCTForChild;
	
	
	this.initOnBrowseSections = _initOnBrowseSections;


	this.updatePropertyValue    = _updatePropertyValue;
	this.getPropertyValue       = _getPropertyValue;
	this.updateChild            = _updateChild
	this.processBusinessRule    = rts_processBusinessRule
	this.fetchEntityRecords     = _fetchEntityRecords
	var propertyCollection  = new Array()
	
	function _getObjectDefaultImage(uniqueid, attachments, placeholderSrc)
	{
	    var returnValue = placeholderSrc
	    if(attachments != null && attachments.toLowerCase().indexOf("sysdefaultimage.") >= 0)
        {
            returnValue = attachments.split(";");
            for(var i = 0; i< returnValue.length; i++)
            {
                if(returnValue[i].toLowerCase().indexOf("sysdefaultimage.") == 0)
                {
                    returnValue = top.helperLib.wsfMapPath("$application/attachments/" + uniqueid + "/" + returnValue[i])
                    break;
                }
            }
        }
        
        return returnValue;        
	}
	
    function _fetchEntityRecords (callback, entityName, columnlist, whereClause, pageSize, pageNumber, sort)
    {
        var me = this;
        this.cb = callback;
        
        if(pageSize != null)
        {
            pageSize = "<pagesize>" + pageSize + "</pagesize><currentpagesize>" + pageSize + "</currentpagesize>"
        }
        else
        {
            pageSize = ""
        }
        
        
        if(pageNumber != null)
        {
            pageNumber = "<currentpage>" + pageNumber + "</currentpage>"
        }
        else
        {
            pageNumber = ""
        }
        
        var tableName = entityName.indexOf("te_") == 0?entityName:"te_" + entityName
        
        if(sort != null)
        {
            var sortArray = sort.split(",");
            sort = "";
            for(var i = 0 ; i < sortArray.length; i++)
            {
                if(sortArray[i].length > 0)
                {
                    if(sortArray[i].indexOf(".") == -1)
                    {
                        sortArray[i] = tableName + "." + sortArray[i]
                    }
                    
                    sort += "<sortfield sortorder='1' sortmode='asc' >" + sortArray[i] + "</sortfield>"
                }
            }
            sort = "<sort>" + sort + "</sort>";
        }
        else
        {
            sort = "<sort><sortfield sortorder='1' sortmode='desc' >" + tableName + ".sys_datetimechange</sortfield></sort>";
        }
        
        
        
        var sXML = "<document><record><tablename>" + tableName + "</tablename><columns>" + columnlist + "," + tableName + ".UniqueID</columns><def>" + pageSize + pageNumber + "<where>" + (whereClause==null?"":whereClause) + "</where>" + sort + "</def></record></document>"
        result = top.helperLib.processSoapRequestAsync(window , _callback, top.helperLib.wsfMapPath("/webservices/wf.object/object.asmx"),"wf.object","FetchSearchDetails", "sXML", "<![CDATA[" + sXML + "]]>")
    	
        function _callback(result)
        {
            if(result == null) return ""

            var response = top.XMLLib.getNodeText(result, "//FetchSearchDetailsResult")        
            var re = /%26/g
            response = response.replace(re ,"&")
    	
	        try{me.cb(response)}catch(e){};
	        me.cb = null;
        }
        
    }	
	
	function _getTopWCT(oWindow)
	{
	    if(oWindow == null) return null;
	    for(var i = 0; i < 10; i++)
	    {
	        if(oWindow.location.href.indexOf("wct.htm") >= 0)
	        {
	            return oWindow.wct;
	        }
	        oWindow = oWindow.parent;
	        if(oWindow == null) return;
	    }
	}
	
	function _getPropertyValue(sPage,objCallBack)
	{

		if(top.context.cache[sPage] != null)
		{
			try{objCallBack(top.context.cache[sPage])}catch(e){}
			return;
		} 
		sXML = "<document><record><objectHeader.objectName>sysProperties</objectHeader.objectName><WF1page>" + sPage + "</WF1page></record></document>"
		var iIndex = top.helperLib.processSoapRequestAsync(null, _gotSysProperty, wsfMapPath("/webservices/wf.object/businessrules.asmx"),"wf.object","processbusinessrule", "sBusinessRuleName","get system property", "sXML", "<![CDATA[" + sXML + "]]>")
		
		propertyCollection[iIndex] = new Object();
		propertyCollection[iIndex].page = sPage;
		propertyCollection[iIndex].callBack= objCallBack;
		return iIndex;
	}

	function rts_processBusinessRule(ruleName, sXML, async, callback)
	{
	    var _callback = callback
	    if(async == null)
	    {
	        async = false;
	    }
	    
	    if(async == true)
	    {
	        top.helperLib.processSoapRequestAsync(window, processResult, top.helperLib.wsfMapPath("/webservices/wf.object/businessrules.asmx"), "wf.object", "processbusinessrule", "sBusinessRuleName", ruleName , "sXML", "<![CDATA[" + sXML + "]]>")
	    }
	    else
	    {
	        var result =  top.helperLib.processSoapRequest(null, wsfMapPath("/webservices/wf.object/BusinessRules.asmx"),"wf.object","processbusinessrule","sBusinessRuleName", ruleName, "sXML","<![CDATA[" + sXML +"]]>")    
	        return processResult(result)
	    }
	    
	    function processResult(response)
	    {
		    if (response == null) 
		    {
		        return ""
	        }
	        
	        var sProcessBusinessRuleResult = top.XMLLib.getNodeText(response, "//processbusinessruleResult")

			var re = /%26/g
			sProcessBusinessRuleResult = sProcessBusinessRuleResult.replace(re ,"&")
	        
	        if(_callback != null)
	        {
	        
	            _callback(sProcessBusinessRuleResult);
	        }
	        else
	        {
	            return sProcessBusinessRuleResult    
	        }
	    }
		
	}

    var cb_updateChild_response;

    function _cb_updateChild(result)
    {
        var returnValue = "";
        if (result != null)
        {
            var sCommitResult = top.XMLLib.getNodeText(result, "//commitResult");
		    if(sCommitResult.indexOf("<objectHeader.Locked>") == 0)
		    {
			    sCommitResult="<document>" + sCommitResult + "</document>"
		    }
    		
		    var sLocked = top.XMLLib.getNodeText(sCommitResult,"/document/objectHeader.Locked")
    		
		    if(sLocked != null && sLocked.length > 0)
		    {
 			    if(confirm("Details are modified by \"" + top.XMLLib.getNodeText(sCommitResult,"/document/objectHeader.LockedbyUser") + "\" at " +  sLocked.split("T")[1] + " on " + sLocked.split("T")[0] + ". \nDo you want to overwrite?") == false ) return "" ;
			    var objXML = top.XMLLib.objXMLDocTemplate.cloneNode(true)
			    objXML.async = false
			    objXML.loadXML(scrXML)	
			    try
			    {
			        objXML.selectSingleNode("/document/record/sys_datetimechange").text=top.XMLLib.getNodeText(sCommitResult,"//objectHeader.Locked")
			    }catch(e){}
			    var sReturn = _updateChild(objXML.xml);
			    returnValue = sReturn;
		    }	
		    else
		    {
			    returnValue = sCommitResult
		    }  

        }		
        
        try
        {
            cb_updateChild_response(returnValue)
        }catch(e){}
        cb_updateChild_response = null;		     
    }

    function _updateChild(scrXML, cb)
	{
	    cb_updateChild_response = cb;
		var result =  top.helperLib.processSoapRequestAsync(null, _cb_updateChild, wsfMapPath("/webservices/wf.object/object.asmx"), "wf.object" , "commit", "sXML", "<![CDATA[" + scrXML +"]]>");
		
		

		
	}	

	function _gotSysProperty(result,iIndex)
	{
		if(result == null) return;
		var sFunctionResponse = top.XMLLib.getNodeText(result,"//processbusinessruleResult");
		var objPage = top.context.cache[propertyCollection[iIndex].page];
		
		if(objPage == null)
		{
			objPage = new Object();
			objPage.personalisationXML = sFunctionResponse;
			top.context.cache[propertyCollection[iIndex].page] = objPage;
		}
		
		try{propertyCollection[iIndex].callBack(objPage)}catch(e){}
		propertyCollection[iIndex].callBack = null
		propertyCollection[iIndex] = null
	}
	
	
	function _updatePropertyValue(sProperty,sVal,sPage,objWindow,bForceServerUpdate)
	{
	
		var sCacheKey = sPage
		var objPage = top.context.cache[sCacheKey]
		if(objPage != null)
		{
			var sOldValue = top.XMLLib.getNodeText(objPage.personalisationXML,"//record[P='" + sProperty + "']/V")
			if(sOldValue == sVal.toString() && bForceServerUpdate != true)
			{
				return
			}
		}
		
		var sXML = "<document><record><objectHeader.objectName>sysProperties</objectHeader.objectName><WF1page>" + sPage + "</WF1page><WF1property>" + sProperty + "</WF1property><WF1val>" + sVal + "</WF1val></record></document>"
		var result = top.helperLib.processSoapRequestAsync(objWindow,null,wsfMapPath("/webservices/wf.object/businessrules.asmx"),"wf.object","processbusinessrule", "sBusinessRuleName","update system property", "sXML", "<![CDATA[" + sXML + "]]>")
		
		if(objPage == null)
		{
			objPage = new Object();
			top.context.cache[sCacheKey] = objPage;
			objPage.personalisationXML = "<document><record><P>" + sProperty +"</P><V>" + sVal + "</V></record></document>";
		}
		else
		{
			objPage.personalisationXML = top.XMLLib.setNodeText(objPage.personalisationXML,"//record[P='" + sProperty + "']/V",sVal.toString())
		}
	}

    //*************************************
    //  COMBO RELATED FUNCTIONS
    //*************************************
    
    //function to apply filter to dependent.
	function _getDirectCombo(objLinkTo, sFieldPrefix, objWindow, objSelectField)
	{
		var sSelect = _getSourceCombo(objSelectField, false, objWindow)
		
		if(objLinkTo.dependency == null)
		{
			objLinkTo.dependency = ""
		}
		
		var sOptions = sSelect;
		var source = objSelectField.getAttribute("source");
		if(source.indexOf("businessrule.") != 0)
		{
		    var arrDependencies = objLinkTo.dependency.split(",");
		    var sWhereClause = "";
		    //build where clause for all related values
		    for(var j = 0; j < arrDependencies.length; j++)
		    {
			    var arrLinktoId = arrDependencies[j].split("-");
			    objTemp = objWindow.document.getElementById(sFieldPrefix + arrLinktoId[0]);
			    if(objTemp == null)
			    {
			        break;
			    }
			    //if(objTemp.value=="") break;
			    if(arrLinktoId.length == 2)
			    {
				    sTempLinkto = arrLinktoId[1];
		        }
			    else
			    {
				    sTempLinkto = arrLinktoId[0];
			    }
			    //var sTempLinkto = arrDependencies[j]
			    if (sTempLinkto.indexOf(".") >= 0 )
			    {
				    var sTmpValue = sTempLinkto.split('.')[1];
				    sTempLinkto = sTmpValue;
			    }
			    sWhereClause += "and @" + sTempLinkto + "='" + objTemp.value  + "' " ;
		    }
		    sWhereClause = sWhereClause.substring(4);
    		
		    var objXML = top.XMLLib.objXMLDocTemplate.cloneNode(true);
		    objXML.loadXML(sSelect);
		    if(sWhereClause != "")
		    {
			    sWhereClause="[" + sWhereClause + "]";
		    }
		    var objOptions = objXML.selectNodes("//option" + sWhereClause );
		    
		    for(var i = 0; i < objOptions.length; i++)
		    {
			    sOptions += objOptions[i].xml;
		    }
		    sOptions = "<select>" + sOptions + "</select>";
		}
		
		
		

		var evt = new Object();
		evt.options = sOptions;
		evt.controlid = objSelectField.id;
		if(objWindow != null && objWindow.runtimeRef != null)
		{
			objWindow.runtimeRef.raiseEvent("onbeforecomboreload", evt);
		}
		sOptions = evt.options;

		return sOptions;
	}
	
	//function called ususally by runtime when the value of a single input changes to check for any dependent combos.
	function _processDynamicList(objWindow, inputCollection, sourceInput, sFieldPrefix, objSource)
	{
		var objTemp,objInput
		//get all the fields linked to this objec
		var sSourceId = sourceInput.id;
		
		if(sFieldPrefix != "")
		{
			sSourceId = sSourceId.substring(sFieldPrefix.length);
		}
		
		for (var sID in inputCollection)
		{
			var input = inputCollection[sID].fieldRef;
			
			if(input == null)
			{
				input = inputCollection[sID].m_element ;
			}
			
			if(input.getAttribute("type") == "Select" && input.getAttribute("i_multisel") != "3")
			{
				var linkToSettings = new linkObject(input.getAttribute("linkto"));			
				
				if(linkToSettings.dependency == null) 
				{
				    continue;
				}
				
				if(linkToSettings.dependency.indexOf(sSourceId) == -1)	
				{
				    continue;
				}
				
				var sResponse
				if(sourceInput.getAttribute("value") == "")
				{
					sResponse ="<select/>";
			    }
				else	
				{
					sResponse = _getDirectCombo(linkToSettings, sFieldPrefix, objWindow, input);
				}

				input.reload(sResponse)

				if(objSource!=null)
				{
					var evt = new Object();
					evt.controlid = sID;
					try{objSource.raiseEvent("onaftercomboreload",evt);}catch(e){}
				}
			}
		}					
	}
	
	function linkObject(sLink)
	{
		if(sLink == null || sLink == "" || sLink == "null") 
		{
		    return;
        }
		var arrLinkTo = sLink.split(";");
		for(var i=0 ; i <arrLinkTo.length ; i++)
		{
			var arrNameValuePair = arrLinkTo[i].split(":");
			eval("this." + arrNameValuePair[0].toLowerCase() + " = arrNameValuePair[1]")
		}
		
		if(this.display == null)
		{
			this.display = this.value;
		}
	}
	
	function _initOnBrowseSections(inputObjects, functionPtr)
	{
		try
		{
			for (var sID in inputObjects)
			{
			    var objField = inputObjects[sID].fieldRef;
    			
			    if( objField == null)
			    {
				    objField = inputObjects[sID].m_element;
			    }
				
				if(objField.getAttribute("type") != "Text")
				{
					continue
				}
				
				
				var fieldSource = 	objField.getAttribute("source");
				
				if(fieldSource != null && fieldSource.toLowerCase().indexOf("tapplicationlist.") == 0 && (objField._browse == true || objField._browseReadonly == true))
				{
                    
					objField.attachEvents("onbrowsenew",functionPtr)
				}
			}
		}
		catch(e){}
	}
	
	
	function _initDependentLists(objWindow, inputObjects, functionPtr, sFieldPrefix)
	{
		var arrInit =new Array()
		
		for (var sID in inputObjects)
		{
			var objField = inputObjects[sID].fieldRef;
			
			if( objField == null)
			{
				objField = inputObjects[sID].m_element;
			}
			

			if(objField.getAttribute("type") != "Select") continue;

			var objLinkTo = new linkObject(objField.getAttribute("linkto"))
			
			if(objLinkTo.dependency == null) continue;
			
			var arrLinkTo = objLinkTo.dependency.split(",");
			
			for(var j = 0 ; j < arrLinkTo.length; j++)
			{
				if (arrInit[arrLinkTo[j]] != null)
				{
					continue
				}
				
				var arrId = arrLinkTo[j].split("-");
				var objControl = objWindow.document.getElementById(sFieldPrefix + arrId[0]);

				if (objControl == null)
				{
					continue;
				}
				
				//var sEval = "objControl.setAttribute('onchange',function(){getDynamicList(this)})"; 
				var sEval = "objControl.attachEvents('onchange', functionPtr)" 
				
				arrInit[arrId[0]] = true;
				eval(sEval)
			}
		}
	}
	
	//called for initial population of all combos on the runtime pages
	//caller points to runtime or the class that makes this call so that an event can be raised through it.
	function _populateCombos(inputCollection, caller)
	{
		for (var sID in inputCollection)
		{
		
			var input = inputCollection[sID].m_element; 
			if(input == null)
			{
			    input = inputCollection[sID].fieldRef; 
			}
			
			if(input.getAttribute("type") == "Select" && input.getAttribute("source") != "" && input.getAttribute("source") != null && input.getAttribute("i_multisel") != '3')	
			{
			
				if(input.getAttribute("linkto") != null && input.getAttribute("linkto").length > 0 && input.getAttribute("linkto") != "null")
				{
					continue
				}
				
				if(input.getAttribute("source") != "")
				{
					_reloadCombo(input, caller)
				}
			}			
		}
	}
	

	function _reloadCombo(input, caller, bForceRefresh)
	{
	    if(bForceRefresh == null) bForceRefresh = false;
	
		var selectXml = _getSourceCombo(input, bForceRefresh, caller)
		
		var evt = new Object();
		evt.options = selectXml;
		evt.controlid = input.id;
		
		try
		{
		    caller.raiseEvent("onbeforecomboreload",evt);
		}catch(e){}
		
		selectXml = evt.options;
		
		if(selectXml != null)
		{
			if (selectXml.length > 0 )
			{
				input.reload(selectXml);
			}
		}
				
		var evt = new Object();
		evt.controlid = input.id;
		
		try
		{
		    caller.raiseEvent("onaftercomboreload",evt);
		}catch(e){}
	}
	

	function _getSourceCombo(objSourceCombo,bRefresh, objWindow)
	{
		try
		{
			var obj
			
			var sSourceComboName = objSourceCombo.source;
			
			if(sSourceComboName == null)
			{
			    sSourceComboName = objSourceCombo.getAttribute("source");
			}
			
			var bSecurityFilter = false;
			try
			{
			    if(objSourceCombo.getAttribute("sourcefilter") != null && objSourceCombo.getAttribute("sourcefilter").length > 0)
			    {
				    bSecurityFilter = true
			    }
			}catch(e){}    
			
			if (sSourceComboName.length == 0) 
			{
			    return ("");
            }
            
			var arrSourceCombo = sSourceComboName.split(".");
			var comboType      =   arrSourceCombo[0];
			
			var sReturnValue;
			var sComboData = null;

            var comboApplicationId = objSourceCombo.applicationid;
            
            if(comboApplicationId == null)
            {
                comboApplicationId = objSourceCombo.getAttribute("applicationid");
            }
            
			if(comboApplicationId == null)
			{
			    comboApplicationId = top.context.session.clientpath;
			}
			  
			if(comboType == "tcombos")
			{
    			sComboData = _fetchDataFromComboXml(arrSourceCombo, comboApplicationId, bRefresh, bSecurityFilter)  
			}
			else if(comboType  == "businessrule")
			{
			    var sBRXML = "<document><record/></document>";
			    
			    if(objWindow != null)
			    {
			        if(objWindow.BRXML)
			        {
			            sBRXML = objWindow.BRXML;
			        }
			    }
			    
			    var response = rts_processBusinessRule(arrSourceCombo[arrSourceCombo.length - 1], sBRXML)
			    
			    response = cleanSoapResponse(response)
			    if(response.length == null) 
			    {
			        sComboData = "";
			    }
			    else
			    {
			        
	                sComboData = top.XMLLib.transformXML(response, top.context.cache["combosort"])
			    }
			}
			
			
			sComboData = sComboData.replace(/&amp;(?=\w*;)/g , "&");
			
			
			return sComboData
		}catch(e){}
	}
		
		
	function _fetchDataFromComboXml(arrSourceCombo, comboApplicationId, bRefresh, bSecurityFilter)
	{
		var objComboCollectionContext = top.context;
		if(top.wct != null && top.wct.adam != null)
		{
		    objComboCollectionContext = top.wct.adam
        }
        
        var key = comboApplicationId + "/" + arrSourceCombo[arrSourceCombo.length - 1]
	    
        if(objComboCollectionContext.combos.combo[key]!=null && bRefresh==false && bSecurityFilter==false)
        {
	        return objComboCollectionContext.combos.combo[key]
        }
    
		var objSourceFileContent = top.XMLLib.objXMLDocTemplate.cloneNode(true)
		objSourceFileContent.async = false;
	
	
    	var sComboLocation = wsfMapPath( "/mc/em/application/" + comboApplicationId + "/" + arrSourceCombo[0] + "/" + arrSourceCombo[1] + ".xml")
	
		if(arrSourceCombo[1].indexOf("/") == 0)
		{
    	    sComboLocation = arrSourceCombo[1] + ".xml"
        }
		else if(arrSourceCombo[1] == "designercombo")
    	{
	        sComboLocation = "/wsfdesigner/SolutionExplorer/Combos/" + arrSourceCombo[2] + ".xml"
	    }    
	    //else if(arrSourceCombo[1].indexOf("sys_")!=0)
	    //    sComboLocation = "/mc/em/application/" + top.context.session.clientpath + "/" + arrSourceCombo[0] + "/" + arrSourceCombo[1] + ".xml"

        sComboLocation = top.helperLib.wsfMapPath(sComboLocation)
		objSourceFileContent.load(sComboLocation)

	    if(bSecurityFilter)
	    {
		    var objOptions = objSourceFileContent.selectNodes("/select/option")
		    for (var i=0;i<objOptions.length;i++)
		    {
				
			    if(objOptions[i].getAttribute("folderid")!=null && objOptions[i].getAttribute("folderid")!=top.context.session.locationid)								
			    {
				    var objSelect=objOptions[i].parentNode											
				    objSelect.removeChild(objOptions[i])						
			    }
		    }
	    }
	
	    sComboData = objSourceFileContent.xml;
	    
	    //	sComboData = "<select id=\"" + arrSourceCombo[1] + "\"><option value=\"0\">Please select one</option></select>"
	    
	    if (sComboData!=null && sComboData.length>0)
	    {
		    sComboData =top.XMLLib.transformXML(sComboData,top.context.cache["combosort"] )
		    objComboCollectionContext.combos.add(key,sComboData)
	    }	
	    
	    return sComboData;
	}
		
    function cleanSoapResponse(responseXml)
    {
        var re=/&apos;/g
		responseXml = responseXml.replace(re ,"'")
		re  = /%26/g
		responseXml = responseXml.replace(re ,"&")
        return responseXml
    }
    
    var m_arrObjectInstanceCallHandle = new Array()
	
	function loadObjectInstanceFromXml(xml, wct)
	{
	
	    var sResponse = "<document>" + cleanSoapResponse(xml) + "</document>"
	    
	    var sTransResp = top.XMLLib.transformXML(sResponse, top.context.cache["RuntimeXSLForES"])
		
		if(wct == null)
		{
			wct = m_arrObjectInstanceCallHandle[callHandle].wct;
        }
        
		wct.objectInstance.XMLRecord = sTransResp;

		if(sTransResp != "")
		{
			wct.objectInstance.record.mergedeserialise(sTransResp)
		}

	}
	
	function loadObjectInstanceAsync(result,callHandle,objWCT)
	{
		var sResponse = top.XMLLib.getNodeText(result,"//GetObjectRecordResult")

        loadObjectInstanceFromXml(sResponse, objWCT)
			
		if(callHandle != null)
		{
			m_arrObjectInstanceCallHandle[callHandle].fnRef();
			m_arrObjectInstanceCallHandle[callHandle].wct = null
			m_arrObjectInstanceCallHandle[callHandle].fnRef = null
			m_arrObjectInstanceCallHandle[callHandle] = null
		}
	}
	
	function loadObjectInstance(objWCT, asyncCallBack)
	{
		loadObjectHeader(objWCT);
		objWCT.objectInstance.record.objectHeader_UniqueID = objWCT.objectUniqueId;
		
		if(asyncCallBack == null)
		{
			result = top.helperLib.processSoapRequest(objWCT.eventWindow,wsfMapPath("/webservices/wf.object/object.asmx"),"wf.object","GetObjectRecord","sXML","<![CDATA[" + objWCT.objectInstance.record.serialise() +"]]>");
			loadObjectInstanceAsync(result, null, objWCT);
		}
		else
		{
			callHandle = top.helperLib.processSoapRequestAsync(objWCT.eventWindow,loadObjectInstanceAsync,wsfMapPath("/webservices/wf.object/object.asmx"),"wf.object","GetObjectRecord","sXML","<![CDATA[" + objWCT.objectInstance.record.serialise() +"]]>");
			m_arrObjectInstanceCallHandle[callHandle] = new Object();
			m_arrObjectInstanceCallHandle[callHandle].wct = objWCT;
			m_arrObjectInstanceCallHandle[callHandle].fnRef = asyncCallBack;
		}
	}	

    function valueObject(useValueOf)
    {
        var arrUseValueof       =   useValueOf.split(",")
        this.brokerId           =   arrUseValueof[0];
        this.searchTemplateName =   arrUseValueof[1];
        this.objectName         =   arrUseValueof[2];
        this.foreignKey         =   arrUseValueof[3];
    }

	function _getLookupResult(useValueOf)
	{
	    var values          = new valueObject(useValueOf);
	    
        var objWct          = new clsWCT();
		objWct.LRBrokerId   = values.brokerId;
		objWct.LRSearchName = values.searchTemplateName;
		objWct.LRMode       = "popup";
		objWct.LRName       = values.objectName;
		
		var objWindowArgs = new Object();
		objWindowArgs.dialogArgs = "dialogWidth:800px;dialogHeight:550px;border:1;help:no;status:no;resizable:yes;" ;
		
		var returnVal = openObject(objWct, objWindowArgs);
		
		return returnVal;
	}		
	
	function _isPluginActive(applicationID)
	{
	    var sXML = top.context.cache["SYSTBroker"].xml;
	    sXML = sXML.toLowerCase();
		return top.XMLLib.getNodeXML(sXML,"//record[applicationid = '" + applicationID.toLowerCase() + "']/applicationid").length > 0;
	}
	
	/********
	    Gets the application details related to the object. The function returns an a "#" seperated value haveing the applicationid
	    and the objectShortName
	    Parameters
	        sBrokerID   =   the objects BROKERID or O   OBJECTSHORTNAME
	        bObjectName =   a flag that indicates whether the caller needs only the applicationid or even the OBJECTSHORTNAME 
	*********/
	function GetApplicationID(sBrokerID, bObjectName)
	{
		var sReturnValue    = context.session.applicationid;
		var sXML            = top.context.cache["SYSTBroker"].xml;
		sXML                = sXML.toLowerCase();
		var oNodeXML        = top.XMLLib.getNodeXML(sXML,"//record[brokerid='" +  sBrokerID.toLowerCase() + "' or objectname='" + sBrokerID.toLowerCase() + "' or objectshortname = '" + sBrokerID.toLowerCase() + "']");
		var sApplicationId  = top.XMLLib.getNodeText(oNodeXML,"//applicationid");
		
		if(sApplicationId.length > 0 )
		{
			sReturnValue = sApplicationId;		
		}
		
		if(bObjectName)
		{
			sReturnValue += "#" + top.XMLLib.getNodeText(oNodeXML,"//objectname");
		}
		
		return sReturnValue
	}
	
	
	function resetWindowRef(objWindow)
	{
		objWin = objWindow;
	}
	
	//************************************************************************************
	//function is used only when the form is loaded from outside the wolf runtime environment
	//************************************************************************************
	var formArray = new Array();
	
	function openForm(windowReference, formPath, objectBrokerId, IframeNameReference, styleSheet)
	{
        
        if(formPath)
        {
            formArray[objectBrokerId] = {};
            formArray[objectBrokerId].brokerId              = objectBrokerId;
            formArray[objectBrokerId].windowReference       = windowReference;            
            formArray[objectBrokerId].formPath              = formPath;
            formArray[objectBrokerId].IframeNameReference   = IframeNameReference;
            formArray[objectBrokerId].styleSheet            = styleSheet;
        }
        
        //this is done as the XSL's are loaded from cache asynchronously. If this is not loaded then the onward
        //process will fail.

        if(!(top.context && top.context.readyForForms()))
        {
            top.context.formsInit();
            var evalText = "setTimeout(function(){top.EMLib.openForm(null,null,'" + objectBrokerId + "',null);},100)";
            eval(evalText)
            return;
        }
        
	    var formSettings            = formArray[objectBrokerId];
        var objWindowArgs           = {};
        objWindowArgs.targetObject  = formSettings.IframeNameReference;
        objWindowArgs.target        = objWindowArgs.targetObject.contentWindow;
        
        var wct                     = new clsWCT();
        wct.brokerid                = formSettings.brokerId;
        wct.styleSheet              = formSettings.styleSheet;
        wct.showDisplayBar          = false;
        
        wct.bfu                     = top.helperLib.wsfMapPath(formSettings.formPath);
        openObject(wct, objWindowArgs);
	}
	
	function openObject(objWCT, objWindowArgs, mode, allowtransparency)
	{
	    if(mode == null)
	    {
	        mode = "popup";
	    }
	    
		objWCT.adam = top.context;
		if (objWCT.adam == null)
		{
			try{objWCT.adam = top.wct.adam;}catch(e){}
		}
        
        if(objWindowArgs != null)
        {
            objWCT.parentWCT = _getTopWCT(objWindowArgs.windowObject);
        }
        
        if(objWCT.parentWCT == null)
        {
		    objWCT.parentWCT = top.wct;
		}
		
		if(objWCT.parentWCT != null)
		{
		    prepareWCTForChild(objWCT, top.wct);
		}

        if(mode == "popup")
        {
	        return showObject(objWCT, objWindowArgs, allowtransparency);
	    }
	    else
	    {
	    //RV this is still under progress
	        if(objWindowArgs == null)
	        {
	            objWindowArgs = {};
	        }
	        
	        objWindowArgs.target = objWCT.parentWCT.objectWindow.parent;
	        
	        objWindowArgs.targetObject = objWindowArgs.target;
	        
	        return showObject(objWCT,objWindowArgs);
          //**********	        
	    }
	}
	
	
	function showObject(objWCT, objWindowArgs, allowtransparency)
	{
		var objWindow = top.window
		
		var sDefaultHeight  = (document.body.offsetHeight/100)*95 ; //window.screen.height
		var sDefaultWidth   = (document.body.offsetWidth/100)*95 ; //window.screen.width
		var defaultLeft     = (window.screen.availWidth - sDefaultWidth) / 2;
		var defaultTop      = (window.screen.availHeight - sDefaultHeight) / 2;
		
		//var sDialogArgs     = ";dialogHeight:" + sDefaultHeight + "px;dialogWidth:" + sDefaultWidth + "px;dialogLeft:" + defaultLeft + "px;dialogTop:" + defaultTop + "px;";
		var sDialogArgs     = ";height:" + sDefaultHeight + "px;width:" + sDefaultWidth + "px;";
		
		if (objWindowArgs != null)
		{
			if(objWindowArgs.windowObject != null)
			{
				objWindow = objWindowArgs.windowObject;
            }
			if(objWindowArgs.dialogArgs != null)
			{
				sDialogArgs = objWindowArgs.dialogArgs.toLowerCase().replace("dialogheight","height").replace("dialogwidth", "width");
		    }		
		}
		
		
		if(objWCT.objectWindow != null)
		{
			objWindow = objWCT.objectWindow;
		}
		
		//if(!objWCT.adam)objWCT.adam = {};

	    //objWCT.adam.libraries = top.libraries;
		//return objWindow.showModalDialog("/widgets/runtime/htc/test_wct.htm",objWCT,sDialogArgs)	
		
		if(objWindowArgs != null && objWindowArgs.target != null)
		{	
		
		    try
		    {
		    //this step is only required when runnin the application. this will fail when the complete environment has not bee initialised
		    //its ok to error in not runtime loading of object forms.
			top.lastBack++;
			top.backArray[top.lastBack] = objWCT;
			}catch(e){}
		
			top.helperLib.attachEvents(objWindowArgs.targetObject, objWindowArgs.targetObject, "onload", showWCT);
			objWindowArgs.target.location   = "about:blank";

			objWindowArgs.targetObject.wct  = objWCT;
		
			top.holdingWCT                  = objWCT;
			//targetobject refers to the frame element
			top.holdingWCT.targetObject     = objWindowArgs.targetObject;
			//target refers to the window frame/contentwindow
			top.holdingWCT.target           = objWindowArgs.target;

			showWCT();
		}
		else
		{
			objWCT.showMode = "popup";
			
			//top.DHTMLLib.showModalWindow("/widgets/runtime/htc/wct.htm",objWCT,sDialogArgs,objWindow)
            var dialog = top.DHTMLLib.showCustomDialog(top , sDialogArgs, null, allowtransparency);
            
            dialog.dialogArguments         = objWCT;
            dialog.container.innerHTML = "<iframe src='" + wsfMapPath("/widgets/runtime/htc/wct.htm") + "' style='" + sDialogArgs + ";border:0px' frameborder='0' allowtransparency = 'true'></iframe>"
            dialog.callBackRef      = _cb_openObject;
            dialog.callBackArguments = objWCT;
			
			//return objWindow.showModalDialog(wsfMapPath("/widgets/runtime/htc/wct.htm"), objWCT, sDialogArgs)		
		}
	}

    function _cb_openObject(returnValue, wct)
    {
        try{wct.callBack(returnValue)}catch(e){}
    }

	function showWCT(evt)
	{
		if(top.holdingWCT == null) return;
		
		//objUnknown is a reference to the window
		objUnknown = top.holdingWCT.target;
		
		if(evt == null) evt = objUnknown.event;

		if((objUnknown.document.readyState && objUnknown.document.readyState != "complete") || (evt && !objUnknown.document.readyState && evt.type != "load")) return
		
		if(objUnknown.location.href.indexOf("wct.htm") >= 0)
		{

		    top.helperLib.detachEvents(objUnknown, objUnknown, "onload", showWCT);
		    top.helperLib.hideLoading(top.holdingWCT.target.parent);

	        top.holdingWCT.targetObject = null;
	        top.holdingWCT.target       = null;
	        top.holdingWCT              = null;
			
		}
		else
		{
			objUnknown.location = wsfMapPath("/widgets/runtime/htc/wct.htm");

		    if (window.addEventListener) 
		    {
		        /*
		            this should not be here but for some reason the onload is
		            not recieving the new window.location as wct.htm
		        */    
		        top.helperLib.hideLoading(top.holdingWCT.target.parent);
		    }

			objUnknown          = null;
		}
		
	}
	
	
	function initWindow()
	{
		try
		{
			if(top.wct.eventWindow != null)
			{
				objWin = top.wct.eventWindow;
			}
			if(objWin == null)
			{
				objWin=top.frames["wctFrame"];
			}
			if(objWin == null)
			{
				objWin = window.frames["wctFrame"];
			}
			if(objWin == null)
			{
				objWin= window.frames["em_objectFrame"].frames["wctFrame"];
			}
		}catch(e){}	
	}


	function escapeSpecialChars(value)
	{

		//if(value.indexOf("&") == -1) return value
		sValue = "" + value
		var re = /</g
		sValue = sValue.replace(re,"%26lt;")
		var re = />/g
		sValue = sValue.replace(re,"%26gt;")
		
		re = /&/g
		sValue = sValue.replace(re,"%26")

		if(sValue.indexOf("<")>=0 && sValue.indexOf("<![CDATA[")!=0)
			sValue = "&lt;![CDATA[" + sValue + "]]&gt;"
		else if(sValue.indexOf("<![CDATA[")==0)	
		{
			sValue = sValue.replace("<![CDATA[","&lt;![CDATA[")
			sValue = sValue.replace("]]>","]]&gt;")
		}
		return sValue
	}

	function _returnObjectStatusFromPermissions(sStatus,sObjectId,sObjectLocationId)
	{
		var canProgress;
		var returnValue = "C";
		if (top.session != null)
		{
			canProgress = top.XMLLib.getNodeText(top.context.session.sessionXML.xml.toLowerCase(),"//record[id='"+ sObjectId + "' and type='object' and wffolderid='" + sObjectLocationId + "' and canprogress = 1]/canprogress");
			if (sStatus == "O" && canProgress == "1")
			{
				returnValue = "O"
			}
			else
			{
				returnValue = "C"
			}
		}
		return returnValue
	}

	function _getBrokerIdFromBfu(wct)
	{
	    try
	    {
		    if(wct.bfu == null)
		    {
			    return "";
			}
		    
		    var sXML = top.context.cache["SYSTBroker"].xml;
		    sXML = sXML.toLowerCase();
		    
		    sName = _getObjectNameFromBfu(wct)
		    
		    var sBrokerID = top.XMLLib.getNodeText(sXML,"//record[name='" + sName + "']/brokerid");
	    	//window.clipboardData.setData("text",sBFU+sXML+sBrokerID)
    		return sBrokerID
		}catch(e){return null}
	}

	function _getObjectNameFromBfu(wct)
	{
		var sBFU = wct.bfu.toLowerCase();
		var sName = sBFU.split("/");
		sName = sName[sName.length-1].split(".")[0];
		if(sName.indexOf("_edit_") >= 0)
		{
		    sName = sName.substring(0, sName.indexOf("_edit_"));
		}
		return sName;
	}
	
	function _getObjectDefFromBrokerId(sBrokerID)
	{
	    sApplicationFolder = GetApplicationID(sBrokerID);
		return wsfMapPath("/mc/em/" + top.context.session.languageFolder + "Application/" + sApplicationFolder + "/objects/release/" + sBrokerID + "_def.xml");
	}
	
	function wsfMapPath(sURL)
	{
	    return top.helperLib.wsfMapPath(sURL);
	} 
	
	
	/********
	Gets the relative file name for the object's screen name specified. If the screenname 
	has been missed out then it returns the default editscreen for the object
    Parameters
	    sObjectName     =   The OBJECTSHORTNAME or the BROKERID
	    templateName    =   The SCREEN NAME or NULL or UNDEFINED
	********/
	function _getObjectBFU(sObjectName, templateName)
	{
	    if(!templateName)
	    {
	        templateName = "";
	    }
	    else
	    {
	        templateName = "_edit_" + templateName
	    }
	    
	    var appInfo = GetApplicationID(sObjectName, true);
	    appInfo = appInfo.split("#");
	    
	    sURL = wsfMapPath("/mc/em/" + top.context.session.languageFolder + "application/" + appInfo[0] + "/objects/release/"+ appInfo[1] + templateName + ".html");
		return sURL
	}

	function clsWCT()
	{
		var objChildContexts        = new Array()
		this.ObjectLookupDetails    = null
		this.objectsCreated         = new clsObjectsCreated()
		this.plugin                 = null
		this.LRBrokerId             = null
		this.LRSearchName           = null
		this.LRName                 = null 
		this.LRMode                 = null // "popup" || ""
		this.objectStatus           = null
		this.objectUniqueId         = null
		this.bfu                    = null
		this.firstPage              = null
		this.adam                   = null
		this.objectWindow           = null
		this.parentWCT              = null;
		this.objectInstance         = new clsObject()
		
		this.spaces                 = null
		this.attachment             = null
		
		this.helptext               = null
		this.showDisplayBar         = true;
		
		this.childBFU               = null
		this.runtimeHelper          = null
		this.cancelCommit           = false
	}

	function clsObject()
	{
		var meObject = this
		this.resetRecord =false
		this.reinit = _reinit
		this.record = new clsObjectRecord()
		this.XMLRecord = null
		function _reinit()
		{
			meObject.record = new clsObjectRecord();
		}
	}

	function clsObjectRecord()
	{
		var me=this
		this.objectHeader_UniqueID = ""
		this.objectHeader_Status = ""
		this.parentserialisecode  = ""
		this.parents              = {};
		
		this.childSerialiseText     = "";
		this.serialisetext          = "";
		this.getDataType            = getDataType;
		this.addAttribute           = _addattribute;
		this.deserialise            = _deserialise;		
		this.mergedeserialise       = _mergedeserialise;
		this.serialise              = _serialise;
		this.appendChildRecord      = _appendchildrecord;
		this.dispose                = _dispose()
		
		var eventHandler = new top.helperLib.clsEventHandler();
		this.attachEvents = eventHandler.attachEvent;
		this.detachEvents = eventHandler.attachEvent;
		this.raiseEvent = eventHandler.raiseEvent;
		
		function _dispose()
		{
			try{eventHandler.dispose()}catch(e){}
			me.attachEvents = null;
			me.detachEvents = null;
			me.raiseEvent = null;
		}
		
		function _appendchildrecord(sXML)
		{	
			appendChildObjectRecord(me,sXML)
		}
		
		function _mergedeserialise(sXML)
		{
			objectMergeDeserialise(sXML,me)
		}

		function _deserialise(sXML)
		{
			objectDeserialise(sXML,me)
		}
		
		function _addattribute(sAttributeName, sAttributeValue)
		{
			var sAttributeExists = eval("me." + sAttributeName.replace(".","_") + "!=undefined")
			eval("me." + sAttributeName.replace(".","_") + "=sAttributeValue")
			if(!sAttributeExists)
				eval("me.serialisetext+=\"'<" + sAttributeName + ">' + escapeSpecialChars(me." + sAttributeName.replace(".","_") + ") + '</" + sAttributeName + ">' + \"")
			var evt = new Object()
			evt.attributeName = sAttributeName
			evt.attributeValue = sAttributeValue
			me.raiseEvent("onafteraddatribute",evt)
		}

		function _serialise()
		{
		    var parentDocument = objectSerialise(me); 
		    if(parentDocument.length > 0)
		    {
		        parentDocument = "'<Parents>" + parentDocument +"</Parents>'+"
		    }
		    
		    var childrenXml = "";
		    if(me.childSerialiseText != "" && me.childSerialiseText != null)
		    {
		        childrenXml = "<Children>" +  me.childSerialiseText  + "</Children>"
		    }
		    
		    var evalText = "'<document><record>'+" + me.serialisetext +  parentDocument + "'" + childrenXml + "</record></document>'";
			return eval(evalText)
		}
		
		function getDataType(oWindow,sFieldName)
		{
			var sReturnValue="unknown"
			var objEditMeta = oWindow.document.getElementById("EditMeta")
			
			var objNode = objEditMeta.selectSingleNode("//fields/*[@id='" + sFieldName + "']")
			if (objNode!=null) sReturnValue =objNode.nodeName
			return sReturnValue
		}
	}

	function appendChildObjectRecord(record,sObjectSerialised)
	{
		record.childSerialiseText += top.XMLLib.getNodeXML(sObjectSerialised,"/document/record")
	}

	function objectSerialise(record)
	{
	    try{
		var parentSerialiseText = "";
	    for(var sKey in record.parents)
        {
            parentSerialiseText += record.parents[sKey].serialise();
        }
		//eval(record.parentserialisecode)
		return parentSerialiseText
		}catch(e){alert("objectSerialise:" + e.description)}
	}

	function getParent(sName,objectRecord)
	{
	    
	    if(objectRecord.objectHeader_objectName != null)
	    {
	        var objectName = objectRecord.objectHeader_objectName.toLowerCase();
            if(objectName == sName.toLowerCase() || "te_" + objectName == sName.toLowerCase())
            {
                return objectRecord;
            }
            
	    }
		
		
		
		var oParent = eval("objectRecord."+sName)
		if(oParent == null)
		{
			eval("objectRecord."+sName+"= new clsObjectRecord()" )
			oParent = eval("objectRecord."+sName)
			oParent.serialisetext = "'<objectHeader.UniqueID>' + this.objectHeader_UniqueID + '</objectHeader.UniqueID>'+"
			var sParentUniqueID = eval("objectRecord.FK_" + sName)
			if(sParentUniqueID!=null && sParentUniqueID.length>0)
			{
				oParent.objectHeader_UniqueID = sParentUniqueID
            }
            objectRecord.parents[sName] = oParent;
			//objectRecord.parentserialisecode += "  parentSerialiseText += '\"<record>\"+' + record."+ sName +".serialisetext + '\"</record>\"+';"
		}
		return oParent
	}

	function objectMergeDeserialise(scrXML,record)
	{
	    
		var objParent
		
		var sFunctionScript = top.XMLLib.transformXML(scrXML,top.context.cache["objectDeserialise"],"merge")	
		
		sFunctionScript = replaceScript(sFunctionScript)
		
		try{
		
		eval(sFunctionScript)
		
		}catch(e){alert("objectMergeDeserialise" + e.message + "\n" + sFunctionScript);clipboardData.setData("text",sFunctionScript)}
	}

	function replaceScript(sScript)
	{
		var re = /\\/g
		sScript =sScript.replace(re,"\\\\")
		re = /"/g
		sScript =sScript.replace(re,"\\\"")
		re = /<quot>/g
		sScript =sScript.replace(re,"\"")
		
		re = /\r\n/g
		sScript = sScript.replace(re,"&#13;")
		re = /\n/g
		sScript = sScript.replace(re,"&#13;")
		//sScript = sScript.replace(re,"%0A")
		
		return sScript
		
	}

	function objectDeserialise(scrXML,record)
	{
		var objParent
		
		record.serialisetext += "'<objectHeader.UniqueID>' + this.objectHeader_UniqueID + '</objectHeader.UniqueID>'+"
		record.serialisetext += "'<objectHeader.Status>' + this.objectHeader_Status + '</objectHeader.Status>'+"
		
		var sFunctionScript = top.XMLLib.transformXML(scrXML,top.context.cache["objectDeserialise"]);

		sFunctionScript     = replaceScript(sFunctionScript);
		

		try
		{
		    eval(sFunctionScript)
		}catch(e){alert("objectDeserialise" + e.message + "\n" + sFunctionScript);clipboardData.setData("text",sFunctionScript)}
	}

	function deserialise(sCurrentXML,sXPATH,objDeserialise)
	{
		if (objDeserialise==null)
		{
			objDeserialise = new clsDeserialise();
		}

		objDeserialise.serialisetext = "";
		if(sCurrentXML == null || sCurrentXML.length == 0)
		{
		    return objDeserialise;
        }
        
		var objCurrentXML = top.XMLLib.objXMLDocTemplate.cloneNode(true);
		objCurrentXML.loadXML (sCurrentXML);
		if (objCurrentXML.xml.length==0)
		{
		    return objDeserialise
		}
		var objChildNode = objCurrentXML.selectSingleNode(sXPATH).firstChild
		var sNodeName
		
		while(objChildNode!=null)
		{
			if(objChildNode.nodeType==1)
			{
				sNodeName = objChildNode.nodeName
				sNodeName = sNodeName.replace(".","_")
				objDeserialise.addAttribute(sNodeName,objChildNode.text)
			}
			objChildNode = objChildNode.nextSibling
		}
		return objDeserialise
	}

	function clsDeserialise()
	{
		var meDeserialise = this
		this.serialisetext =""
		this.serialise = _serialise
		this.internalSerialise = _internalserialise
		this.addAttribute = _addattribute
		
		function _addattribute(sAttributeName,sAttributeValue)
		{
			var objValue = eval("this." + sAttributeName )
		    if(objValue==null)
		    {
			    eval("this." + sAttributeName + "=sAttributeValue;this.serialisetext += '<" + sAttributeName + ">\" + escapeSpecialChars(this." + sAttributeName + ") + \"</" + sAttributeName + ">'")
            }
		    else
		    {
			    eval("this." + sAttributeName + "=sAttributeValue")	
            }
            
        }
		
		function _internalserialise()
		{
			return eval("\"" + meDeserialise.serialisetext + "\"")
		}
		
		function _serialise()
		{
			return eval("\"" + meDeserialise.serialisetext + "\"")
		}
	}

	function clsObjectRules()
	{
		this.preSave=null;//needs to be extended later to accept presave paramenters
		this.postSave =null;//needs to be extended later to accept presave paramenters
		//this.selfCompleting = false;
		//this.closeObject = true;
		this.preClose = null;
		this.postClose = null;
		this.printedOutput = false;
		this.attachmentEnabled = false;
		this.runtimehelperEnabled = false
	}

	function clsObjectsCreated()
	{
		var meObjectsCreated = this
		this.items = new Array()
		this.count = 0;
		this.add = _add
		
		function _add(sNewObject)
		{
			meObjectsCreated.items[meObjectsCreated.items.length] = sNewObject
			meObjectsCreated.count++;
		}	
	}

	function clsCombos()
	{
		var meCombos = this
		this.combo = new Array()
		this.add = _add
		
		function _add(sNewComboName,sNewComboXML)
		{
			meCombos.combo[sNewComboName] = sNewComboXML
		}
	}

	function clsMainContext()
	{
		var meMainContext = this
		this.window = top;
		try{
		this.cacheUtil          = new top.clscacheLib(meMainContext.window);
		}catch(e){}
		this.session            = null;
		this.combos             = new clsCombos();
		this.cache              = new Array();
		this.reinitWCT          = _reinitwct;
		this.lastELQueryTimeStamp="";
		this.wct                = null;
		this.intervalHandle;
		//this.showUpdates= alertChanges;
		this.plugin             = null;
		this.applicationpopup   = null;
		this.initSession        = initSession;
		this.closeWindow        = _closewindow;
		this.objInterfaceBase   = null;
		this.firstMenuTitle     = null; //Use as context detail. Indicates the title of the menu item that had been clicked to invoke this wct.
		this.currentDate        = getCurrentDate;
		this.currentTime        = getCurrentTime;
		this.enviroment         = new Array();
		this.addXMLToCache      = _addXMLToCache;
		this.runtimeInit        = _runtimeInit; //method called when the complete runtime environment is being initialised
		this.formsInit          = _formsInit;   //method called if only information sufficient to load a form is required
		
		this.readyForForms      = _readyForForms;
		
		var formInitialiseActivated     = false;
		var runtimeInitialseActivated   = false;
		
		function _readyForForms()
		{
		    if(!top.context.cache["objectDeserialise"]) return false
		    if(!top.context.cache["combosort"]) return false
		    if(!top.context.cache["RT_SchemaTransformation"]) return false
		    if(!top.context.cache["RuntimeXSLForES"]) return false
		    if(!top.context.cache["SYSTBroker"]) return false
		    return true
		}
		
		function _runtimeInit()
		{
		    if(runtimeInitialseActivated) return
		    runtimeInitialseActivated = true;
            //load solution environment information
            var objSolutionXML = top.XMLLib.objXMLDocTemplate.cloneNode(true);
		    objSolutionXML.async = false;
		    objSolutionXML.load(wsfMapPath("$application/xml/solution.xml"));

		    top.context.session.application = new clsSolutionDeserialise();
		    top.context.session.application.deserialise(objSolutionXML.xml);

            top.context.session.languageFolder = "";
            _formsInit();
		}
		
		function _formsInit()
		{
		    if(formInitialiseActivated) return
		    formInitialiseActivated = true;
		    try
		    {
		        initialiseXSL();
		        initialiseDBData();
		    }catch(e){}
		}

        function _addXMLToCache(objQueue,iCacheIndex)
        {
			meMainContext.cache[objQueue.tagVariant] = objQueue.queue[0].XMLObject
        }

		function _initialisedXSL(xmlDocument)
		{
		    /*
		    _initialisedXSL(objQueue,iCacheIndex)
		    var xmlDocument = top.XMLLib.objXMLDocTemplate.cloneNode(true);
		    xmlDocument.loadXML(objQueue.queue[0].sXML)
		    */
		    
		    var xmlRecords = xmlDocument.selectNodes("/document/record")
		    for(var i=0; i < xmlRecords.length ; i++)
		    {
		        var id = xmlRecords[i].getAttribute("id");
		        var objXSL = top.XMLLib.objXSLDocTemplate.cloneNode(true);
		        
		        objXSL.loadXML (top.XMLLib.getNodeFirstChild( xmlRecords[i] ).xml );
		        //alert(objXSL.xml)
		        meMainContext.cache[id] = objXSL
		    }
		    
		}
		
		function initialiseXSL()
		{
            var xmlDocument = top.XMLLib.objXMLDocTemplate.cloneNode(true);
		    xmlDocument.async = false;
		    
		    xmlDocument.load(wsfMapPath("/widgets/runtime/xsl/runtimexsl.xml"));
	        
            //this line has been put for Firefox. If the xsl is loaded first in a modal dialog (popup) a bug in firefox prevents 
            //gives an xmlserializer not defined error
            top.XMLLib.loadXSL(wsfMapPath("/widgets/runtime/xsl/readonlyTransform.xsl"),"readonlyTransformXML")	    
	        top.XMLLib.loadXSL(wsfMapPath("/widgets/grid/xsl/griddata.xsl"),"wolf_griddata")	    
	        
            _initialisedXSL(xmlDocument)
		    //meMainContext.cacheUtil.loadXMLFromCache("all", _initialisedXSL, "all", wsfMapPath("/widgets/runtime/xsl/runtimexsl.xml"))
		}
		
		function _closewindow()
		{
			window.close()
		}	
		
		function _reinitwct()
		{
			meMainContext.wct=new clsWCT();
		}	
		
		function getCurrentDate()
		{
			var dt = new Date()
			return dt.getDate() + "/" + parseInt(dt.getMonth()+1) + "/" + dt.getFullYear()
		}

		function getCurrentTime()
		{
			var dt = new Date()
			return dt.getHours() + ":" + dt.getMinutes()  
		}

		function initSession(objsessionState)
		{
			top.session = objsessionState;
			meMainContext.session = new clsSession(objsessionState)
		}
	}
	
	function clsObjectLookup()
	{
		var objObjectLookup = new Array();
		this.Add = addValues;
		this.ObjectLookValues = objObjectLookup;
		
		function addValues(newName ,newValue)
		{
			objObjectLookup[newName] = newValue;
		}
		
		this.dispose=_dispose
		function _dispose()
		{
			try{disposeObject(objObjectLookup)}catch(e){}					
		}
	}	

	function clsSession(oSessionXML)
	{
	    var me = this;
		this.sessionXML         = oSessionXML;
		this.userid             = top.XMLLib.getNodeText(oSessionXML,"/record/UniqueID");
		this.defaultfolderid    = top.XMLLib.getNodeText(oSessionXML,"/record/WFfolderid");
		this.defaultfoldername  = top.XMLLib.getNodeText(oSessionXML,"/record/WFdefaultfolder");
		this.applicationid      = top.XMLLib.getNodeText(oSessionXML,"/record/applicationID");
		this.sessionid          = top.XMLLib.getNodeText(oSessionXML,"/record/sessionID");
		this.username           = top.XMLLib.getNodeText(oSessionXML,"/record/UserName");
		this.dateformat         = top.XMLLib.getNodeText(oSessionXML,"/record/DateFormat");
		this.clientid           = top.XMLLib.getNodeText(oSessionXML,"/record/ClientID");
		this.designer           = top.XMLLib.getNodeText(oSessionXML,"/record/WFdesigner") == "1";
        var sClientPath         = top.XMLLib.getNodeText(oSessionXML,"/record/applicationID");

        if(me.clientid != "")
        {
            sClientPath += "/clients/" +  me.clientid;
        }
		this.loginid            = top.XMLLib.getNodeText(oSessionXML,"/record/loginId");
		this.clientpath         = top.XMLLib.getNodeText(oSessionXML,"/record/ClientPath");
		
		//this.roleid = top.XMLLib.getNodeText(oSessionXML,"/record/WFroleid")
		//this.rolename = top.XMLLib.getNodeText(oSessionXML,"/record/WFrole")
		
		this.useruid = top.XMLLib.getNodeText(oSessionXML,"/record/WFuserObjectmappingid");
		this.usermapname = top.XMLLib.getNodeText(oSessionXML,"/record/WFuserObjectmappingdisplayname");
		
		//this.applicationname = top.XMLLib.getNodeText(oSessionXML, "/record/applicationname") ;
		
		
		this.departmentid = top.XMLLib.getNodeText(oSessionXML,"/record/DepartmentID");
		this.languageFolder = "";
		
		//this.SettingsXML=top.XMLLib.getNodeXML(oSessionXML,"/record/SettingsXML/document")
		
		this.personalisation = new clsPersonalisationDeserialise()
		
	//	this.personalisation.deserialise = function(){deserialisePersonalisation(this,arguments[0],arguments[1])};
        
            
		var sXML = top.XMLLib.getNodeXML(oSessionXML,"/record/SettingsXML")
		var re = /&lt;/g; 
		sXML = sXML.replace(re,"<")
		re = /&gt;/g; 
		sXML = sXML.replace(re,">")
		sXML = top.XMLLib.getNodeXML(sXML,"/record/SettingsXML/document")
		
		this.personalisation.deserialise(top.helperLib.HTMLDecode(sXML),false)

		//this.personalisation.deserialise(top.helperLib.HTMLDecode(top.XMLLib.getNodeXML(oSessionXML,"/record/SettingsXML/document")),false)
	}

	var g_parent = function(type) 
	{
		var p = new Object();
		for (x in type.prototype) 
		{
			if (x != "parent") 
			{
				p[x.toString()] = this[x.toString()];          
			}
		}   
		return p;  
	};

    clsSolutionDeserialise.prototype = new clsDeserialise;
	function clsSolutionDeserialise()
	{
		var me = this
		clsDeserialise.call(this,me)
		var parent = g_parent(clsDeserialise)

		this.deserialise = function(sSettingsXML)
		{
			deserialise(sSettingsXML,"//document/record",me)
		};
		
		this.serialise = function(iDefaultPageSize)
		{
			me.iPageSize=iDefaultPageSize
			me.iEndRowID=iDefaultPageSize
			return me.internalSerialise()
		};
	}
    

	clsPersonalisationDeserialise.prototype = new clsDeserialise;
	function clsPersonalisationDeserialise()
	{
		var me = this
		clsDeserialise.call(this,me)
		var parent = g_parent(clsPersonalisationDeserialise)

		this.deserialise = function(sSettingsXML,bInit)
		{
			deserialise(sSettingsXML,"/document",me)
		//	if(bInit==true)
		//	{
				me.sDateFrom =""
				me.sDateTo=""
		//	}
	//		objPersonalisation.serialise = function(){ return serialisePersonalisation(this,arguments[0])};
		};
		
		this.serialise = function(iDefaultPageSize)
		{
			me.iPageSize=iDefaultPageSize
			me.iEndRowID=iDefaultPageSize
			return me.internalSerialise()
		};
	}

	function login(sUserName,sPassword,sApp)
	{
	    initialiseContext();
		var result = top.helperLib.processSoapRequest(null, wsfMapPath("/webservices/wf.session/session.asmx"),"wf.Session","GetUserProfile","sLogin",sUserName,"sPassword",sPassword,"sApplicationID",sApp)		
		if (result==null)
		{
		    return		
        }
        
		var sFunctionResponse   = top.XMLLib.getNodeText(result,"//GetUserProfileResult");
		sFunctionResponse       = sFunctionResponse.replace(/%26/g, "&amp;")
		
		if (sFunctionResponse == "") 
		{
		    return;
        }
		sFunctionResponse       = sFunctionResponse.replace('<record>', '<record><applicationname>' + sApp + '</applicationname>');
		sFunctionResponse       = sFunctionResponse.replace('<record>', '<record><loginId>' + sUserName + '</loginId>');
		
		//alter current session
		
		var objsessionState = top.XMLLib.objXMLDocTemplate.cloneNode(true)
		sFunctionResponse = sFunctionResponse.replace(/WFfirstname>/g,"UserName>")
		sFunctionResponse = sFunctionResponse.replace(/WFdefaultlocation>/g,"LocationName>")
		sFunctionResponse = sFunctionResponse.replace(/UniqueID>/g,"UserID>")
		objsessionState.loadXML(sFunctionResponse)
		top.context.initSession(objsessionState)	
		if(top.context.plugin!=null)
		{
			setTimeout(function(){top.context.plugin.initialise()},1000);
		}
		initialiseDBData()
	}

	function initialiseDBData()
	{
	    if(top.context.cache["SYSTBroker"] != null)
	    {
	        return
	    }

		var result =  top.helperLib.processSoapRequest(null, wsfMapPath("/webservices/wf.object/object.asmx"), "wf.object","GetBrokerDetails", "sXML", "<![CDATA[<document><record><tablename>tBroker</tablename><BrokerID ></BrokerID><def><fields><IsFinancialEnabled/><AuthorityTopLevel/></fields></def></record></document>]]>")

		var sResponse =""
		
		if (result == null) return 
		{
			sResponse = top.XMLLib.getNodeText(result,"//GetBrokerDetailsResult")
		}

		if(	sResponse!="")
		{
			top.context.cache["SYSTBroker"]= top.XMLLib.objXMLDocTemplate.cloneNode(true)	
			//clipboardData.setData("text",sResponse)
			top.context.cache["SYSTBroker"].loadXML(sResponse)
		}	
	}

    function _sessionExpired()
    {
        alert("Your Session has expired. Please login again.");
        doLogin();
    }

	function doLogin(pluginObject, callBackRef)
	{
		if(bDologinActive == true) 
		{
			return;
		}
		bDologinActive = true;

		initialiseContext(pluginObject);

        top.helperLib.processSoapRequestAsync(window, _cb_doLogin,  wsfMapPath("/webservices/wf.session/session.asmx"), "wf.Session", "IsActiveSession");
        
        function _cb_doLogin(result)
        {
           var sFunctionResponse = top.XMLLib.getNodeText(result,"//IsActiveSessionResult");
           var userIsAuthenticated = (sFunctionResponse.toLowerCase() == "true"); 
           
            if (!userIsAuthenticated) 
            {
		        var currentWindow = objWin;
		        if(currentWindow == null)
		        {
			        currentWindow = window;
			    }
		        var sLoginPage = wsfMapPath("/mc/login.html");

                
                var iWidth    = 350;
                var iHeight   = 300;
                
                if(navigator.appName == "Microsoft Internet Explorer" && navigator.userAgent.indexOf("MSIE 6.0") > 0 )
                {
                    iHeight += 52; 
                }
                
		        var iLeft     = (window.screen.availWidth - iWidth) / 2;
		        var iTop      = (window.screen.availHeight - iHeight) / 2;
                                
                var dialog = top.DHTMLLib.showCustomDialog(top , "height:" + iHeight + "px;width:" + iWidth + "px;");
                
                dialog.dialogArguments         = top;
                dialog.container.innerHTML = "<iframe src='" + sLoginPage + "' style='height:" + iHeight + "px;width:" + iWidth + "px;border:0px' frameborder='0' allowtransparency = 'true'></iframe>"
                dialog.callBackRef      = _doLoginCallBack;
                dialog.callBackArguments = callBackRef;
                
	            //var sReturnValue = window.showModalDialog(sLoginPage, top, "center:yes;dialogTop:" + iTop + "px;dialogLeft:" + iLeft + "px;dialogWidth:" + iWidth + "px;dialogHeight:" + iHeight + "px;border:1;help:no;status:no;resizable:no;unadorned:yes");
	            //return _doLoginCallBack(sReturnValue, callBackRef);

		    }
		    else
		    {
		        return _doLoginCallBack(true, callBackRef);
		    }
        } 

	}
	
	function _doLoginCallBack(returnValue, args)
	{
        if(returnValue == null)	    
        {
		    top.location = "mc/blanklogin.htm"
		    return
		    top.context = null;
        }
        else
        {
		    readUserProfile();
		    bDologinActive = false;
		}
		
        if(args)
        {
            args(returnValue)
        }
        return returnValue;
	}
	
	function initialiseContext(pluginObject)
	{
		if(top.context == null)
		{
			var objTemp = top.document.body.appendChild(top.document.createElement("script"));
			objTemp.language = "javascript";
			objTemp.type     = "text/javascript";
			objTemp.text = "var session;var context";
			
			top.context             = new clsMainContext();
			top.context.appId       = top.appId;
			top.context.loginPage   = top.loginPage;
			if(pluginObject != null)
			{
				top.context.plugin = pluginObject;
			}
		}		
	}
	
	function readUserProfile(userName, password, applicationId)
	{
	    if(top.context == null)
	    {
	        initialiseContext();
	    }

        if(top.context.session == null)
        {
            var result ,sFunctionResponse
            if(userName)
            {
        	    result = top.helperLib.processSoapRequest(window, wsfMapPath("/webservices/wf.session/session.asmx"),"wf.Session","GetUserProfile","sLogin",userName,"sPassword",password,"sApplicationID",applicationId)		
		        if (result==null){return}
		        sFunctionResponse=top.XMLLib.getNodeText(result,"//GetUserProfileResult")		
            }else
            {		    
                result = top.helperLib.processSoapRequest(window, wsfMapPath("/webservices/wf.session/session.asmx") ,"wf.Session","GetSessionXML")
                sFunctionResponse = top.XMLLib.getNodeText(result,"//GetSessionXMLResult");
            }
            
            sFunctionResponse       = sFunctionResponse.replace(/%26/g, "&amp;")
            var sessionState        = top.XMLLib.objXMLDocTemplate.cloneNode(true);
            
            sessionState.loadXML(sFunctionResponse);
            //top.XMLLib.setNodeText(sessionState.selectSingleNode("/record"), "applicationname", top.appName);
            
            top.context.initSession(sessionState);
        }
		if (top.context.cache["objErrLogLangXML"] == null && top.context.session.languageFolder != "" )
		{
			var sErrLogXMLPath = wsfMapPath("/mc/" + top.context.session.languageFolder + "application/"  + top.context.session.applicationid + "/ErrLog_Localiser.xml")
			//loadErrLogLangLocaliser(sErrLogXMLPath)
		}
	}
	
	function prepareWCTForChild(objWCT, topWCT)
	{
	    try
	    {
		    if(topWCT.objectInstance !=  null && (topWCT.objectInstance.record.objectHeader_UniqueID != null && topWCT.objectInstance.record.objectHeader_UniqueID != ""))
		    {
		        objWCT.objectInstance.record.addAttribute("FK_" + topWCT.objectInstance.record.objectHeader_objectName, topWCT.objectInstance.record.objectHeader_UniqueID);
		    }
		}catch(e){}    
	}
	
	function loadObjectHeader(objWCT)
	{
		if(objWCT.brokerid == null)
		{
			objWCT.brokerid = _getBrokerIdFromBfu(objWCT);
	    }

		if(objWCT.brokerid == null || objWCT.brokerid.length == 0) 
		{
		    return;
		}

		var sObjectDef = _getObjectDefFromBrokerId(objWCT.brokerid);
		var sFunctionResponse  = top.context.cache["objectHeader_" + objWCT.brokerid];
		
		if(sFunctionResponse == null || sFunctionResponse.length == 0)
		{
			var result = top.helperLib.processSoapRequest(objWCT.eventWindow, wsfMapPath("/webservices/wf.object/utilityprocessor.asmx"), "wf.object", "XmlTransform", "sXML", "<![CDATA[<document><record><path>" + sObjectDef +"</path><xsl>" + wsfMapPath("/widgets/runtime/xsl/objectHeader.xsl") + "</xsl></record></document>]]>");
			//if (result==null) return null
			sFunctionResponse = top.XMLLib.getNodeText(result,"//XmlTransformResult");
            
			top.context.cache["objectHeader_" + objWCT.brokerid] = sFunctionResponse; 
		}

		objWCT.objectInstance.record.deserialise(sFunctionResponse);
		
	}	
	
	function getEnvironData(sEnvironSetting,objWCT)
	{
		var sEnValue = "", sEnvironBrkr, sEnvironFldname, sDefXML, sDefXMLPath;
		if(sEnvironSetting.indexOf("environ:") == 0)
		{
			sEnvironBrkr = sEnvironSetting.split(":")[1];
			sEnvironFldname = sEnvironSetting.split(":")[2];
			sDefXMLPath = _getObjectDefFromBrokerId(sEnvironBrkr);			
			
			if(top.context.enviroment[sEnvironBrkr] != null)
			{
				var sDefXML = top.context.cache["objectDef_" + sEnvironBrkr];
				if(sDefXML == null)
				{
					var result = top.helperLib.processSoapRequest(objWCT.eventWindow, wsfMapPath("/webservices/wf.object/utilityprocessor.asmx"),"wf.object","XmlTransform", "sXML", "<![CDATA[<document><record><path>" + sDefXMLPath +"</path><xsl>" + wsfMapPath("/widgets/runtime/xsl/objectfields.xsl") + "</xsl><params><param>" + sEnvironBrkr + "</param><param>;</param></params></record></document>]]>");
					sDefXML = top.XMLLib.getNodeText(result,"//XmlTransformResult");
					top.context.cache["objectDef_" + objWCT.brokerid] = sDefXML ;
				}
				var objDef = top.XMLLib.objXMLDocTemplate.cloneNode(true)
				objDef.loadXML(sDefXML)
				var sONodeName = top.XMLLib.getNodeText(objDef,"//Tree/TreeNode[displayname='" + sEnvironFldname + "']/name"); // objDef.selectSingleNode("//Tree/TreeNode[displayname='" + "First Name" + "']/name");
				var sObjectName = top.XMLLib.getNodeText(objDef,"//Tree/objectname");
				sONodeName = ("te_" + sObjectName + "." + sONodeName).toLowerCase();
			
				var sEnXML = top.context.enviroment[sEnvironBrkr];
				sEnValue = top.XMLLib.getNodeText(sEnXML,"/document/record/" + sONodeName)//top.XMLLib.getNodeText(sEnXML,"/document/record/" + sEnvironFldname);
				if(sEnValue == "")
				{
					var sTmpEnXML = sEnXML.toLowerCase();
					sEnValue = top.XMLLib.getNodeText(sTmpEnXML,"/document/record/" + sEnvironFldname.split('.')[1]);
				}
			}
		}
		return sEnValue;
	}
}		
