/*
 *+------------------------------------------------------------------------+
 *| IBM Confidential
 *| OCO Source Materials
 *| BI and PM: viewer
 *| (C) Copyright IBM Corp. 2001, 2009
 *|
 *| US Government Users Restricted Rights - Use, duplication or
 *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *|
 *+------------------------------------------------------------------------+
 */

/**
	@fileoverview
	This file implements all that is necessary to send requests to the server side of Cognos Viewer (using the URL Api),
	process the responses and to perform actions on a report like next page or email.
	It manages the report state (conversation, tracking, prompting), the report output and the features on the client for the viewer.
*/

/**
	Initialize the CCognosViewer object.
	@requires CCognosViewerRequest
	@constructor
	@param {string} sId Identifier used for this object. This identifier will be used to mark elements used by this class.
	@param {string} sGateway Path to "cognos.cgi". For example: "/cognos8/cgi-bin/cognos.cgi".
*/

var CV_BACKGROUND_LAYER_ID = "CV_BACK";

if (typeof window.gaRV_INSTANCES == "undefined")
{
	window.gaRV_INSTANCES = [];
}


function CognosViewerSession(oCV)
{
	this.m_sConversation = oCV.getConversation();
	this.m_sParameters = oCV.getExecutionParameters();
	this.m_envParams = oCV.envParams;
	this.m_bRefreshPage = false;
}

function CCognosViewer(sId, sGateway)
{
	// Declare a global instance of CCognosViewer if none exists [for backward compatibility].
	// This global instance will be refered too by global prompt functions like setPromptControl() and promptButtonNext().
	if (typeof window.gCognosViewer == "undefined")
	{
		window.gCognosViewer = this;
	}

	this.m_sActionState = "";

	this.m_bKeepSessionAlive = false;

	/**
	 * @type array
	 * @private
	 */
	this.m_undoStack = new Array();

	/**
		@type array
		@private
	*/
	this.m_aSecRequests = [];

	/**
		@type string
		@private
	*/
	this.m_sSessionPrompts = "";

	/**
		@type bool
		@private
	*/
	this.m_bDebug = false;

	/**
		@type string
		@private
	*/
	this.m_sCAFContext = "";
	/**
		@type string
		@private
	*/
	this.m_sContextInfoXML = "";
	/**
		@type string
		@private
	*/
	this.m_sConversation = "";
	/**
	 * @type string
	 * @private
	 */
	 this.m_sStatus = "";
	/**
		@type string
		@private
	*/
	this.m_sGateway = sGateway;
	/**
		@type string
		@private
	*/
	this.m_sId = sId;
	/**
		@type string
		@private
	*/
	this.m_sMetadataInfoXML = "";
	/**
		@type string
		@private
	*/
	this.m_sParameters = "";
	/**
		@type string
		@private
	*/
	this.m_sReportState = "";
	/**
		@type string
		@private
	*/
	this.m_sTracking = "";
	/**
		@type string
		@private
	*/
	this.m_sSoapFault = "";
	/**
		@type string
		@private
	*/
	this.m_sWaitHTML = "";
	/**
		@type CDrillManager
		@private
	*/
	this.m_oDrillMgr = null;
	/**
		@type CDrillManager
		@private
	*/
	this.goDrillManager = null;

	/**
	 *  @type CWaitPage
	 *  @private
	 */
	this.m_waitPage = new CWaitPage(sId, sGateway);

	/**
		@type CSubscriptionManager
		@private
	*/
	this.m_oSubscriptionManager = null;

	/**
		@type CViewerManager
		@private
	*/
	this.m_oCVMgr = null;

	if (typeof CViewerManager == "function")
	{
		this.m_oCVMgr = new CViewerManager(this);
	}

	if (typeof CDrillManager == "function")
	{
		this.m_oDrillMgr = new CDrillManager(this);
		this.goDrillManager = this.m_oDrillMgr;
	}

	if (typeof CSubscriptionManager == "function")
	{
		this.m_oSubscriptionManager = new CSubscriptionManager(this);
	}

	if (window.gaRV_INSTANCES)
	{
		// only add the cognos viewer object to the array if it isn't already in it
		var bFound = false;
		for (var iIndex=0; iIndex < window.gaRV_INSTANCES.length; iIndex++)
		{
			if (window.gaRV_INSTANCES[iIndex].m_sId == sId)
			{
				window.gaRV_INSTANCES[iIndex] = this;
				bFound = true;
				break;
			}
		}

		if (!bFound)
		{
			window.gaRV_INSTANCES = window.gaRV_INSTANCES.concat(this);
		}
	}

	this.m_oServerRequest = new ServerRequest(this.m_sId);

	this.m_bReportHasPrompts = false;
}

/**
 * KeyDown events handler attached to the document, which disables hotkey page navigation within the viewer
 * @private
 */
CCognosViewer.prototype.captureHotkeyPageNavigation = function(evt)
{

	evt = (evt) ? evt : ((event) ? event : null);
	if(evt)
	{
		var node = getNodeFromEvent(evt);
		if((evt.keyCode == 8 && node.nodeName.toLowerCase() != "input" && node.nodeName.toLowerCase() != "textarea") || (evt.altKey == true && (evt.keyCode == 37 || evt.keyCode == 39)))
		{
			evt.returnValue = false;
			evt.cancelBubble = true;
			if(typeof evt.stopPropagation != "undefined")
			{
				evt.stopPropagation();
			}
			if(typeof evt.preventDefault != "undefined")
			{
				evt.preventDefault();
			}

			return false;
		}
	}

	return true;
};

/**
 * Returns the wait page implementation
 * @return (CWaitPage)
 */
 CCognosViewer.prototype.getWaitPageImpl = function()
 {
 	return this.m_waitPage;
 };


/**
 * Call this method to disable hot key page navigation within the viewer (back space, alt+left arrow, alt+right arrow)
 */
CCognosViewer.prototype.disableBrowserHotkeyPageNavigation = function()
{

	if (document.attachEvent)
	{
		document.attachEvent("onkeydown", this.captureHotkeyPageNavigation);
	}
	else if (document.addEventListener)
	{
		document.addEventListener("keydown", this.captureHotkeyPageNavigation, false);
	}
};

/**
 * Hide/shows the viewer wait page
 * @private
 */
 CCognosViewer.prototype.showWaitPage = function(bShow)
 {
 	if(bShow)
 	{
		this.m_waitPage.show(false);
 	}
 	else
 	{
 		this.m_waitPage.hide();
 	}
 };

/**
 * Sets if the current HTML being displayed contains prompt controls
 * @param (boolean) hasPrompts
*/
CCognosViewer.prototype.setHasPrompts = function(hasPrompts)
{
	this.m_bReportHasPrompts =  hasPrompts;
};

/**
 * Checks to see if the HTML being displayed contains prompt controls
 * @return (boolean)
 */
 CCognosViewer.prototype.getHasPrompts = function()
 {
 	return this.m_bReportHasPrompts;
 };


/**
 * Sets the request mode (page/data)
 * @param (boolean) bPageRequest
*/
CCognosViewer.prototype.setUsePageRequest = function(bPageRequest)
{
	this.m_oServerRequest.setUsePageRequest(bPageRequest);
};

/**
 * Gets the request mode (page/data)
 * @return (boolean)
 */
 CCognosViewer.prototype.getUsePageRequest = function()
 {
 	return this.m_oServerRequest.getUsePageRequest();
 };

/**
 * If you don't want the viewer to release the current conversation on a page reload, use this method to keep the session alive
 * on page reloads
 * @param (boolean)
 */
CCognosViewer.prototype.setKeepSessionAlive = function(bValue)
{
	this.m_bKeepSessionAlive = bValue;
}

/**
 * Return the "Keep Session Alive" boolean value
 * @return (boolean)
 */
CCognosViewer.prototype.getKeepSessionAlive = function()
{
	return this.m_bKeepSessionAlive;
}

/**
 * Returns the web content root
 * @return (string)
 */
CCognosViewer.prototype.getWebContentRoot = function()
{
	if (typeof this.sWebContentRoot != "undefined")
	{
		return this.sWebContentRoot;
	}
	else
	{
		return "..";
	}
};

/**
 * Returns the skin directory
 * @return (string)
 */
CCognosViewer.prototype.getSkin = function()
{
	if (typeof this.sSkin != "undefined")
	{
		return this.sSkin;
	}
	else
	{
		return this.getWebContentRoot() + "/skins/corporate";
	}
};

CCognosViewer.prototype.getSelectionController = function()
{
	var selectionController;
	try
	{
		selectionController = eval("oCVSC" + this.m_sId);
	}
	catch(e)
	{
		selectionController = null;
	}

	return selectionController;
};

/**
	Set up a function to call for events in CCognosViewer.
	@param {string} sEventName Event names are:
		<ul>
		<li><code>done</code> (when a report page is returned)</li>
		<li><code>error</code> (when an error code is returned)</li>
		<li><code>prompt</code> (when an prompt page is returned)</li>
		<li><code>wait</code> (when we get a ?working? and ?stillWorking? state)</li>
		</ul>
	@param {function} oFct Function to call when this even occurs.
	@param {bool} bCaptureEvent If set to true, the normal behavior will not be used.
*/
CCognosViewer.prototype.addCallback = function(sEventName, oFct,  bCaptureEvent)
{
	if (!this.m_aCallback)
	{
		this.m_aCallback = [];
	}

	this.m_aCallback = this.m_aCallback.concat({
		m_sEvent: sEventName,
		m_oCallback: oFct,
		m_bCaptureEvent: (bCaptureEvent===true)
	});
};

/**
	Determines if the element supports drill down or not.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Default is <code>false</code>.
	@type bool
*/
CCognosViewer.prototype.canDrillDown = function(sId)
{
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			return (selectionController.canDrillDown(sCtx));
		}
	}
	return false;
};

/**
	Determines if the element supports drill up or not.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Default is <code>false</code>.
	@type bool
*/
CCognosViewer.prototype.canDrillUp = function(sId)
{
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			return (selectionController.canDrillUp(sCtx));
		}
	}
	return false;
};

/**
	Call this function to know if all required prompts have valid inputs.
*/
CCognosViewer.prototype.canSubmitPrompt = function()
{
	var oPromptElement = null;

	if (this.preProcessControlArray && this.preProcessControlArray instanceof Array)
	{
		var kCount = this.preProcessControlArray.length;
		for ( var k=0; k < kCount; k++ )
		{
			oPromptElement = eval( this.preProcessControlArray[k] );
			if ( oPromptElement.isValid() === false )
			{
				return false;
			}
		}
	}

	return true;
};

/**
	Context Menu Handler in Report Viewer.
	dcm == Display Context Menu
	@private
*/
CCognosViewer.prototype.dcm = function(event, selectNode)
{
	if (this.canDisplayContextMenu())
	{
		if (this.rvMainWnd.displayContextMenu(event, selectNode) != false)
		{
			if(this.sBrowser=='ie')
			{
				event.cancelBubble = true;
				event.returnValue = false;
			}
			else
			{
				event.stopPropagation();
				event.preventDefault();
			}
		}
	}
};

/**
 * Determines if the viewer should show a context menu
 * @private
 */
 CCognosViewer.prototype.canDisplayContextMenu = function()
 {
 	return (this.getStatus() != "prompting" && this.getStatus() != "working" && this.rvMainWnd != null && typeof this.bCanUseCognosViewerContextMenu != 'undefined' && this.bCanUseCognosViewerContextMenu);
 };

/**
	Handler for drill actions in Report Viewer.
	de == Drill Event
	@private
*/
CCognosViewer.prototype.de = function(event)
{
	var oDrillMgr = this.getDrillMgr();
	if (oDrillMgr)
	{
		oDrillMgr.singleClickDrillEvent(event, 'RV');
	}
};

/**
	@param {string} Message
	@private
*/
CCognosViewer.prototype.debug = function(sMsg)
{
	if (this.m_bDebug)
	{
		var sCallee = "";
		var oCaller = this.debug.caller;
		if (typeof oCaller == "object" && oCaller !== null)
		{
			sCallee = oCaller.toString().match(/function (\w*)/)[1];
		}
		if (!sCallee)
		{
			sCallee = '?';
		}
		alert(sCallee + ": " + sMsg);
	}
};

/**
	@param {string} sEvent Event name to call the callback functions for.
	@type boolean
	@return <i>true</i> if there was a callback associated with the event and that it's capture event was set to true. <i>false</i> otherwise.
	@private
*/
CCognosViewer.prototype.executeCallback = function(sEvent)
{
	var bEventWasCaptured = false;

	if (this.m_aCallback && this.m_aCallback.length)
	{
		for (var idxCallback = 0; idxCallback < this.m_aCallback.length; ++idxCallback)
		{
			var oCB = this.m_aCallback[idxCallback];

			if (oCB.m_sEvent == sEvent)
			{
				if (typeof oCB.m_oCallback == "function")
				{
					oCB.m_oCallback();
				}
				if (oCB.m_bCaptureEvent)
				{
					bEventWasCaptured = true;
				}
			}

		}
	}
	return bEventWasCaptured;
};

/**
	CAF context information.
	@return CAF encoded string.
	@type string
*/
CCognosViewer.prototype.getCAFContext = function()
{
	return this.m_sCAFContext;
};


/**
	Get the fault
	@return string
*/
CCognosViewer.prototype.getSoapFault = function()
{
	return this.m_sSoapFault;
}

/**
	Returns the identifiers of the columns related to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return array of identifiers of the columns making up this element.
	@type string[]
*/
CCognosViewer.prototype.getColumnContextIds = function(sId)
{
	return  this.getContextIds(sId, 2);
};

/**
	Conversation info (encoded string).
	@return CAF encoded string.
	@type string
*/
CCognosViewer.prototype.getConversation = function()
{
	return this.m_sConversation;
};

/**
 * Status of the ongoing report server conversation
 * @return conversation status
 * @type string
 */
CCognosViewer.prototype.getStatus = function()
{
	return this.m_sStatus;
};

/**
 * Returns the action state. This value will only be set if the action is in a interupted state (wait/prompting)
 * @return action state
 * @type string
 */
 CCognosViewer.prototype.getActionState = function()
 {
 	return this.m_sActionState;
 };

/**
	Get the name of the ref data item associated with the element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Name of the ref data item associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getDataItemName = function(sId)
{
	var sName = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aName = selectionController.getRefDataItem(sCtx);
			if (aName) {
				sName = aName;
			}
		}
	}
	return sName;
};

/**
	Get the Name of the data type associated with the element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Name of the data type associated with the element. Returns <code>null</code> if there is not any.
	@type int
*/
CCognosViewer.prototype.getDataType = function(sId)
{
	var sType = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aType = selectionController.getDataType(sCtx);
			if (aType) {
				sType = aType;
			}
		}
	}
	return sType;
};


/**
	Returns the level associated with the element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Depth (relative to the hierarchy) of the element. Returns <code>null</code> if there is not any.
	@type integer
*/
CCognosViewer.prototype.getDepth = function(sId)
{
	var sLevel = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aLevel = selectionController.getDepth(sCtx);
			if (aLevel) {
				sLevel = aLevel;
			}
		}
	}
	return sLevel;
};

/**
	@return CAF encoded string.
	@type string
	@private
*/
CCognosViewer.prototype.getDrillMgr = function()
{
	return this.m_oDrillMgr;
};


/**
	@return the subscription handler.
	@type object
	@private
*/
CCognosViewer.prototype.getSubscriptionManager = function()
{
	return this.m_oSubscriptionManager;
};


/**
	Execution Parameters (encoded string).
	@return CAF encoded string.
	@type string
*/
CCognosViewer.prototype.getExecutionParameters = function()
{
	return this.m_sParameters;
};

/**
	@private
	@return Gateway path.
	@type string
*/
CCognosViewer.prototype.getGateway = function()
{
	return this.m_sGateway;
};

/**
	Returns the Hierarchy Unique Name (HUN) associated to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Name (HUN) of the hierarchy associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getHierarchyUniqueName = function(sId)
{
	var sHun = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aHUN = selectionController.getHun(sCtx);
			if (aHUN) {
				sHun = aHUN;
			}
		}
	}
	return sHun;
};

/**
	Returns the Dimension Unique Name (DUN) associated to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Name (DUN) of the dimension associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getDimensionUniqueName = function(sId)
{
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aDUN = selectionController.getDun(sCtx);
			if (aDUN) {
				return aDUN;
			}
		}
	}
	return null;
};

/**
	@private
	@return Id Identifier for this instance of CCognosViewer.
	@type string
*/
CCognosViewer.prototype.getId = function()
{
	return this.m_sId;
};

/**
	Returns the Level Id (LUN) associated to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Identifier for the level associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getLevelId = function(sId)
{
	var sLevel = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
			if (selectionController != null) {
			var aLUN = selectionController.getLun(sCtx);
			if (aLUN) {
				sLevel = aLUN;
			}
		}
	}
	return sLevel;
};

/**
	Returns the Member Unique Name (MUN) associated to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Name (MUN) of the member associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getMemberUniqueName = function(sId)
{
	var sMUN = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aMUN = selectionController.getMun(sCtx);
			if (aMUN) {
				sMUN = aMUN;
			}
		}
	}
	return sMUN;
};

/**
	This function return the name of the javascript reference (variable) to this object. The default is "window" if the id is invalid.
	@private
	@return Id Identifier for this instance of CCognosViewer.
	@type string
*/
CCognosViewer.prototype.getObjectId = function()
{
	var sObjId = "window";
	if (typeof this.getId() == "string") {
		sObjId = "oCV" + this.getId();
	}
	return sObjId;
};

/**
	Returns the Query Id associated to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Model id associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getQueryModelId = function(sId)
{
	var sQuery = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aQMID = selectionController.getQueryModelId(sCtx);
			if (aQMID) {
				sQuery = aQMID;
			}
		}
	}
	return sQuery;
};

/**
	Returns the Query name associated to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Query name associated with the element. Returns <code>null</code> if there is not any.
	@type string
*/
CCognosViewer.prototype.getQueryName = function(sId)
{
	var sQuery = null;
	var sCtx = this.findCtx(sId).split("::")[0];
	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			var aQuery = selectionController.getRefQuery(sCtx);
			if (aQuery) {
				sQuery = aQuery;
			}
		}
	}
	return sQuery;
};

CCognosViewer.prototype.getContextIds = function(sId, index)
{
	var aIds = [];
	var sCtx = this.findCtx(sId);
	if (sCtx)
	{
		var aIDparts = sCtx.split("::");
		if (aIDparts && aIDparts.length > 1 && index < aIDparts.length)
		{
			aIds = aIDparts[index].split(":");
		}
	}
	return aIds;
};


/**
	Returns the identifiers of the rows related to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return array of identifiers of the rows making up this element.
	@type string[]
*/
CCognosViewer.prototype.getRowContextIds = function(sId)
{
	return this.getContextIds(sId, 1);
};

/**
	Returns the identifiers of the page related to an element.
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return array of identifiers of the rows making up this element.
	@type string[]
 */
CCognosViewer.prototype.getPageContextIds = function(sId)
{
	return this.getContextIds(sId, 3);
};

/**
	@private
	@param {string} sKey the key of the string
	@type string
	@return The localized string matching the key. Returns the key if it there is not string associated.
*/
CCognosViewer.prototype.getString = function(sKey)
{
	if (this.oStrings && this.oStrings[sKey]) {
		return this.oStrings[sKey];
	}
	return sKey;
};

/**
	@private
	@type CViewerManager
	@return A CViewerManager instance or a "window" object if the former do not exists.
*/
CCognosViewer.prototype.getRV = function()
{
	if (typeof this.m_oCVMgr == "object")
	{
		return this.m_oCVMgr;
	}
	return window;
};

/**
	@private
	@type array
	@return available secondary requests
*/
CCognosViewer.prototype.getSecondaryRequests = function()
{
	return this.m_aSecRequests;
};

/**
	@private
	@type string
	@return session prompts (CAF string)
*/
CCognosViewer.prototype.getSessionPrompts = function()
{
	return this.m_sSessionPrompts;
};

/**
	Tracking info (encoded string).
	@type string
	@return CAF encoded string.
*/
CCognosViewer.prototype.getTracking = function()
{
	return this.m_sTracking;
};

/**
	@private
	@type string
	@param {string} sId Identifier or a HTML element
	@return Returns an empty string if not found.
*/
CCognosViewer.prototype.findCtx = function(sId)
{
	var sCtx = "";
	if (typeof sId == "string")
	{
		// return sId if it matches something in the context data
		var sRefDataItem = sId.split("::")[0];
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			if (selectionController.isContextId(sRefDataItem))
			{
				sCtx = sId;
			}
		}
	}
	if (!sCtx)
	{
		var oHTMLElement = this.findElementWithCtx(sId);
		if (oHTMLElement)
		{
			sCtx = oHTMLElement.getAttribute("ctx");
		}
	}
	return sCtx;
};

/**
	@private
	@type HTMLelement
	@param {string} sId Identifier or a HTML element
	@return Returns a HTML element with a <i>ctx</i> attribute. Processed recursively on the children. Returns <code>null</node> if there is not any.
*/
CCognosViewer.prototype.findElementWithCtx = function(sId)
{
	var oElement = sId;
	if (typeof sId == "string") {
		oElement = this.findElementWithCtx(document.getElementById(sId));
	}
	if (oElement)
	{
		if (oElement.getAttribute && oElement.getAttribute("ctx"))
		{
			return oElement;
		}
		for (var idxChild = 0; idxChild < oElement.childNodes.length; idxChild++)
		{
			var oChild = this.findElementWithCtx(oElement.childNodes[idxChild]);
			if (oChild) {
				return oChild;
			}
		}
	}
	return null;
};

/**
	Returns the use value associated to an element.
	@type string
	@param {string} sId Identifier or the HTML element with a ctxId attribute.
	@return Use value associated with the element. Returns <code>null</code> if there is not any.
*/
CCognosViewer.prototype.getUseValue = function(sId)
{
	var sVal = null;

	var sCtx = this.findCtx(sId).split("::")[0];

	if (sCtx) {
		var selectionController = this.getSelectionController();
		if (selectionController != null) {
			sVal = selectionController.getUseValue(sCtx);
		}
	}
	return sVal;
};

/**
	@private
	@param {object} oProp Properties to add to this instance of CCognosViewer, like flags and strings.
*/
CCognosViewer.prototype.init = function(oProperties)
{
	if (oProperties && typeof oProperties == "object")
	{
		for (var sProp in oProperties)
		{
			this[sProp] = oProperties[sProp];
		}
	}
};

/**
 * @private
 * Method that should only be called when the user hits the back button in the browser
 */
CCognosViewer.prototype.initStandaloneViewerState = function(originalState)
{
	var backJaxForm = document.getElementById('formBackJax' + this.getId());
	if (typeof backJaxForm != "undefined" && backJaxForm != null && typeof backJaxForm.responseText != "undefined" && backJaxForm.responseText.value.length > 0)
	{
		this.processResponseText(backJaxForm.responseText.value);
	}
	else
	{
		this.processResponseState(originalState);
	}
};

/**
 * @private
 * @Saves the responseXML for a completed request
 */
CCognosViewer.prototype.saveBackJaxInformation = function(responseText)
{
	var backJaxForm = document.getElementById('formBackJax' + this.getId());
	if (typeof backJaxForm != "undefined" && backJaxForm != null)
	{
		if (typeof backJaxForm.responseText != "undefined")
		{
			backJaxForm.responseText.value = responseText;
		}
	}
};

/**
	Pre-selects a node prior handling of the context menu.
	pcc == Page Context Clicked
	@private
*/
CCognosViewer.prototype.pcc = function(evt)
{
	var selectionController;
	try
	{
		selectionController = eval("oCVSC" + this.getId());
	}
	catch(e)
	{
		selectionController = null;
	}

	if(selectionController != null)
	{
		selectionController.pageContextClicked(evt);
	}
};

/**
 * @private
 * @param {XMLHTTP response} oResponse
 */
CCognosViewer.prototype.isValidAjaxResponse = function(responseXML)
{
	return (responseXML != null && responseXML.childNodes.length != 0 && responseXML.childNodes[0].nodeName != "parsererror");
};

/**
 * @private
 */
CCognosViewer.prototype.resubmitInSafeMode = function()
{
	//re-submit the request in "page" mode. We'll need to inform the user we're doing this (Post beta)
	this.setUsePageRequest(true);
	this.envParams["cv.useAjax"] = "false";
	this.m_oServerRequest.clearRequest();
	this.sendRequest(this["LAST_ACTION_PARAMS"].param1);
};

/**
	@private
	@param {XMLHTTP response} oResponse
*/
CCognosViewer.prototype.processResponse = function(oResponse)
{
	var oResponseState = null;

	try
	{
		var sContentType = oResponse.getResponseHeader("Content-type");
		if(sContentType.indexOf("text/html") != -1)
		{
			// make sure we clear the tracking and conversation before we unload the viewer
			// or we'll trigger a cancel request which will more then likely cause another fault.
			this.m_sTracking = "";
			this.m_sConversation = "";
			clearLastAction();

			// this is an HTML response, most likely a fault page.
			document.write(oResponse.responseText);
		}
		// application/xml should only be used for data only response (i.e. no HTML)
		else if (sContentType.indexOf("application/xml") != -1)
		{
			var responseXML = oResponse.responseXML;
			if(this.isValidAjaxResponse(responseXML) == false)
			{
				// try re-parsing client side
				responseXML = XMLBuilderLoadXMLFromString(oResponse.responseText);
			}

			this.processResponseXML(responseXML, null);
		}
		else
		{
			var responseText = oResponse.responseText;

			if (responseText == null)
			{
				this.resubmitInSafeMode();
			}
			this.processResponseText(responseText);
		}
	}
	catch (e)
	{
		oResponseState = null;
		this.executeCallback("error");
	}
}

/**
	@private
	@param {XMLHTTP response} sText
	@param {Boundary from the header} sText
*/
CCognosViewer.prototype.processResponseText = function (sText)
{
	var boundaryIndex = sText.indexOf("</state></xml>");
	if (boundaryIndex == -1)
	{
		this.resubmitInSafeMode();
	}

	// length of "</state></xml>"
	boundaryIndex += 14;

	var xmlPart = sText.substring(0, boundaryIndex);
	var responseXML = XMLBuilderLoadXMLFromString(xmlPart);

	var resposneHTML = sText.substring(boundaryIndex);

	if (this.processResponseXML(responseXML, resposneHTML))
	{
		if (this.getStatus() != "working" && this.getStatus() != "stillWorking")
		{
			clearLastAction();
		}
		this.saveBackJaxInformation(sText);
	}
}

/**
	@private
	@param XML element
	@param responseHTML
*/
CCognosViewer.prototype.processResponseXML = function (responseXML, responseHTML)
{
	if(this.isValidAjaxResponse(responseXML) == false)
	{
		this.resubmitInSafeMode();
		return false;
	}
	else if (processAuthenticationFault(responseXML))
	{
		return false;
	}
	else
	{
		try
		{
			var stateData = responseXML.getElementsByTagName("state");
			if (stateData != null && stateData.length > 0)
			{
				if (typeof stateData[0].text != "undefined")
				{
					oResponseState = eval("(" + stateData[0].text + ")");
				}
				else
				{
					oResponseState = eval("(" + stateData[0].textContent + ")");
				}
			}
			if (oResponseState)
			{
				var sStatus = oResponseState.status;
				var bWaitPage = sStatus == "working" || sStatus == "stillWorking";

				if (!bWaitPage && this.sBrowser == 'moz')
				{
					var oRVContent = document.getElementById('RVContent' + this.getId());
					if (oRVContent)
					{
						if (typeof oResponseState.outputFormat != 'undefined' && oResponseState.outputFormat == 'XML')
						{
							oRVContent.style.overflow = 'hidden';
						}
						else
						{
							oRVContent.style.overflow = 'auto';
						}
					}
				}

				if (typeof responseHTML == "string")
				{
					var oRVContent = document.getElementById('RVContent' + this.getId());
					if (!bWaitPage && oRVContent)
					{
						oRVContent.scrollTop=0;
					}


					if (bWaitPage)
					{
						this.m_waitPage.initializeWaitPage(responseHTML);
					}
					else if(this.processResponseOutput(responseHTML) === false)
					{
						return;
					}
				}

				this.gbPromptRequestSubmitted = false;

				this.processResponseState(oResponseState);
			}
		}
		catch (e)
		{
			oResponseState = null;
			this.executeCallback("error");
			return false;
		}
	}
	return true;
};

/**
	@private
	@param {string} sResponseText
	@return (boolean)
*/
CCognosViewer.prototype.processResponseOutput = function(sResponseText)
{

	try
	{

		if(this.m_undoStack.length > 0)
		{
			this.m_undoStack[this.m_undoStack.length-1].m_bRefreshPage = true;
		}

		this.pageNavigationObserverArray = [];

		// IE bug: innerHTML do not handle <form>s, the page will be ignored if there is a <form> tag around the HTML code.
		// The main form (formWarpRequest) is wrapped around the <div> we are using for the report, we should not have a <form> in the output anyway.
		var sHTML = sResponseText.replace(/<form[^>]*>/gi,"").replace(/<\/form[^>]*>/gi,"");

		this.m_sHTML = sHTML;
		this.setHasPrompts(false);

		var oRVContent = document.getElementById("RVContent" + this.getId());
		var oReportDiv = document.getElementById("CVReport" + this.getId());

		// if the report contains prompts, then set the display to none to fix a possible flicker for
		// when the prompt sizes itself (trakker 531880)
		if (sHTML.match(/prompt\/control\.js|PRMTcompiled\.js/gi))
		{
			this.setHasPrompts( true );
			oRVContent.style.display = "none";
		}

		if (window.gScriptLoader)
		{
			// Extract the style and css elements from the HTML response
			sHTML = window.gScriptLoader.extractStyles(sHTML);
			sHTML = window.gScriptLoader.extractCSS(sHTML);

			if(window.gScriptLoader.containsAjaxWarnings())
			{
				this.resubmitInSafeMode();
				return false;
			}

			// Now set the innerHTML with the parsed up HTML response
			if (this.sBrowser == 'ie')
			{
				// IE specific 'fix' where if sHTML has script tags at the beginning they won't be loaded into the DOM. Adding
				// a valid tag first causes all subsequent scripts to be loaded into the DOM.
				sHTML = "<span style='display:none'>&nbsp;</span>" + sHTML;
			}
			oReportDiv.innerHTML = sHTML;

			window.gScriptLoader.loadScriptsFromDOM(oReportDiv);

			// Apply the extracted styles
			window.gScriptLoader.applyCSS();
			window.gScriptLoader.applyStyles();

			if(window.gScriptLoader.containsAjaxWarnings())
			{
				this.resubmitInSafeMode();
				return false;
			}

			// run the extracted scripts
			window.gScriptLoader.executeScripts(oRVContent);
		}
		else
		{
			oReportDiv.innerHTML = sHTML;
			oRVContent.style.display = "block";
		}
	}
	catch (e)
	{
	}

	return true;
};

/**
	@private
	@param {object} oState
*/
CCognosViewer.prototype.processResponseState = function(oState)
{
	this.setStatus(oState.status);
	this.setConversation(oState.conversation);
	this.setTracking(oState.tracking);
	this.setCAFContext(oState.caf);
	this.setExecutionParameters(oState.parameters);
	this.setSecondaryRequests(oState.secondaryRequests);
	this.setSessionPrompts(oState.session_prompts);
	this.setActionState(oState.action_state);

	var bShowWaitPage = ( oState.status == "working" || oState.status == "stillWorking" || oState.status == "default" );
	if( !bShowWaitPage )
	{
		this.removeTransparentBackgroundLayer();
	}

	if (typeof g_firefoxPluginHelper != "undefined" && g_firefoxPluginHelper != null)
	{
		g_firefoxPluginHelper.processResponseState(oState, this);
	}

	if(typeof oState.clientunencodedexecutionparameters != "undefined")
	{
		var formWarpRequest = document.getElementById("formWarpRequest" + this.getId());
		if(formWarpRequest != null && typeof formWarpRequest["clientunencodedexecutionparameters"] != "undefined")
		{
			formWarpRequest["clientunencodedexecutionparameters"].value = oState.clientunencodedexecutionparameters;
		}

		if(typeof document.forms["formWarpRequest"] != "undefined" && typeof document.forms["formWarpRequest"]["clientunencodedexecutionparameters"] != "undefined")
		{
			document.forms["formWarpRequest"]["clientunencodedexecutionparameters"].value = oState.clientunencodedexecutionparameters;
		}
	}

	if (oState.sResponseSpecification)
	{
		this.updateResponseSpecification(oState.sResponseSpecification);
	}

	if(typeof this.envParams != "undefined")
	{
		this.envParams["ui.primaryAction"] = oState.primary_action;
	}

	if(this.getStatus() == "complete")
	{
		this.m_undoStack.push(new CognosViewerSession(this));
	}

	if (bShowWaitPage)
	{
		if (oState.status == "working" || oState.status == "default")
		{
			var waitTable = document.getElementById("CVWaitTable" + this.getId());
			if (waitTable && waitTable.getAttribute("simpleDialog") == "true")
			{
				this.m_waitPage.destroy();
				waitTable = null;
			}

			if (typeof waitTable == 'undefined' || waitTable == null || waitTable.parentNode.id == "CVWait" + this.getId())
			{
				this.m_waitPage.show(this.bIsSavedReport);
			}
		}
		if(this.getUsePageRequest() == true && window.history.length > 0 && document.progress){
			window.history.go(+1);
		}
		// add a delay for this callback to allow the server request to clean up, and not block any futher server requests
		setTimeout("oCV"+this.getId()+".executeCallback(\"wait\");",10);
	}
	else if(oState.status == "cancel")
	{
		this.executeCallback("cancel");
	}
	else if (oState.status == "fault")
	{
		this.setSoapFault(oState.soapFault);
		this.m_waitPage.hide();
		this.executeCallback("fault");
	}
	else
	{
		if (oState.status != "prompting" || !this.executeCallback("prompt"))
		{

			if (this.rvMainWnd)
			{
				this.writeNavLinks(this.getSecondaryRequests().join(" "));
				this.updateLayout(oState.status);
				var oToolbar = this.rvMainWnd.getToolbar();
				if (oToolbar)
				{
					this.rvMainWnd.updateToolbar(oState.outputFormat);
					oToolbar.draw();
				}

				var oBannerToolber = this.rvMainWnd.getBannerToolbar();
				if (oBannerToolber)
				{
					oBannerToolber.draw();
				}
			}

			this.m_waitPage.hide();
			this.executeCallback("done");
		}
	}

	var oReportDiv = document.getElementById("CVReport" + this.getId());
	if (typeof oReportDiv != 'undefined' && oReportDiv != null)
	{
		oReportDiv.style.display = '';
	}
};

/**
	Helper function to generate one link for the page navigation.
	@private
	@param {object} oLink A object that contains the link info. oLink.text is the string to show to the user. oLink.sImg is the name of the icon to show for the normal (active) state. oLink.sImgDisabled is the name of the icon for the disabled state.
	@param {string} sRequest The request to send when the link is clicked. Possible values are <code>firstPage</code>, <code>nextPage</code>, <code>previousPage</code> and <code>lastPage</code>.
	@param {string} bActive True if the link should be active (normal state). False to disabled the link.
	@type string
	@return The HTML string that makes up the navigation links.
*/
CCognosViewer.prototype.writeNavLink = function(oLink, sRequest, bActive)
{
	var sPattern = "";
	if (bActive)
	{
		sPattern =
			'<td class="portlet-table-text" nowrap="nowrap">' +
				'<img src="LINK_IMG" width="15" height="15" alt="LINK_TEXT" title="LINK_TEXT">' +
			'</td>' +
			'<td class="portlet-table-text" nowrap="nowrap">' +
				'<a href="#" onclick="oCV' + this.getId() + '.sendRequest(new CCognosViewerRequest(\'LINK_REQUEST\'));return false;"' +
					(this.sBrowser == 'ie' ? 'accessKey="P"' :'') +
				'>LINK_TEXT</a>&#160;' +
			'</td>';
	}
	else
	{
		sPattern =
			'<td class="portlet-table-text" nowrap="nowrap">' +
				'<img src="LINK_IMG" width="15" height="15" alt="LINK_TEXT" title="LINK_TEXT">' +
			'</td>' +
			'<td class="portlet-table-text" nowrap="nowrap">LINK_TEXT&#160;</td>';
	}

	var sImg = this.sSkin + (!bActive && oLink.sImgDisabled ? oLink.sImgDisabled : oLink.sImg);
	return sPattern.replace(/LINK_REQUEST/g, sRequest).replace(/LINK_TEXT/g, oLink.sText).replace(/LINK_IMG/g, sImg);
};

/**
	Loads up the necessary info for the navigation links (localized strings, icon names, skin to use).
	@private
*/
CCognosViewer.prototype.loadNavLinks = function()
{
	// load navlinks string and image path dynamically, synchronously.
	var sText = window.gScriptLoader.loadFile(this.getGateway(), "b_action=xts.run&m=portal/report-viewer-navlinks.xts");
	if (sText)
	{
		this.init(eval("(" + sText + ")"));
	}
};

/**
	Build the HTML code for the navigation links and update them in the UI.
	@param {string} sSR space separated secondary requests
	@private
*/
CCognosViewer.prototype.writeNavLinks = function(sSR)
{
	var oNavLinksDiv = document.getElementById("CVNavLinks" + this.getId());
	if (oNavLinksDiv)
	{
		if (typeof this.oNavLinks != "object" || typeof sSR != "string" || !sSR.match(/\bfirstPage\b|\bpreviousPage\b|\bnextPage\b|\blastPage\b|\bplayback\b/i))
		{
			oNavLinksDiv.style.display = "none";
			return;
		}

		oNavLinksDiv.style.display = (document.all ? "block" : "table-cell");
		var aLinks = [
			this.writeNavLink(this.oNavLinks.oFirst, 'firstPage', sSR.match(/\bfirstPage\b/gi)),
			this.writeNavLink(this.oNavLinks.oPrevious, 'previousPage', sSR.match(/\bpreviousPage\b/gi)),
			this.writeNavLink(this.oNavLinks.oNext, 'nextPage', sSR.match(/\bnextPage\b/gi)),
			this.writeNavLink(this.oNavLinks.oLast, 'lastPage', sSR.match(/\blastPage\b/gi))];

		var sHTML = "";
		if (this.sBrowser != 'ie')
		{
			sHTML += '<a name="jumptonavlinks"><img src="' + this.getWebContentRoot() + '/common/images/spacer.gif" width="1" height="1" border="0"' +
				' alt="' + this.getString('sNavLinksTooltip') + '" title="' + this.getString('sNavLinksTooltip') + '"></a>';
		}
		sHTML += '<table border="0" cellpadding="0" cellspacing="0" class="pageControls"><tbody><tr>';

		sHTML += aLinks.join('');

		if ( sSR.match(/\bplayback\b/gi) )
		{
			sHTML += '<td width="100%" align="right" valign="bottom" class="portlet-table-text" style="height: 15px">' +
				'<table border="0" cellpadding="0" cellspacing="0" class="pageControls">' +
					'<tr>' +
						'<td valign="bottom" class="portlet-table-text">' +
							'<table border="0" cellpadding="0" cellspacing="0" class="pageControls">' +
								'<tr>' +
									'<td align="right" width="100%">' +
										'<img src="' + this.getWebContentRoot() + '/rv/images/playback.gif" width="15" height="15"' +
											' alt="' + this.getString('sPlayback') + '" tooltip="' + this.getString('sPlayback') + '">' +
									'</td>' +
								'</tr>' +
							'</table>' +
						'</td>' +
						'<td valign="bottom" class="portlet-table-text">' +
							'<a href="javascript:void(0);" onclick="oCV' + this.getId() + '.sendRequest(new CCognosViewerRequest(\'playback\'))" accessKey="P">' +
								this.getString('sPlayback') +
							'</a>&#160;' +
						'</td>' +
					'</tr>' +
				'</table>' +
			'</td>';
		}
		sHTML += '</tr></tbody></table>';
		oNavLinksDiv.innerHTML = sHTML;
	}
	else
	{
		setTimeout('oCV' + this.getId() + '.writeNavLinks("' + sSR + '");', 100);
	}
};

/**
	@private
	@type CDispatcher
*/
CCognosViewer.prototype.getDispatcher = function()
{
	if (!this.m_oDispatcher)
	{
		this.m_oDispatcher = new CDispatcher();
	}
	return this.m_oDispatcher;
};

/**
	@private
	@param {CCognosViewerRequest} oRequest The request to send.
	@type string
	@return the URL to execute.
*/
CCognosViewer.prototype.generateRequestParams = function(oRequest)
{
	var oParams = {};
	// generate server specific request params
	this.m_oServerRequest.generateRequestParams(oParams, this.envParams);

	oParams["ui.action"] = oRequest.getAction();

	if(this.getUsePageRequest() == true)
	{
		var aOptions = oRequest.m_oOptions.keys();
		for (var idxOption = 0; idxOption < aOptions.length; idxOption++)
		{
			oParams[aOptions[idxOption]] = oRequest.getOption(aOptions[idxOption]);
		}

		var aParameters = oRequest.m_oParams.keys();
		for (var idxParameter = 0; idxParameter < aParameters.length; idxParameter++)
		{
			oParams[aParameters[idxParameter]] = oRequest.getParameter(aParameters[idxParameter]);
		}

		for(param in this.envParams)
		{
			if(typeof oParams[param] == "undefined" && param != "cv.actionState")
			{
				oParams[param] = this.envParams[param];
			}
		}

		if (this.getActionState() != "" && (oRequest.getAction() == "wait" || oRequest.getAction() == "forward" || oRequest.getAction() == "back"))
		{
			oParams["cv.actionState"] = this.getActionState();
		}

		var sEP = this.getExecutionParameters();
		if (sEP)
		{
			oParams.executionParameters = sEP;
		}

		oParams["ui.conversation"] = this.getConversation();
		oParams.m_tracking = this.getTracking();
		if (this.envParams["ui.routingServerGroup"] != null)
		{
			oParams["ui.routingServerGroup"] = this.envParams["ui.routingServerGroup"];
		}
	}
	else
	{
		if (this.getActionState() != "" && (oRequest.getAction() == "wait" || oRequest.getAction() == "forward" || oRequest.getAction() == "back"))
		{
			oParams["cv.actionState"] = this.getActionState();
		}

		if (typeof this.envParams["ui.primaryAction"] != "undefined")
		{
			oParams["ui.primaryAction"] = this.envParams["ui.primaryAction"];
		}

		if (this.envParams["cv.header"] != null)
		{
			oParams["cv.header"] = this.envParams["cv.header"];
		}
		if (this.envParams["cv.toolbar"] != null)
		{
			oParams["cv.toolbar"] = this.envParams["cv.toolbar"];
		}

		if (this.envParams["m_session"] != null)
		{
			oParams["m_session"] = this.envParams["m_session"];
		}

		if (this.envParams["ui.backURL"] != null)
		{
			oParams["errURL"] = encodeURIComponent(this.envParams["ui.backURL"]);
		}

		if(typeof this.envParams["ui.errURL"] != "undefined")
		{
			oParams["errURL"] = encodeURIComponent(this.envParams["ui.errURL"]);
		}

		if (this.envParams["cv.showFaultPage"] != null)
		{
			oParams["cv.showFaultPage"] = this.envParams["cv.showFaultPage"];
		}

		if (this.envParams["cv.debugDirectory"] != null)
		{
			oParams["cv.debugDirectory"] = this.envParams["cv.debugDirectory"];
		}

		var sEP = this.getExecutionParameters();
		if (sEP)
		{
			oParams.executionParameters = encodeURIComponent(sEP);
		}

		var sSP = this.getSessionPrompts();
		if (sSP)
		{
			oParams.session_prompts = encodeURIComponent(sSP);
		}

		var aOptions = oRequest.m_oOptions.keys();
		for (var idxOption = 0; idxOption < aOptions.length; idxOption++)
		{
			oParams[ encodeURIComponent( aOptions[idxOption] ) ] = encodeURIComponent( oRequest.getOption(aOptions[idxOption]) );
		}

		oParams["ui.conversation"] = encodeURIComponent(this.getConversation());
		oParams.m_tracking = encodeURIComponent(this.getTracking());

		var aParameters = oRequest.m_oParams.keys();
		for (var idxParameter = 0; idxParameter < aParameters.length; idxParameter++)
		{
			oParams[ encodeURIComponent( aParameters[idxParameter] ) ] = encodeURIComponent( oRequest.getParameter(aParameters[idxParameter]) );
		}

		var sCAF = this.getCAFContext();
		if (sCAF)
		{
			oParams["ui.cafcontextid"] = sCAF;
		}

		if (this.envParams["ui.routingServerGroup"] != null)
		{
			oParams["ui.routingServerGroup"] = encodeURIComponent(this.envParams["ui.routingServerGroup"]);
		}
	}

	return oParams;
};

/**
	Sends a request to the server using an Ajax request.
	@param {CCognosViewerRequest} oRequest The request to send.
*/
CCognosViewer.prototype.sendRequest = function(oRequest)
{
	if (this["LAST_ACTION_PARAMS"] == "undefined" || this["LAST_ACTION_PARAMS"] == null || this["LAST_ACTION_PARAMS"] == "")
	{
		this["LAST_ACTION_PARAMS"] = {"param1": oRequest};
	}
	this["LAST_ACTION"] = "sendRequest";


	var sAction = oRequest.getAction();

	this.m_oServerRequest.setAction(sAction);
	var oParams = this.generateRequestParams(oRequest);
	for (oParam in oParams)
	{
		this.m_oServerRequest.addArgument(oParam, oParams[oParam]);
	}
	this.m_oServerRequest.setRequestURL(this.getGateway());

	var callBack = oRequest.getCallback();
	if(callBack == null)
	{
		this.m_oServerRequest.setCallback(this);
	}
	else
	{
		this.m_oServerRequest.setCallback(callBack);
	}

	if(this.getUsePageRequest() === true)
	{
		this.setKeepSessionAlive(true);
		if(typeof document.progress != "undefined")
		{
			setTimeout("document.progress.src=\"" + this.getWebContentRoot() + "/skins/corporate/branding/progress.gif" + "\";", 1);
		}
	}

	if( ( sAction === "forward" || sAction === "back" ) && typeof this.m_viewerFragment == "undefined" )
	{
		this.createTransparentBackgroundLayer();
	}

	this.m_oServerRequest.execute();

	var waitTable = document.getElementById("CVWaitTable" + this.getId());
	if (this.getId() == "_NS_" && sAction != "cancel" && (!waitTable || (this.m_waitPage && this.m_waitPage.m_waitPageDiv && this.m_waitPage.m_waitPageDiv.style.display == "none")))
	{
		this.m_waitPage.destroy();
		setTimeout("oCV"+this.getId()+".m_waitPage.showSimpleWaitDialog(oCV" + this.getId() + ")",10);
	}
};

/**
 *   Ignores mouse clicks in the background layer when request is running
 */
function CVBackgroundLayer_ignoreMouseClick( e )
{
	if (e.returnValue) { e.returnValue = false; }
	else if (e.preventDefault) { e.preventDefault(); }
	else { return false; }
}

/**
 * Creates a transparent background to be displayed when request is running so that mouse clicks can be ignored
 */
CCognosViewer.prototype.createTransparentBackgroundLayer = function()
{
	this.removeTransparentBackgroundLayer();

	var oBL = document.createElement( 'div' );
	oBL.id = CV_BACKGROUND_LAYER_ID;
	oBL.style.display = 'none';
	oBL.style.position = 'absolute';

	oBL.style.top = "0px";
	oBL.style.left = "0px";
	oBL.style.zIndex = 98;

	oBL.style.width = "100%";
	oBL.style.height = "100%";

	oBL.style.backgroundColor = 'rgb(238, 238, 238)'; //arbitrary colour
	oBL.style.opacity = '0';
	oBL.style.filter = 'alpha(opacity:0)';

	oBL.innerHTML = '<table tabindex="1" width="100%" height="100%"><tr><td onclick="CVBackgroundLayer_ignoreMouseClick(event)"></td></tr></table>';
	oBL.style.display = 'inline';

	document.body.appendChild( oBL );
}

/**
 * Removes the transparent background layer
 */
CCognosViewer.prototype.removeTransparentBackgroundLayer = function()
{
	var oBL = document.getElementById( CV_BACKGROUND_LAYER_ID );
	if( oBL )
	{
		oBL.parentNode.removeChild( oBL );
	}
}

/**
 * Closes active http connections. Note this method will not issue a cancel. If you need to cancel an RSVP request, use the cancel method
 * @return (boolean)
 */
CCognosViewer.prototype.closeActiveHTTPConnection = function()
{
	return this.m_oServerRequest.cancel();
};

/**
 * Returns true if the viewer is in asynch mode, and the request is cancellable
 * @return (boolean)
 */
 CCognosViewer.prototype.canCancel = function()
 {
 	var sTracking = this.getTracking();
	var sConversation = this.getConversation();
	var sStatus = this.getStatus();

	return sTracking != "" && sConversation != "" && (sStatus != "complete");
 };

/**
 * Cancels the current request, and restores the viewer back to the previous state.
 */
CCognosViewer.prototype.cancel = function(hrefLink)
{
	if (this.getWaitPageImpl().cancelSubmitted())
	{
		return;
	}
	this.getWaitPageImpl().setCancelSubmitted(true);
	this.removeTransparentBackgroundLayer();

	this.m_oServerRequest.cancel();

	if(this.canCancel() === true)
	{
		//before we cancel, verify we have a conversation and tracking
		var sTracking = this.getTracking();
		var sConversation = this.getConversation();

		var cognosViewerRequest = new CCognosViewerRequest("cancel");

		if(this.m_undoStack.length > 0)
		{
			var cognosViewerUndo = 	this.m_undoStack.pop();

			this.m_sConversation = cognosViewerUndo.m_sConversation;
			this.m_sParameters = cognosViewerUndo.m_sParameters;
			this.m_envParams = cognosViewerUndo.envParams;
			this.m_sStatus = "complete";

			if(cognosViewerUndo.m_bRefreshPage == true)
			{
				var undoSpec = "<CognosViewerUndo>";
				undoSpec += "<conversation>"
				undoSpec += this.m_sConversation;
				undoSpec += "</conversation>"
				undoSpec += "</CognosViewerUndo>";
				cognosViewerRequest.addParameter("cv.previousSession", undoSpec);
			}
			else
			{
				this.m_undoStack.push(cognosViewerUndo);
				cognosViewerRequest.setCallback(function(){});
				this.m_waitPage.hide();
			}
		}

		this.sendRequest(cognosViewerRequest);
		this.setTracking("");
	}
	else if (typeof this.envParams != "undefined" && (this.envParams["ui.primaryAction"] == "authoredDrillThrough" || this.envParams["ui.primaryAction"] == "authoredDrillThrough2"))
	{
		this.rvMainWnd.executePreviousReport(-1);
	}
	else
	{
		executeBackURL(this.getId());
	}
};

/**
 *	Sends a wait request to the report server. If the current status is not "working" or "stillWorking", the request will not be sent
 *  @return (boolean)
 */
CCognosViewer.prototype.wait = function()
{
	if(this.m_sStatus == "working" || this.m_sStatus == "stillWorking")
	{
		this.sendRequest(new CCognosViewerRequest('wait'));
		return true;
	}

	return false;
};

/**
	@param {string} sValue CAF encoded string.
*/
CCognosViewer.prototype.setCAFContext = function(sValue)
{
	this.m_sCAFContext = sValue;
};

/**
	@param {string} sXML XML for the context.
*/
CCognosViewer.prototype.setContextInfo = function(sXML)
{
	this.m_sContextInfoXML = sXML;
};

/**
	@param {string} sValue CAF encoded string.
*/
CCognosViewer.prototype.setConversation = function(sValue)
{
	this.m_sConversation = sValue;
};

/**
	@param {string} sValue CAF encoded string.
*/
CCognosViewer.prototype.setActionState = function(sValue)
{
	this.m_sActionState = sValue;
};

/**
 * Sets the conversation status
 * @param string (conversation status)
 */
 CCognosViewer.prototype.setStatus = function(sStatus)
 {
 	this.m_sStatus = sStatus;
 }

/**
	@param {bool} bDebug Enable/disable debugging in {@link CCognosViewer}.
	@private
*/
CCognosViewer.prototype.setDebug = function(bDebug)
{
	this.m_bDebug = bDebug;
};

/**
	@param {string} sValue CAF encoded string.
*/
CCognosViewer.prototype.setExecutionParameters = function(sValue)
{
	this.m_sParameters = sValue;
};

/**
	@param {string} sXML XML for the metadata.
*/
CCognosViewer.prototype.setMetadataInfo = function(sXML)
{
	this.m_sMetadataInfoXML = sXML;
};

/**
	@param {array} aValue
*/
CCognosViewer.prototype.setSecondaryRequests = function(aValue)
{
	if (aValue) {
		this.m_aSecRequests = aValue;
	}
	else {
		this.m_aSecRequests = [];
	}
};

/**
	@param {string} sValue
*/
CCognosViewer.prototype.setSessionPrompts = function(sValue)
{
	this.m_sSessionPrompts = sValue;
};

/**
	@param {string} sValue CAF encoded string.
*/
CCognosViewer.prototype.setTracking = function(sValue)
{
	this.m_sTracking = sValue;
};

/**
 	@param (string) sValue fault code
 */
CCognosViewer.prototype.setSoapFault = function(sValue)
{
	this.m_sSoapFault = sValue;
};

CCognosViewer.prototype.showExcel = function(sURL)
{
	if( this.envParams["cv.excelWindowOpenProperties"] )
	{
		window.open(sURL, "", this.envParams["cv.excelWindowOpenProperties"]);
	}
	else
	{
		window.open(sURL, "", "");
	}

	var doPostBack = document.forms["formWarpRequest" + this.getId()].elements["ui.postBack"];
	var backURL = document.forms["formWarpRequest" + this.getId()].elements["ui.backURL"];
	if (doPostBack && doPostBack.value)
	{
		setTimeout('oCV' + this.getId() + '.getRV().doPostBack();', 100);
	}
	else if (backURL && backURL.value)
	{
	    if (backURL.value.length < 2048)
	    {
		    setTimeout('location.replace("' + backURL.value + '");', 100);
        }
        else
        {
	        var backURL = decodeURIComponent(backURL.value);
	        var URLandParameters = backURL.split("?");
	        var backURLForm = document.createElement("form");

	        backURLForm.style.display = "none";
	        backURLForm.setAttribute("method", "post");
	        backURLForm.setAttribute("action", URLandParameters[0]);

	        var parameterList = URLandParameters[1].split("&"); // must be ampersand symbol

	        for(var nextParameter = 0; nextParameter < parameterList.length; nextParameter++)
	        {
		        // We cannot use "split" here using "=" because there are "=" within the parameters
		        // that must be kept.
		        var equalsIndexPos = parameterList[nextParameter].indexOf("=");
		        var parameterName = parameterList[nextParameter].substr(0, equalsIndexPos);
		        var parameterValue = parameterList[nextParameter].substr(equalsIndexPos + 1);

		        var urlFormField = document.createElement("input");
		        urlFormField.setAttribute("type", "hidden");
		        urlFormField.setAttribute("name", decodeURIComponent(parameterName));
		        urlFormField.setAttribute("value", decodeURIComponent(parameterValue));

		        backURLForm.appendChild(urlFormField);
	        }

	        document.body.appendChild(backURLForm);
	        backURLForm.submit();
        }
	}
	else
	{
		window.close();
	}
};

/**
	@private
	@param {CModal} oDlg A reference to a CModal
	@param {string} sPath path of the XTS dialog to run
*/
CCognosViewer.prototype.showModal = function(oDlg, sPath)
{
	var sParams = "b_action=xts.run";
	sParams += "&m=" + sPath;

	var oDispatcher = this.getDispatcher();
	var oDispReq = oDispatcher.createRequest(this.getGateway(), sParams, oDlg);
	oDispReq.setResponseType("HTTP");
	oDispatcher.dispatchRequest(oDispReq);
};

/**
	Used by prompt controls to submit (forward) requests.
	@private
	@param {string} sAction <code>cancel</code>, <code>back</code>, <code>next</code> or <code>finish</code>.
	@param {string} sUrl "Back url" to use after the prompt has been cancelled.
*/
CCognosViewer.prototype.promptAction = function(sAction, sUrl)
{
	if ( typeof datePickerObserverNotify == "function" )
	{
		datePickerObserverNotify();
	}
	if (sAction == "cancel")
	{
		this.cancelPrompt(sUrl);
	}
	else
	{
		var oReq = new CCognosViewerRequest( sAction == "back" ? "back" : "forward" );

		if (sAction == "finish")
		{
			oReq.addOption("run.prompt", false);
		}
		else if (sAction == "back" || sAction == "next")
		{
			oReq.addOption("run.prompt", true);
		}
		if (sAction == "reprompt")
		{
			oReq.addOption("_promptControl", sAction);
		}
		else {
			oReq.addOption("_promptControl", "prompt");
		}

		this.submitPromptValues(oReq);
	}
};

/**
	@private
	@param {string} sUrl "Back url" to use after the prompt has been cancelled.
*/
CCognosViewer.prototype.cancelPrompt = function(sUrl)
{
	this.cancel();
};

/**
	Notifies other controls when a prompt control is updated
	@private
	@param {integer} iState
	@param {object} oNotifier
*/
CCognosViewer.prototype.notify = function(iState, oNotifier)
{
	var kCount = 0, k = 0;
	var oPromptElement = null;
	if (this.rangeObserverArray && this.rangeObserverArray instanceof Array)
	{
		kCount = this.rangeObserverArray.length;
		for (k=0; k<kCount; k++)
		{
			oPromptElement = eval(this.rangeObserverArray[k]);
			if (oPromptElement && typeof oPromptElement == "object" && typeof oPromptElement.update == "function")
			{
				oPromptElement.update();
			}
		}
	}

	var bPageEnabled = true;
	if (this.preProcessControlArray && this.preProcessControlArray instanceof Array)
	{
		kCount = this.preProcessControlArray.length;
		for (k=0; k<kCount; k++)
		{
			oPromptElement = eval(this.preProcessControlArray[k]);
			if ((typeof oPromptElement.getValid == "function") && !oPromptElement.getValid())
			{
				bPageEnabled = false;
				break;
			}
		}
	}
	this.notifyPageNavEnabled(bPageEnabled);

	if (this.multipleObserverArray && this.multipleObserverArray instanceof Array)
	{
		kCount = this.multipleObserverArray.length;
		for (k=0; k<kCount; k++)
		{
			oPromptElement = eval(this.multipleObserverArray[k]);
			if (oPromptElement && typeof oPromptElement == "object" && typeof oPromptElement.checkInsertRemove == "function")
			{
				oPromptElement.checkInsertRemove();
			}
		}
	}

	for (var idxNotif = 0; idxNotif < gaNotifyTargets.length; idxNotif++)
	{
		var oTarget = gaNotifyTargets[idxNotif];
		if (typeof oTarget != "undefined" && typeof oTarget.notify == "function")
		{
			oTarget.notify(iState, oNotifier);
		}
	}
};

/**
	@private
	@param {bool} bEnabled
*/
CCognosViewer.prototype.notifyPageNavEnabled = function(bEnabled)
{
	if (this.pageNavigationObserverArray && this.pageNavigationObserverArray instanceof Array)
	{
		var kCount = this.pageNavigationObserverArray.length;

		//determine if there is a finish button on the page, if so we'll disable the next.
		var bFinishPresent = false;
		var oPromptElement = null;
		var iPromptElementType = null;
		var k = 0;
		for (k=0; k<kCount; k++)
		{
			try
			{
				oPromptElement = eval(this.pageNavigationObserverArray[k]);
				iPromptElementType = oPromptElement.getType();
				if (iPromptElementType == PROMPTBUTTON_FINISH)
				{
					bFinishPresent = true;
					break;
				}
			}
			catch(e)
			{
			}
		}

		for (k=0; k<kCount; k++)
		{
			try
			{
				oPromptElement = eval(this.pageNavigationObserverArray[k]);
				iPromptElementType = oPromptElement.getType();
				if (!bEnabled)
				{
					if ((iPromptElementType == PROMPTBUTTON_NEXT) || (iPromptElementType == PROMPTBUTTON_OK) || (iPromptElementType == PROMPTBUTTON_FINISH))
					{
						oPromptElement.setEnabled(false);
					}
				}
				else
				{
					if (iPromptElementType == PROMPTBUTTON_FINISH)
					{
						oPromptElement.setEnabled(this.bCanFinish);
					}
					else if (iPromptElementType == PROMPTBUTTON_NEXT)
					{
						oPromptElement.setEnabled(this.bNextPage || !bFinishPresent);
					}
					else if (iPromptElementType == PROMPTBUTTON_OK)
					{
						oPromptElement.setEnabled(true);
					}
				}
			}
			catch(e2)
			{
			}
		}
	}
};

/**
	@private
	@param {object} oReq
*/
CCognosViewer.prototype.submitPromptValues = function(oReq)
{
	if ( this.gbPromptRequestSubmitted === true )
	{
		return false;
	}
	this.gbPromptRequestSubmitted = true;

	oReq = this.preparePromptValues(oReq);

	this.sendRequest(oReq);
}

CCognosViewer.prototype.preparePromptValues = function(oReq)
{
	// Use aInputs to keep track of input fields submitted.
	var aInputSubmitted = [];

	if (this.preProcessControlArray)
	{
		var kCount = this.preProcessControlArray.length;
		var k = 0;
		for (k=0; k<kCount; k++)
		{
			var oPrmtCtrl = eval(this.preProcessControlArray[k]);
			var bPrmtEnabled = (typeof oPrmtCtrl.isEnabled == "function" ? oPrmtCtrl.isEnabled() : true);
			if (oPrmtCtrl && typeof oPrmtCtrl.preProcess == "function" && bPrmtEnabled)
			{
				oPrmtCtrl.preProcess();
				if (oPrmtCtrl.m_oSubmit)
				{
					oReq.addParameter(oPrmtCtrl.m_oSubmit.name, oPrmtCtrl.m_oSubmit.value);
					aInputSubmitted.push(oPrmtCtrl.m_oSubmit);

					if (oPrmtCtrl.m_sPromptId && oPrmtCtrl.m_oForm && oPrmtCtrl.m_oForm.elements && typeof oPrmtCtrl.m_oForm.elements['p_' + oPrmtCtrl.m_sRef] == "object")
					{
						// we have a promptID based control, add its value separately (ie multiple search controls on the same parameter on the same page).
						oReq.addParameter('p_' + oPrmtCtrl.m_sPromptId, oPrmtCtrl.m_oForm.elements['p_' + oPrmtCtrl.m_sRef].value);
					}

				}
			}
		}
	}

	var elFWR = document.getElementById("formWarpRequest" + this.getId());
	if (elFWR)
	{
		var aInputs = elFWR.elements;
		for (var idxInput = 0; idxInput < aInputs.length; idxInput++)
		{
			var elInput = aInputs[idxInput];
			if ( !elInput.name || !elInput.name.match(/^p_/) )
			{
				continue;
			}
			var bToAdd = true;
			for (var idxSubmitted = 0; idxSubmitted < aInputSubmitted.length; idxSubmitted++)
			{
				if (aInputSubmitted[idxSubmitted] == elInput)
				{
					bToAdd = false; break;
				}
			}
			if (bToAdd)
			{
				oReq.addParameter(elInput.name, elInput.value);
				aInputSubmitted.push(elInput);
			}
		}
	}

	var oRM = this['CognosReport'];
	if (oRM)
	{
		var aParams = oRM.prompt.getParameters();
		for (var i = 0; i < aParams.length; i++)
		{
			var sName = "p_" + aParams[i].getName();
			if ( !oReq.getParameter(sName) )
			{
				oReq.addParameter(sName, aParams[i].getXML());
			}
		}
	}

	return oReq;
};

/**
	@constructor
	@param sAction {string} See {@link #setAction} method for possible values.
	@type CCognosViewerRequest
*/
function CCognosViewerRequest(sAction)
{
	/**
		@private
		@type string
	*/
	this.m_sAction = "";
	/**
		@private
		@type string
	*/
	this.m_sData = "";
	/**
		@private
		@type CDictionary
		@deprecated
	*/
	this.m_oOptions = new CDictionary();
	/**
		@private
		@type CDictionary
		@deprecated
	*/
	this.m_oParams = new CDictionary();

	/**
	 * @private
	 * @type CDictionary
	 */
	this.m_oFormFields = new CDictionary();

	/**
	 * @private
	 * @type string
	 */
	this.m_sRequestType = "ajax";

	/**
	 * The callback to be executed
	 * @private
	 */
	this.m_callback = null;

	this.setAction(sAction);


}

/**
 * Sets the callback function to be executed
 * @param callbackFunction (function)
 */
CCognosViewerRequest.prototype.setCallback = function(callback)
{
	this.m_callback = callback;
};

/**
 * Returns the callback function to be used
 * @return (function)
 */
CCognosViewerRequest.prototype.getCallback = function()
{
	return this.m_callback;
}

/**
 * Sets the request type (ajax,post,get)
 * @param string
 */
CCognosViewerRequest.prototype.setRequestType = function(sRequestType)
{
	if(typeof sRequestType != "undefined" && typeof sRequestType == "string")
	{
		if(sRequestType.match(/\ajax\b|\bpost\b|\bget\b/i))
		{
			this.m_sRequestType = sRequestType;
		}
	}
};

/**
 * Returns the request type
 * @return string
 */
CCognosViewerRequest.prototype.getRequestType = function()
{
	return this.m_sRequestType;
}

/**
	Add a option (name/value pair). See URL Api for possible options.
	@param {string} sName
	@param {string} sValue
	@deprecated
*/
CCognosViewerRequest.prototype.addOption = function(sName, sValue)
{
	this.m_oOptions.add(sName, sValue);
};

/**
	Remove an option (by name). See URL Api for possible options.
	@param {string} sName
	@param {string} sValue
	@deprecated
*/
CCognosViewerRequest.prototype.removeOption = function(sName)
{
	this.m_oOptions.remove(sName);
};

/**
	Add a parameter name/value pair to this request (for prompts).
	@param {string} sName
	@param {string} sValue
	@deprecated
*/
CCognosViewerRequest.prototype.addParameter = function(sName, sValue)
{
	this.m_oParams.add(sName, sValue);
};

/**
 * Adds a form field to the request
 * @param (string) sName
 * @param (string) sValue
 */
 CCognosViewerRequest.prototype.addFormField = function(sName, sValue)
 {
	this.m_oFormFields.add(sName, sValue);
 };

 /**
  * Returns the list of form fields associated with the request
  * @return CDictionary
  */
 CCognosViewerRequest.prototype.getFormFields = function()
 {
 	return this.m_oFormFields;
 };

/**
	@type string
*/
CCognosViewerRequest.prototype.getAction = function()
{
	return this.m_sAction;
};

/**
	@type string
*/
CCognosViewerRequest.prototype.getData = function()
{
	return this.m_sData;
};

/**
	@param {string} sName
	@type string
	@deprecated
*/
CCognosViewerRequest.prototype.getOption = function(sName)
{
	return this.m_oOptions.get(sName);
};

/**
	@param {string} sName
	@type string
	@deprecated
*/
CCognosViewerRequest.prototype.getParameter = function(sName)
{
	return this.m_oParams.get(sName);
};

/**
	@param {string} sName
	@type bool
	@deprecated
*/
CCognosViewerRequest.prototype.hasOption = function(sName)
{
	return this.m_oOptions.exists(sName);
};

/**
	@param {string} sName
	@type bool
	@deprecated
*/
CCognosViewerRequest.prototype.hasParameter = function(sName)
{
	return this.m_oParams.exists(sName);
};

/**
	@param sAction {string} possible values: <ul><li>add</li><li>back</li><li>cancel</li><li>currentPage</li><li>drill</li><li>email</li><li>firstPage</li><li>forward</li><li>getOutput</li><li>lastPage</li><li>nextPage</li><li>previousPage</li><li>print</li><li>release</li><li>render</li><li>run</li><li>runSpecification</li><li>save</li><li>saveas</li><li>wait</li></ul>
*/
CCognosViewerRequest.prototype.setAction = function(sAction)
{
	this.m_sAction = sAction;
};

/**
	Set the data for the current action (see URL Api).
	@param {string} sValue
*/
CCognosViewerRequest.prototype.setData = function(sValue)
{
	this.m_sData = sValue;
};

/**
	Show/hide header, toolbar based on the current state.
	@private
	@param {string} sState Conversation's state
*/
CCognosViewer.prototype.updateLayout = function(sState)
{
	var oHeader = document.getElementById('CVHeader' + this.getId());
	var oToolbar = document.getElementById('CVToolbar' + this.getId());
	if (!oHeader && !oToolbar)
	{
		setTimeout('oCV' + this.getId() + '.updateLayout("' + sState + '");', 100);
		return;
	}

	if (oHeader) {
		if (sState == "prompting" && !this.bShowHeaderWithPrompts) {
			oHeader.parentNode.style.display = "none";
		}
		else {
			oHeader.parentNode.style.display = "";
		}
	}
	if (oToolbar) {
		if (sState == "prompting") {
			oToolbar.parentNode.style.display = "none";
		}
		else {
			oToolbar.parentNode.style.display = "";
		}
	}
};

/**
	Update the state of the response specification.
	@private
	@param {string} sResponseSpecification specification state
*/
CCognosViewer.prototype.updateResponseSpecification = function(sResponseSpecification)
{
	this.sResponseSpecification = sResponseSpecification;
};

/**
	Returns the response specification if available.
	@private
	@param
*/
CCognosViewer.prototype.getResponseSpecification = function()
{
	return this.sResponseSpecification;
};

CCognosViewer.prototype.exit = function(callback)
{
	var form = document.getElementById("formWarpRequest" + this.getId());
	var tracking = this.getTracking();
	if(!tracking && form && form["m_tracking"] && form["m_tracking"].value) {
		tracking = form["m_tracking"].value;
	}

	if(tracking != "")
	{
		var params="b_action=cognosViewer&cv.responseFormat=successfulRequest";


		if(this.envParams["cv.debugDirectory"] != null)
		{
			params += "&cv.debugDirectory=" + this.envParams["cv.debugDirectory"];
		}

		if(tracking != "")
		{
			var sStatus = this.getStatus();
			if(sStatus == "working" || sStatus == "prompting") {
				params += "&ui.action=cancel";
			}
			else {
				params += "&ui.action=release";
			}

			params += "&m_tracking=";
			params += tracking;
		}

		if(!callback)
		{
			// If no callback was provided, this http request needs to be synchronous. The dispatcher doesn't
			// currently support synchronous requests, so for the time being, we'll create our own http request and send
			// it along
			var httpRequest;
			if (typeof ActiveXObject != "undefined")
			{
				httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
			}
			else
			{
				httpRequest = new XMLHttpRequest();
			}

			httpRequest.onreadystatechange = XMLHttpRequestReadyStateChanged;
			httpRequest.open("POST", this.getGateway(), false);
			httpRequest.setRequestHeader("Content-Type", "text/html");
			httpRequest.send(params);
			if (httpRequest.responseXML != null)
			{
				var responseXML = httpRequest.responseXML;
				if (typeof g_firefoxPluginHelper != "undefined" && g_firefoxPluginHelper != null)
				{
					g_firefoxPluginHelper.addDebugLogsFromResponseXML(responseXML);
				}
			}
		}
		else
		{
			var request = gDispatcher.createRequest(this.getGateway(), params, callback);
			gDispatcher.dispatchRequest(request);
		}
	}
}

/**
 * Executes a viewer action
 * @param (string) The action to execute (ie. run)
 */
CCognosViewer.prototype.executeAction = function(sAction)
{
	try
	{
		var action = eval("new " + sAction + "Action();");
		action.setCognosViewer(this);
		action.execute();
	}
	catch(exception)
	{
		window.status = "Error loading " + sAction + " action.";
	}
};

/**
	Loads dynamically CSS and JavaScript files and execute inline scripts found in HTML code in the response outputs.
	@constructor
*/
function CScriptLoader(sWebContentRoot)
{
	/**
	 	Array of files to load.
		@type array
		@private
	*/
	this.m_oFiles = {};
	/**
	 	Array of inline script to execute.
		@type array
		@private
	*/
	this.m_aScripts = [];
	/**
	 	Inline styles to apply.
		@type style object
		@private
	*/
	this.m_inlineStyle = null;
	/**
	 	Array of inline CSS style sheets to apply.
		@type array
		@private
	*/
	this.m_aCSS = [];

	/**
	 	Array of document.writes/document.writeln to execute.
		@type array
		@private
	*/
	this.m_aDocumentWriters = [];

	this.m_ajaxWarnings = [];

	/**
	 	Reference to the interval procedure.
		@type object
		@private
	*/
	this.m_oTimer = null;
	/**
	 	Length of the interval (in Milliseconds) to check if files are done loading and that we can execute the inline scripts.
		@type integer
		@private
	*/
	this.m_iInterval = 20;

	/**
	 	Regular expression to retrieve CSS file paths.
		@type RegularExpression
		@private
	*/
	this.m_reFindCssPath = new RegExp('<link[^>]*href="([^"]*)"');

	/**
	 	Regular expression to retrieve JavaScript file paths.
		@type RegularExpression
		@private
	*/
	this.m_reFindJavaScriptPath = new RegExp('<script[^>]*src="([^"]*)"');

	/**
	 	Regular expression to retrieve JavaScript inline code.
		@type RegularExpression
		@private
	*/
	this.m_reFindInlineScript = /<script(\s|.)*?<\/script>/gim;

	/**
	 	Regular expression to retrieve CSS inline code.
		@type RegularExpression
		@private
	*/
	this.m_reFindInlineStyle = /<style\b(\s|.)*?<\/style>/gi;

	/**
	 	Regular expression to test if a CSS (&lt;link&gt; tag) is present.
		@type RegularExpression
		@private
	*/
	this.m_reHasCss = /<link .*?>/gi;

	/**
	 	Regular expression to test if a JavaScript (&lt;script&gt; tag) is present.
		@type RegularExpression
		@private
	*/
	this.m_reHasJavaScript = /<script(\s|.)*?<\/script>/gi;
	/**
	 	Regular expression to test if a file name has a CSS extension.
		@type RegularExpression
		@private
	*/
	this.m_reIsCss = /\.css$/i;
	/**
	 	Regular expression to test if a file name has a JS extension.
		@type RegularExpression
		@private
	*/
	this.m_reIsJavascript = /\.js$/i;
	/**
	 	Regular expression to match closing &lt;script&gt; tags.
		@type RegularExpression
		@private
	*/
	this.m_reScriptTagClose = /\s*<\/script>.*?$/i;
	/**
	 	Regular expression to match opening &lt;script&gt; tags.
		@type RegularExpression
		@private
	*/
	this.m_reScriptTagOpen = /^.*?<script[^>]*>\s*/i;

	/**
	 	Regular expression to match closing &lt;style&gt; tags.
		@type RegularExpression
		@private
	*/
	this.m_reStyleTagClose = /(-|>|\s)*<\/style>\s*$/gi;
	/**
	 	Regular expression to match opening &lt;style&gt; tags.
		@type RegularExpression
		@private
	*/
	this.m_reStyleTagOpen = /^\s*<style[^>]*>(\s|<|!|-)*/gi;

	/**
		String that represents the web content root
		@type String
		@private
	*/
	this.m_sWebContentRoot = sWebContentRoot;
}

/**
	Helper function to execute all inline javascript from a page, after all javascript files were loading and processed.
	@private
*/
CScriptLoader.prototype.executeScripts = function(oRVContent)
{
	if (this.isReadyToExecute())
	{
		for (var idxScript = 0; idxScript < this.m_aScripts.length; idxScript++)
		{
			if (this.m_aScripts[idxScript])
			{
				var oScript = document.createElement('script');
				oScript.setAttribute("language", "javascript");
				oScript.setAttribute("type", "text/javascript");
				oScript.text = this.m_aScripts[idxScript];
				document.getElementsByTagName("head").item(0).appendChild(oScript);
			}
		}

		this.m_aScripts = [];

		for(var idx = 0; idx < this.m_aDocumentWriters.length; ++idx)
		{
			var documentWriter = this.m_aDocumentWriters[idx];
			documentWriter.execute();
		}

		this.m_aDocumentWriters = [];

		if (!this.m_aScripts.length && !this.m_aDocumentWriters.length)
		{
			clearInterval(this.m_oTimer);
			this.m_oTimer = null;

			if (oRVContent != null && typeof oRVContent != "undefined")
			{
				oRVContent.style.display = "block";
			}
		}
		else if (!this.m_oTimer)
		{
			this.m_oTimer = setInterval(function(){window.gScriptLoader.executeScripts(oRVContent);}, this.m_iInterval);
		}
	}
	else if (!this.m_oTimer)
	{
		this.m_oTimer = setInterval(function(){window.gScriptLoader.executeScripts(oRVContent);}, this.m_iInterval);
	}
};

/**
	Helper function.
	@type bool
	@private
	@return true if all files in {m_oFiles} are set to 'complete'. false otherwise.
*/
CScriptLoader.prototype.isReadyToExecute = function()
{
	for (var idxFile in this.m_oFiles)
	{
		if (this.m_oFiles[idxFile] != "complete")
		{
			return false;
		}
	}
	return true;
};

/**
	Load and process a CSS file from HTML code [received from an ajax response].
	@private
	@param {string} sHTML HTML code with a &lt;link&gt; tag.
*/
CScriptLoader.prototype.loadCSS = function(sHTML)
{
	var aM = sHTML.match(this.m_reHasCss);
	if (aM)
	{
		for (var i = 0; i < aM.length; i++)
		{
			if (aM[i].match(this.m_reFindCssPath))
			{
				var linkRef = RegExp.$1;
				if(linkRef.indexOf("GlobalReportStyles") != -1)
				{
					this.validateGlobalReportStyles(linkRef);
				}

				this.loadObject(linkRef);
			}

			// remove the link tag from the html block
			sHTML = sHTML.replace(aM[i], '');
		}
	}

	return sHTML;
};

/**
 * @private
 * @param (String)
 */
CScriptLoader.prototype.validateGlobalReportStyles = function(globalReportStyleLinkRef)
{
	var linkNodes = document.getElementsByTagName("link");
	for(var i = 0; i < linkNodes.length; ++i)
	{
		var linkNode = linkNodes[i];
		if(linkNode.getAttribute("href").indexOf("GlobalReportStyles") != -1)
		{
			if(linkNode.getAttribute("href").toLowerCase() != globalReportStyleLinkRef.toLowerCase())
			{
				this.m_ajaxWarnings.push("Ajax response contains different versions of the GlobalReportStyles.css.");
			}

			break;
		}
	}
};

/**
	Load a file synchronously and return the content.
	@param {string} sURL URL to fetch
	@param {string} sParams parameter string to add to the file
	@param {string} sType POST or GET
	@type string
	@return The content of the file
	@private
*/
CScriptLoader.prototype.loadFile = function(sURL_param, sContent_param, sType_param)
{
	var sURL = "";
	if (sURL_param) {
		sURL = sURL_param;
	}
	var sContent = null;
	if (typeof sContent_param == "string") {
		sContent = sContent_param;
	}
	var sType = "POST";
	if (sType_param == "GET") {
		sType = "GET";
	}

	var oHTTPRequest = null;
	if (typeof ActiveXObject != "undefined")
	{
		oHTTPRequest = new ActiveXObject("Msxml2.XMLHTTP");
	}
	else
	{
		oHTTPRequest = new XMLHttpRequest();
	}

	oHTTPRequest.open(sType, sURL, false);
	oHTTPRequest.send(sContent);

	return oHTTPRequest.responseText;
};

/**
	Helper function to load and process file (CSS or Javascript) from HTML code received from an ajax response.
	@private
	@param {string} sName
*/
CScriptLoader.prototype.loadObject = function(sName)
{
	var oFile = null;

	if (this.m_oFiles[sName])
	{
		return;
	}

	if (sName.match(this.m_reIsCss))
	{
		// Add a <link> tag in the document. This let the browser deals with the cache.
		oFile = document.createElement('link');
		oFile.setAttribute("rel", "stylesheet");
		oFile.setAttribute("type", "text/css");
		oFile.setAttribute("href", sName);
		this.m_oFiles[sName] = "complete";
	}
	else if (sName.match(this.m_reIsJavascript))
	{
		oFile = document.createElement('script');
		oFile.setAttribute("language", "javascript");
		oFile.setAttribute("type", "text/javascript");
		oFile.setAttribute("src", sName);
		oFile.sFilePath = sName;
		oFile.onreadystatechange = CScriptLoader_onReadyStateChange;
		oFile.onload = CScriptLoader_onReadyStateChange;
		this.m_oFiles[sName] = "new";
	}

	if (oFile)
	{
		document.getElementsByTagName("head").item(0).appendChild(oFile);
	}
};

/**
	Helper function to load and process JavaScript files and code from HTML code received from an ajax response.
	@private
	@param {string} sHTML
*/
CScriptLoader.prototype.loadScripts = function(sHTML)
{
	var aM = sHTML.match(this.m_reHasJavaScript);
	if (aM)
	{
		for (var i = 0; i < aM.length; i++)
		{
			var sReplaceString = "";
			if (aM[i].match(this.m_reFindJavaScriptPath))
			{
				this.loadObject(RegExp.$1);
			}
			else if (aM[i].match(this.m_reFindInlineScript))
			{
				if(aM[i].indexOf("document.write")!= -1)
				{
					var sId = "CVPlaceHolder" + i;
					sReplaceString = "<span id=\"" + sId + "\"></span>";
					this.m_aDocumentWriters.push(new CDocumentWriter(sId, aM[i]));
					this.m_ajaxWarnings.push("Ajax response contains a version of document.write().");
				}
				else
				{
					var s = aM[i].replace(this.m_reScriptTagOpen, "").replace(this.m_reScriptTagClose, "");
					this.m_aScripts.push(s);
				}
			}

			// remove the inline script from the html block
			sHTML = sHTML.replace(aM[i], sReplaceString);
		}
	}

	return sHTML;
};


/**
	Helper function to load and process JavaScript files from HTML code received from an ajax response.
	@private
	@param {string} sHTML
*/
CScriptLoader.prototype.loadScriptFiles = function(sHTML, oCV)
{
	var aM = sHTML.match(this.m_reHasJavaScript);
	if (aM)
	{
		for (var i = 0; i < aM.length; i++)
		{
			if (aM[i].match(this.m_reFindJavaScriptPath))
			{
				if (RegExp.$1.indexOf("PRMTcompiled.js") != -1 || RegExp.$1.indexOf("prompt/control.js") != -1)
				{
					oCV.setHasPrompts(true);
				}
				this.loadObject(RegExp.$1);
				// remove the script tag from the html block
				sHTML = sHTML.replace(aM[i], '');
			}
		}
	}

	return sHTML;
};

/**
	Apply the inline styles we created (this.m_inlineStyle) in extractStyles.
	@private
*/
CScriptLoader.prototype.applyStyles = function()
{
	if (this.m_inlineStyle)
	{
		var nStyles = document.getElementsByTagName("style").length + document.getElementsByTagName("link").length;
		if (nStyles++ >= 30)
		{
			this.m_ajaxWarnings.push("Stylesheet limit reached.");
			return;
		}

		var head = document.getElementsByTagName('head')[0];
		head.appendChild(this.m_inlineStyle);
	}
}

/**
	Extract the inline styles (CSS) from HTML code [received from an ajax response]. We do that before
	setting the innerHTML in processResponseOutput else it ends up being redundant and, not surprisingly,
	IE blows up (acts strange).
	@private
	@param {string} sHTML HTML code with a &lt;style&gt; tag.
*/
CScriptLoader.prototype.extractStyles = function(sHTML)
{
	this.m_inlineStyle = null;

	var aM = sHTML.match(this.m_reFindInlineStyle);

	if (aM)
	{
		var styleText = "";

		for (var i = 0; i < aM.length; i++)
		{
			var sText = aM[i].replace(this.m_reStyleTagOpen, '').replace(this.m_reStyleTagClose, '');
			sHTML = sHTML.replace(aM[i], '');
			styleText = styleText + sText + "\n";
		}

		var nStyle = document.createElement('style');
		nStyle.setAttribute("type", "text/css");

		if (nStyle.styleSheet)
		{
			nStyle.styleSheet.cssText = styleText;
		}
		else
		{
			nStyle.appendChild(document.createTextNode(styleText));
		}

		this.m_inlineStyle = nStyle;
	}

	return sHTML;
}

/**
	Apply the inline CCS we pushed into this.m_aCSS in extractCSS.
	@private
*/
CScriptLoader.prototype.applyCSS = function()
{
	var nCSS = this.m_aCSS.pop();
	var nStyles = document.getElementsByTagName("style").length + document.getElementsByTagName("link").length;

	while (nCSS)
	{
		if (nStyles++ >= 30)
		{
			this.m_ajaxWarnings.push("Stylesheet limit reached.");
			return;
		}

		this.loadObject(nCSS);
		nCSS = this.m_aCSS.pop();
	}
}

/**
	Extract the inline (CSS) from HTML code [received from an ajax response]. We do that before
	setting the innerHTML in processResponseOutput else it ends up being redundant and, not surprisingly,
	IE blows up (acts strange).
	@private
	@param {string} sHTML HTML code with a &lt;link&gt; tag.
*/
CScriptLoader.prototype.extractCSS = function(sHTML)
{
	this.m_aCSS = [];

	var aM = sHTML.match(this.m_reHasCss);

	if (aM)
	{
		for (var i = 0; i < aM.length; i++)
		{
			if (aM[i].match(this.m_reFindCssPath))
			{
				var linkRef = RegExp.$1;
				if(linkRef.indexOf("GlobalReportStyles") != -1)
				{
					this.validateGlobalReportStyles(linkRef);
				}

				this.m_aCSS.push(linkRef);
			}
			sHTML = sHTML.replace(aM[i], '');
		}
	}

	return sHTML;
};

CScriptLoader.prototype.loadScriptsFromDOM = function(domElement)
{
	if (!domElement)
	{
		return;
	}

	var scriptElements = domElement.parentNode.getElementsByTagName("script");
	while(scriptElements.length > 0)
	{
		var scriptElement = scriptElements[0];
		if (scriptElement.getAttribute("src") != null && scriptElement.getAttribute("src").length > 0)
		{
			this.loadObject(scriptElement.getAttribute("src"));
		}
		else
		{
			var sScript = scriptElement.innerHTML;

			if(sScript.indexOf("document.write")!= -1)
			{
				this.m_ajaxWarnings.push("Ajax response contains a version of document.write().");
			}
			else if (sScript.length > 0)
			{
				this.m_aScripts.push(sScript);
			}
		}

		scriptElement.parentNode.removeChild(scriptElement);
	}
}

/**
	Load and process inline styles (CSS) from HTML code [received from an ajax response].
	@private
	@param {string} sHTML HTML code with a &lt;style&gt; tag.
*/
CScriptLoader.prototype.loadStyles = function(sHTML)
{
	var aM = sHTML.match(this.m_reFindInlineStyle);
	if (aM)
	{
		for (var i = 0; i < aM.length; i++)
		{
			var sText = aM[i].replace(this.m_reStyleTagOpen, '').replace(this.m_reStyleTagClose, '');
			var nStyle = document.createElement('style');
			nStyle.setAttribute("type", "text/css");

			if (nStyle.styleSheet)
			{
                                // IE has a limit of 31 stylesheets. If ever we reach the limit, then re-submit the request in "page" mode.
				// fix for trakker 564899 and 615224
				if ((document.getElementsByTagName("style").length + document.getElementsByTagName("link").length) >= 30)
				{
                                        this.m_ajaxWarnings.push("Stylesheet limit reached.");
                                        return;

				}
				else
				{
					nStyle.styleSheet.cssText = sText;
				}
			}
			else
			{
				// Mozilla & Firefox
				nStyle.appendChild( document.createTextNode(sText) );
			}

                        document.getElementsByTagName("head").item(0).appendChild(nStyle);

			// remove the inline style from the html block
			sHTML = sHTML.replace(aM[i], '');
		}
	}
	return sHTML;
};


/**
	Setter for the loading state of a file.
	@private
	@param {string} sFile Path of the file to load.
	@param {string} sState State of the current file. Can be 'new' or 'complete'.
*/
CScriptLoader.prototype.setFileState = function(sFile, sState)
{
	this.m_oFiles[sFile] = sState;
};

CScriptLoader.prototype.containsAjaxWarnings = function()
{
	return (this.m_ajaxWarnings.length > 0);
};

/**
	Helper Function. Event called when a file status is changed (ie. when it's done loading).
	@private
*/
function CScriptLoader_onReadyStateChange()
{
	if (typeof this.readyState == "undefined")
	{
		// Mozilla-based browser are using onload event, so we are here when the file is done loading.
		this.readyState = "complete";
	}
	if (this.readyState == "loaded" || this.readyState == "complete")
	{
		window.gScriptLoader.setFileState(this.sFilePath, "complete");
	}
}

// Declare a global instance of CScriptLoader if none exists. We just need one instance per page.
if (typeof window.gScriptLoader == "undefined")
{
	window.gScriptLoader = new CScriptLoader();
}

/**
	Initialize the CWaitPage object.
	@constructor
	@param {string} sId The unique namespace to be used by this object
	@param {string} sGateway Path to "cognos.cgi". For example: "/cognos8/cgi-bin/cognos.cgi".
 */

function CWaitPage(sNamespace, sGateway)
{
	this.m_sNamespace = sNamespace;
	this.m_sGateway = sGateway;
	this.m_waitPageDiv = null;
	this.m_waitPageIframe = null;
	this.m_bUse = true;
	this.m_sHTML = "";
	this.m_bCancelSubmitted = false;
};

CWaitPage.prototype.cancelSubmitted = function()
{
	return this.m_bCancelSubmitted;
}

CWaitPage.prototype.setCancelSubmitted = function(bSubmitted)
{
	this.m_bCancelSubmitted = bSubmitted;
}

/**
 * Sets the wait page HTML
 * @private
 */
CWaitPage.prototype.initializeWaitPage = function(sHTML)
{
	this.m_sHTML = sHTML;
	this.setCancelSubmitted(false);
}

/**
 * Returns the unique namespace
 * @return (string)
 */
CWaitPage.prototype.getNamespace = function()
{
	return this.m_sNamespace;
};

/**
 *
 */
 CWaitPage.prototype.setUseWaitPage = function(bUse)
 {
 	this.m_bUse = bUse;
 };

/**
 * Returns the gateway
 * @return (string)
 */
CWaitPage.prototype.getGateway = function()
{
	return this.m_sGateway;
};

CWaitPage.prototype.destroy = function()
{
	if (this.m_waitPageDiv != null)
	{
		this.m_waitPageDiv.parentNode.removeChild(this.m_waitPageDiv);
		this.m_waitPageDiv = null;
	}

	if (this.m_waitPageIframe != null)
	{
		this.m_waitPageIframe.parentNode.removeChild(this.m_waitPageIframe);
		this.m_waitPageIframe = null;
	}
}

/**
 * Returns a boolean value indicating whether or not the wait page has been initialized
 * @return (boolean)
 */
CWaitPage.prototype.isInitialized = function()
{
	return (this.m_waitPageDiv != null && this.m_waitPageIframe != null);
};

/**
 * Will initialize and draw the wait page. This method should be used to render the page
 * @param bSavedReport (boolean) Indicates running a saved report. This will dictate whether the wait page shows "delivery options" or not.
 */
CWaitPage.prototype.show = function(bSavedReport)
{
	if(this.m_bUse === true && this.m_sHTML != "")
	{
		if(this.isInitialized() === false)
		{
			this.create(bSavedReport);
		}

		this.render(true, bSavedReport);
	}
};

/**
 * Will hide the wait page
 */
CWaitPage.prototype.hide = function()
{
	this.render(false);
	this.showDeliveryOptions(false);
};

/**
 * Displays a very simply wait dialog with a wait icon and some text.
 * @param oCV the cognos viewer object
 */
CWaitPage.prototype.showSimpleWaitDialog = function(oCV)
{
	this.initializeWaitPage(this.getSimpleWaitDialogHtml(oCV));
	this.show(false);
}

/**
 * returns the html for a very simply wait dialog with a wait icon and some text.
 * @param oCV the cognos viewer object
 */
CWaitPage.prototype.getSimpleWaitDialogHtml = function(oCV)
{
	var waitPageHtml = "<table id=\"CVWaitTable" + oCV.getId() + "\" simpleDialog=\"true\" style=\"border: 1px solid #000000;\" cellpadding=\"0\" cellspacing=\"0\">";
	waitPageHtml += "<tr><td align=\"center\">";
	waitPageHtml += "<div class=\"body_dialog_modal\" style=\"border:1px solid #999999;\">";
	waitPageHtml += "<table align=\"center\" cellspacing=\"0\" cellpadding=\"0\" style=\"vertical-align:middle;;\">";
	waitPageHtml += "<tr><td rowspan=\"2\">";
	waitPageHtml += "<img src=\"" + oCV.getWebContentRoot() + "/skins/corporate/branding/progress.gif\" style=\"margin:5px;\" width=\"48\" height=\"48\" name=\"progress\"/>";
	waitPageHtml += "</td><td nowrap=\"nowrap\"><span class=\"busyUpdatingStr\">";
	waitPageHtml += oCV.oStrings.sWorking;
	waitPageHtml += "</span></td></tr><tr><td nowrap=\"nowrap\"><span class=\"busyUpdatingStr\">";
	waitPageHtml += oCV.oStrings.sPleaseWait;
	waitPageHtml += "</span></td></tr><tr><td style=\"height:7px;\" colspan=\"2\"></td></tr></table></div></td></tr></table>";

	return waitPageHtml;
}

/**
 * Will hide/show the delivery options toolbar buttons within the wait page
 * @param bShow (boolean) Boolean which dictates whether to show the delivery option toolbar buttons
 */
CWaitPage.prototype.showDeliveryOptions = function(bShow)
{
	var htmlElement = document.getElementById("DeliveryOptionsVisible" + this.getNamespace());
	if (htmlElement)
	{
		htmlElement.style.display = (bShow === false ? "none" : "block");
	}

	htmlElement = document.getElementById("OptionsLinkSelected" + this.getNamespace());
	if (htmlElement)
	{
		htmlElement.style.display = (bShow === false ? "none" : "block");
	}

	htmlElement = document.getElementById("OptionsLinkUnselected" + this.getNamespace());
	if (htmlElement)
	{
		htmlElement.style.display = (bShow === false ? "block" : "none");
	}

	this.updateCoords();
};

/**
 * Initializes the wait page div and hidden iframe
 * @param bSavedReport (boolean) Indicates whether or not the wait page should make available the delivery options
 * @private
 */
CWaitPage.prototype.create = function(bSavedReport)
{
	if (typeof document.body != "undefined")
	{
		this.m_waitPageDiv = this.createWaitPageDiv(bSavedReport);
		this.m_waitPageIframe = this.createWaitPageIframe(this.m_waitPageDiv);
	}
};

/**
 * Updates the x and y coordinates of the wait page
 * @private
 */
CWaitPage.prototype.updateCoords = function()
{
	if(this.isInitialized())
	{
		// position the wait page in the middle of the report
		var iBottom = 0;
		var iLeft = 0;
		if (typeof window.innerHeight != "undefined")
		{
			iBottom = Math.round((window.innerHeight/2) - (this.m_waitPageDiv.offsetHeight/2));
			iLeft = Math.round((window.innerWidth/2) - (this.m_waitPageDiv.offsetWidth/2));
		}
		else
		{
			iBottom = Math.round((document.body.clientHeight/2) - (this.m_waitPageDiv.offsetHeight/2));
			iLeft = Math.round((document.body.clientWidth/2) - (this.m_waitPageDiv.offsetWidth/2));
		}

		this.m_waitPageDiv.style.bottom = iBottom + "px";
		this.m_waitPageDiv.style.left = iLeft + "px";

		this.m_waitPageIframe.style.left = this.m_waitPageDiv.style.left;
		this.m_waitPageIframe.style.bottom = this.m_waitPageDiv.style.bottom;
		this.m_waitPageIframe.style.width = this.m_waitPageDiv.offsetWidth + "px";
		this.m_waitPageIframe.style.height = this.m_waitPageDiv.offsetHeight + "px";
	}
};

/**
 * Builds the wait page div
 * @param bSavedReport (boolean) Indicates whether or not the wait page should render the delivery options
 * @private
 */
CWaitPage.prototype.createWaitPageDiv = function(bSavedReport)
{
	var oWaitDiv = document.createElement("DIV");
	oWaitDiv.setAttribute("id", "CVWait" + this.getNamespace());

	oWaitDiv.style.position = "absolute";
	oWaitDiv.style.textAlign = "center";
	oWaitDiv.style.zIndex = 100;

	document.body.appendChild(oWaitDiv);

	try
	{
		oWaitDiv.innerHTML = this.m_sHTML;
	}
	catch (oExcpt) {}

	return oWaitDiv;
};

/**
 * Builds the wait page hidden iframe (used so the wait page draws over iframes)
 * @param bSavedReport (boolean) Indicates whether or not the wait page should render the delivery options
 * @private
 */
CWaitPage.prototype.createWaitPageIframe = function(waitPageDiv)
{
	var hiddenIframe = document.createElement("iframe");

	var sWebContentRoot = "..";

	var oCV = null;
	try
	{
		oCV = eval("oCV" + cvId);
	}
	catch(exception){}

	if (oCV != null)
	{
		sWebContentRoot = oCV.getWebContentRoot();
	}

	hiddenIframe.setAttribute("id","CVWaitIframe" + this.getNamespace());
	hiddenIframe.setAttribute("src",sWebContentRoot + '/common/images/spacer.gif');
	hiddenIframe.setAttribute("scrolling",'no');
	hiddenIframe.setAttribute("frameborder",'0');
	hiddenIframe.style.position='absolute';
	hiddenIframe.style.zIndex=99;
	hiddenIframe.style.display='none';

	document.body.appendChild(hiddenIframe);

	return hiddenIframe;
};

/**
 * Displays or hides the wait page
 * @param bShow (boolean) Indicates whether to hide or show the wait page
 * @private
 */
CWaitPage.prototype.render = function(bShow)
{
	if(this.m_waitPageDiv != null && this.m_waitPageIframe != null)
	{
		var sDisplay = bShow ? "block" : "none";

		this.m_waitPageDiv.style.display = sDisplay;
		this.m_waitPageIframe.style.display = sDisplay;

		this.updateCoords();
	}
};

/**
	Initialize the CDocumentWriter object.
	@constructor
	@param {string} sId The unqiue id of the anchor tag which is a placholder for the script to execute
	@param {string} sScript The script to be executed
 */
function CDocumentWriter(sId, sScript)
{
	this.m_sId = sId;
	this.m_sText = "";
	this.m_sScript = sScript;
};

/**
 * Determines if the document writer can handle the embedded script successfully.
 * @return (boolean)
 */
CDocumentWriter.prototype.isValid = function()
{
	if(typeof this.m_sScript != "undefined" && this.m_sScript && window.gScriptLoader)
	{
		var aMatch = this.m_sScript.match(window.gScriptLoader.m_reFindInlineScript);
		if(aMatch && aMatch.length == 1)
		{
			return true;
		}
	}

	return false;
}

/**
 * Executes the inline script. This method will return false if an error occurs
 * @return (boolean)
 */
CDocumentWriter.prototype.execute = function()
{

	if(this.isValid() && window.gScriptLoader)
	{
		var reDocumentWrite = /document\.write(ln)?\s*\(/gi;
		var sScript = this.m_sScript.replace(reDocumentWrite, "this.write(").replace(window.gScriptLoader.m_reScriptTagOpen, '').replace(window.gScriptLoader.m_reScriptTagClose, '');

		try
		{
			eval(sScript);
			var placeHolderNode = document.getElementById(this.m_sId);

			if(placeHolderNode)
			{
				var parentNode = placeHolderNode.parentNode;

				placeHolderNode.innerHTML = this.m_sText;

				return true;
			}
		}
		catch(e){}
	}

	return false;
};

/**
 * Builds a string and caches it locally to be inserted later on during execution
 */
CDocumentWriter.prototype.write = function(oArgument)
{
	var sResult = "";
	if(typeof oArgument == "function")
	{
		sResult = eval(oArgument);
	}
	else if(typeof oArgument == "string")
	{
		sResult = oArgument;
	}

	this.m_sText += sResult;
};


