    /* %fv: udatalayer.js-70 % %dc: Thu Aug 06 14:40:53 2009 %*/

/******************************************************************************
COPYRIGHT
    (C) 2008 Compuware Corporation.  All rights reserved.
    Unpublished - rights reserved under the Copyright Laws of the United States.

    U.S. GOVERNMENT RIGHTS-Use, duplication, or disclosure by the
    U.S. Government is subject to restrictions as set forth in
    Compuware Corporation license agreement and as
    provided in DFARS 227.7202-1(a) and 227.7202-3(a) (1995),
    DFARS 252.227-7013(c)(1)(ii)(OCT 1988), FAR 12.212(a) (1995),
    FAR 52.227-19, or FAR 52.227-14 (ALT III), as applicable.
    Compuware Corporation

    This product contains confidential information and trade
    secrets of Compuware Corporation.  Use disclosure, or
    reproduction is prohibited
    without the prior express written permission of Compuware Corporation.
******************************************************************************/

/*******************************************************************************
date   refnum    version who description
080411 c26508    9.ajax  tsk mashup enablement
080508 c26571    9.ajax  mzu add more API function for unit test
080611 c26696    9.ajax  mzu Move command-related methods from ubase to udatalayer
080911 c27012    9.ajax  jdk Added webmessage
081015 c26877    9.ajax  jdk uwindow should be created without ID
081107 c27220    9.ajax  mzu Export AjaxRequest
090401 c27358    9401c1  fd  RIA: Use field IDs rather than names in the JSON stream.
090528 c27361    9401c1  mzu Change Command processing to a queue style.
* date   refnum    version who description
*******************************************************************************/

/*global UNIFACE document ActiveXObject XMLHttpRequest alert location window JSON */

function uNIFACE_doEval(a_text)
{
//    with(window) {
        /*jslint evil: true */
        (window["eval"] ? window["eval"](a_text) :  eval(a_text));
        /*jslint evil: false */
    //}
}

(function(){


var preCommandEvents = {};
var postCommandEvents = {};

var requestManager = (function(){
	var requestNextId = 1;
	var requestNum = 0;
	var _hadAsyncRequest = false;
	var requestMap = {};
	UNIFACE.trace("initializing requestManager");
	
	return {
	    getReq : function(aID)
	    {
	        return requestMap[aID];
	    },
		registerReq : function(aReq) {
			if ( !aReq.manageable ) {
				return;
			}
			if (aReq.id === undefined)
			{
			    aReq.id = this.generateId();
			}
			if ( typeof requestMap[aReq.id] !== "object" ) {
				requestNum++;
				_hadAsyncRequest = true;
			}
			requestMap[aReq.id] = aReq;
			UNIFACE.trace("after registerReq: requestNum=" + requestNum + " req id = " + aReq.id );
		},
		
		unregisterReq : function(aId) {
			UNIFACE.trace("before unregisterReq: requestNum=" + requestNum+ " req id = " + aId);
			if ( typeof requestMap[aId] === "object" ) {
				if ( requestNum > 0 ) {
					requestNum--;
				}
				delete requestMap[aId];
			}
			UNIFACE.trace("after unregisterReq: requestNum=" + requestNum+ " req id = " + aId);
		},
		
		abortReq : function(aId) {
		    UNIFACE.trace("aborting request " + aId);
			var req = requestMap[aId];
			if ( req ) {
				this.unregisterReq(aId);
				if ( req.scope ) {
					req.scope.unBlock();
				}
			}
		},
		
		abortAllReqs : function() {
			var id, req;
			for (id in requestMap) if ( requestMap.hasOwnProperty(id) ) {
				this.abortReq(id);
			}
			this.clearRequestNum();
		},
		
		onStateChange : function(aId) {
            UNIFACE.trace("onStateChange req " + aId.toString()  );

			if (true &&  typeof requestMap[aId] !== "undefined" ) {
                 UNIFACE.trace("attempt requestMap[aId].onStateChange() req " + aId.toString()  );
				requestMap[aId].onStateChange();
			}
		},

		clearRequestNum : function() {
			requestNum = 0;
			_hadAsyncRequest = false;
			requestMap = {};
			UNIFACE.trace("ClearNum: requestNum=" + requestNum);
		},
		
		hadAsyncRequest : function() {
			return _hadAsyncRequest;
		},
		
		shouldIdle : function() {
			return (requestNum === 0);	
		},
		
		generateId : function() {
			var generatedId = requestNextId;
			requestNextId++;
            UNIFACE.trace("UNIFACE request manager: just generated request ID " + generatedId + ".");
			return generatedId;
		},
		
		getUpcomingRequestId : function() {
			return requestNextId;
		}
	};
})();


var initialCommands = []; 


/**
Commands that are suspended because *somthing* was blocked

The output fields of suspended commands are blocked as well, to ensure proper order of requests.

Contains objects of type RequestScope
*/
var blockedCommands = []; 

var loadedScript = {};


/**
Run all blocked commands.

Algorithm:
- The output for all suspended commands is blocked. Unblock it first.
- Go down the list, for each command:
    - Check whether it's still blocked
    - Block its output
    - If command was not blocked: execute it
    - Otherwise: leave on the queue

This algorithm should be improved such that:
- The enabled/disabled state for the fields that are blocked and unblocked during 
this process is updated only once, after the whole queue has been processed
*/
function runBlockedCommands()
{
    var i;
    
    for (i = 0; i<blockedCommands.length; i++)
    {
        blockedCommands[i].unBlock();
    }
    i=0;
    while (i<blockedCommands.length)
    {    
        /* 
        1. Check that the field firing the event still exists.
            If not, just discard it.
        */
        if (!blockedCommands[i].checkInstance)
        {
            // Node is not connected to LUV any more - discard the command
            blockedCommands.splice(i,1);
        }
        /*
        2. Check that the command is not blocked any more, 
           and block its output
        */
        else if (!blockedCommands[i].checkAndBlock())
        {
            blockedCommands[i].execute();
            blockedCommands.splice(i,1);
        }
        else
        {   
        // 3.  This command can not be executed yet
            i++;
        }
    }
}    

/** 
Helper function to create XMLHttpRequest object.
Used in dynamic JS loading for browsers that do not have an onload/onreadystatechange
event on script tags, and for AJAX requests.
*/
function creXHR()
{
    if (typeof window.ActiveXObject != 'undefined' ) 
    {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    else 
    {
        return new XMLHttpRequest();
    }
}

/**
Dynamically add CSS to a page. This occurs when a DSP container loads a DSP that introduces new widgets,
in response to a "CSS" command from the JSON stream.
*/
function addCSS(a_css)
{
    var i;
    var l_elms = document.getElementsByTagName('link');        
    var l_existingElms = {};
    for (i = 0; i<l_elms.length; i++)
    {
        if (l_elms[i].rel === "stylesheet" && l_elms[i].type === "text/css")
        {
            l_existingElms[l_elms[i].attributes.href.value] = true;
            l_existingElms[l_elms[i].href] = true;
        }
    }
    for (i = 0; i<a_css.length; i++)
    {
        if (!(a_css[i] in l_existingElms))
        {
            var l_el = document.createElement("link");
            l_el.href = a_css[i];
            l_el.rel = "stylesheet";
            l_el.type = "text/css";
            document.getElementsByTagName('head')[0].appendChild(l_el);        
        }
    }
}

/**
Dynamically add script to a page. This occurs when a DSP container loads a DSP that introduces new widgets,
in response to a "JS" command from the JSON stream.
The a_ONLOAD is called as soon as the script has finished loading.
*/
function addScript(a_src, a_onload)
{

    var l_src = "";
    var l_text = "";
    if (typeof a_src === "object")
    {
        if ("src" in a_src)
        {
            l_src = a_src.src;
        }
        else if ("text" in a_src)
        {
            l_text = a_src.text;
        }
    }
    else
    {
        l_src = a_src;
    }

    var l_el = document.createElement("script");
    if (l_src)
    {
        l_el.src = l_src;
        UNIFACE.dl.commands.freeze();    
    }
    l_el.type = "text/javascript";
    if (l_text)
    {
        var l_tn = document.createTextNode(l_text);
        l_el.appendChild(l_tn);        
    }
    if (a_onload !== undefined)
    {
        l_el.onload = a_onload;
        l_el.onreadystatechange= function () {
            if (this.readyState == 'complete' || this.readyState == 'loaded')
            {
                this.onreadystatechange = null;
                a_onload();
            }
        };
   }
    document.getElementsByTagName('head')[0].appendChild(l_el);

    return l_el;
}

/**
Dynamically add script to a page. This occurs when a DSP container loads a DSP that introduces new widgets,
in response to a "JS" command from the JSON stream.
Currently unused -  this function uses XMLHttpRequest to load the JS, which is not compatible with some libraries
(DOJO) that expect a script tag to be present.
*/
function ldScript(a_script)
{
    var l_xhr = creXHR();
    l_xhr.open("GET",a_script, false);
    l_xhr.send("");
    
    if (true && l_xhr.status==200)
    {
        if (l_xhr.responseText !== null)
        {
            uNIFACE_doEval(l_xhr.responseText );
        }
    }
}

/**
Dynamically add script to a page. This occurs when a DSP container loads a DSP that introduces new widgets,
in response to a "JS" command from the JSON stream.
This method is currently in use.

It adds a <script> tag to the page, then subsequently freezes the command queue until the script tag has finished 
loading.
This ensures that any dependencies are resolved in the corrent order, and that no attempt is made to realize widgets
whose implementation has not been loaded yet.
*/
function addJS(a_JS)
{
    /* Check that the script was not loaded yet */
    var l_elms = document.getElementsByTagName('script');        
    var l_existingElms = {};
    var i;
    for (i = 0; i<l_elms.length; i++)
    {
        if (l_elms[i].type === "text/javascript" && l_elms[i].src)
        {
            l_existingElms[l_elms[i].attributes.src.value] = true;
            l_existingElms[l_elms[i].src] = true;
        }
    }
    if (!(a_JS in l_existingElms) && !(a_JS in loadedScript))
    {
        loadedScript[a_JS]=true;  
        /* Load the script. When loading has finished, call the  UNIFACE.dl.commands.thawe() 
        function to restart JS Processing*/
        addScript(a_JS, UNIFACE.dl.commands.thawe );
        return;
    }
}

var    UJSON_VERSION_ID = "vsn";
var    UJSON_VERSION = "1";

/*
Used in UDOH tests to force synchronous instead of async requests.
*/
var onlySynchronous = false;

function UnifaceRequest()
{
}

UnifaceRequest.prototype.setOperation = function(a_operation)
{
    this.operation = a_operation;
};

function SubmitRequest()
{
    this.submitForm = document.createElement("form");
    this.submitForm.style.display = "none";
    this.submitForm.method = "POST";
    this.submitForm.acceptCharset = "UTF-8";
    this.paramElements = {};
    document.body.appendChild(this.submitForm);
}

SubmitRequest.prototype = new UnifaceRequest();


SubmitRequest.prototype.addParam = function(a_paramName, a_paramValue)
{
    if (this.paramElements[a_paramName] == undefined) /* pragma(allow-loose-compare) */
    {
        this.paramElements[a_paramName] = document.createElement("textarea");
        this.paramElements[a_paramName].name = a_paramName;
        this.submitForm.appendChild(this.paramElements[a_paramName]);
    }
    this.paramElements[a_paramName].value = a_paramValue;
};

SubmitRequest.prototype.addBodyPart = SubmitRequest.prototype.addParam;

SubmitRequest.prototype.setURL = function(a_url)
{
    this.submitForm.action = a_url;
};

SubmitRequest.prototype.send = function()
{
    if ( typeof this.operation === "string" && this.operation !== "" ) 
    {
        this.submitForm.action += ".";
        this.submitForm.action += this.operation;
    }
    this.addParam("u:requestType", "dynamic");
    this.addParam("u:responseType", "fullpage");
    
    this.submitForm.submit();
};

function AJAXRequest()
{
	this.manageable = true;
	this.id = undefined;
    this.xmlDoc = creXHR();
    this.paramString = "";
    this.method = "POST";
    this.requestType = "dynamic";
    this.responseType = "update";
}

AJAXRequest.prototype = new UnifaceRequest();

AJAXRequest.prototype.addParam = function(a_paramName, a_paramValue)
{
    if (this.paramString.length !== 0)
    {
        this.paramString += "&";
    }
    this.paramString += encodeURIComponent(a_paramName) + "=" + encodeURIComponent(a_paramValue);
};

AJAXRequest.prototype.addBodyPart = AJAXRequest.prototype.addParam;

AJAXRequest.prototype.setURL = function(a_url)
{
    this.url = a_url;
};

/*------------------------------------------*/
AJAXRequest.prototype.onStateChange = function() 
{
    UNIFACE.trace("StateChange req " + (this.id ? this.id.toString() : "<no id>" ) + " state " + this.xmlDoc.readyState.toString() );
    if ( this.xmlDoc.readyState != 4 ) 
    {
        return ;
    }

    try
    {
        UNIFACE.trace("StateChange req " + (this.id ? this.id.toString() : "<no id>" ));
        if (!onlySynchronous) {
            // The request is done; turn off the busy-indicator.
            if (this.asyncMode) {
                UNIFACE.extension.busyIndicator.setBusyAsync(false);
            } else {
                UNIFACE.extension.busyIndicator.setBusySync(false);
            }
        }

        // if "OK"
        if (true && this.xmlDoc.status==200)
        {
            requestManager.unregisterReq(this.id);
            if (this.xmlDoc.responseText !== null)
            {
                var upiput=null;
                if (this.xmlDoc.responseText.substr(0,1)!=="<")
                {
                    upiput = JSON.parse('[' +  this.xmlDoc.responseText + ']');
                }
                if (upiput)
                {
                    /* 
                    Schedule all commands in this response.
                    Processing is performed in the finally block below.
                    */                
                    UNIFACE.dl.initialCommand( { beforeResponse : null }, this);
                    UNIFACE.dl.initialCommand(upiput, this);
                    return;
                }
            }
        }

        if (this.xmlDoc.responseText.substr(0,1)=="<")
        {    /*@c26877*/
            UNIFACE.extension.popupWindow.showFailure('UNIFACE','Runtime error','Application error',this.xmlDoc.responseText);
        }
        else
        {
            alert("Server returned error code " + this.xmlDoc.status);
        }

        return true;
    }
    finally
    {
        /* Schedule a command so that after this respone has been completely processed
         (e.g. all commands have been processed), the nodes that were blocked for this request are unblocked.
        */
        if (true && this.scope !== undefined)
        {
            UNIFACE.dl.initialCommand( { unblock : this.instance}, this);
        }
        if (typeof this.callBack === "function")
        {
            UNIFACE.dl.initialCommand( { callback: this.callBack }, this);
        }
        UNIFACE.dl.initialCommand( { afterResponse : null }, this);
        
        
        /* Process the scheduled commands
        */
        UNIFACE.dl.commands.run();    
    }
};

AJAXRequest.prototype.send = function(a_callback)
{
    var me = this;
    var id = this.id;
    var wasCalled = false;
    
    this.callBack = a_callback;

    this.xmlDoc.onreadystatechange = function() {
        wasCalled = true;
        if (UNIFACE)
        {
            UNIFACE.trace("onreadystatechange " + (id ? id.toString() : "<no id>" ) + " state " + me.xmlDoc.readyState );
        }
        if ( me.manageable ) {
        	requestManager.onStateChange(id);   // loose coupled by a string id
        } else {
        	me.onStateChange();
        }
    };
    
    var targetUrl = this.url;
    if ( typeof this.operation === "string" && this.operation !== "" ) {
    	targetUrl += "." + this.operation;
    }
    
    if ( this.method === "GET" ) {
    	targetUrl += "?" + this.paramString;
    }
    
    this.xmlDoc.open(this.method, targetUrl, this.asyncMode);
    this.xmlDoc.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

    if ( this.method === "POST" ) {
        //this.addParam("requestBody", this.bodyText);
        
        this.addParam("u:requestType", this.requestType);
        this.addParam("u:responseType", this.responseType);
    } 
    
    if (!onlySynchronous) {
        // Turn on the busy-indicator.
        if (this.asyncMode) {
            UNIFACE.extension.busyIndicator.setBusyAsync(true);
        } else {
            UNIFACE.extension.busyIndicator.setBusySync(true);
        }
    }
        UNIFACE.trace("Async mode: " + this.asyncMode );

    if (this.asyncMode) {
        // Immediately send the request.
        this.xmlDoc.send(this.paramString);
        requestManager.registerReq(me);
    } else {
        // Wait a very short time before sending the synchronous request,
        // allowing for the busyIndicator to do its job.
        var sendIt = function(){
            me.xmlDoc.send(me.paramString);
        	requestManager.registerReq(me);
            
            // Firefox3 does not do the onreadystatechange callback...
            if (!wasCalled) {
        		me.onStateChange();
        	}
        };
        if (onlySynchronous) {
            sendIt();  // Immediately
        } else {
            window.setTimeout(sendIt, 5);
        }
    }
};

function UJSON_Exception(msg) {
	this.message = msg;
}

function assertUJSONversion(ujson_object) {
    if (ujson_object[UJSON_VERSION_ID] !== undefined && ujson_object[UJSON_VERSION_ID] !== UJSON_VERSION) {
        UNIFACE.throwException( new UJSON_Exception("UJSON version mismatch (expected \""+ UJSON_VERSION + "\", received \"" + ujson_object[UJSON_VERSION_ID] + "\").  Try a Refresh, or contact your application administrator."));
    }
}

function Command(a_cmd, a_data, a_request)
{
    this.cmd = a_cmd;
    this.data = a_data;
    this.req = a_request;
}

UNIFACE.namespace("dl").extend(
{
/* 
add one or more commands to the command scheduler
*/
initialCommand : function(a_commandSet, a_request)
{
     if (typeof a_commandSet == "object" && a_commandSet)
     {
         if (a_commandSet.constructor === Array)
        {
            var idx;
            for (idx =0; idx < a_commandSet.length; idx++)
            {
                UNIFACE.dl.initialCommand(a_commandSet[idx], a_request);
            }
        }
        else
        {
            var l_cmd;
            for (l_cmd in a_commandSet) if (a_commandSet.hasOwnProperty(l_cmd))
            {
                initialCommands.push( new Command( l_cmd, a_commandSet[l_cmd],a_request ) );
            }
        }
    }
},

/* 
compatibility.
*/
runInitialCommands: function() {
	UNIFACE.dl.commands.run();
},

/*
Call a trigger directly if scope is not blocked (handled by Notify() )
*/
callTrigger: function(a_field, a_triggerName, a_event, a_force)
{
    if (!a_force && UNIFACE.dl.commands.isProcessing() ) {  
        return;
    }
    
    // See if the field has the trigger property
    var l_triggerName = a_triggerName.toLowerCase();
    if (a_field.definition.triggers===undefined)
    {
        return;
    }
    var l_scope = a_field.definition.triggers[a_triggerName];
    if (l_scope ===undefined)
    {
        return;
    }

    // Call the trigger.
    UNIFACE.dl.Notify(l_triggerName, a_field, {}, "t");
    if (a_event != undefined) /* pragma(allow-loose-compare) */
    {
        if (a_event.preventDefault != undefined) /* pragma(allow-loose-compare) */
        {
            a_event.preventDefault();
        }
        return false;
    }
},

/*
Schedule calling a trigger after all pending commands have been processed.
*/
postTrigger: function(a_field, a_triggerName, a_force)
{
    UNIFACE.dl.initialCommand( { trigger: {  field : a_field, triggerName: a_triggerName, force: a_force} });
},

/*------------------------------------------*/
Notify : function(a_moduleName, a_realizedObject, a_args, a_moduleType)
{
    var l_ctx = new UNIFACE.scope.RequestScope();
    l_ctx.create(a_moduleName, a_realizedObject, a_args, a_moduleType);
    if (l_ctx.checkAndBlock())
    {
        blockedCommands.push(l_ctx);
    }
    else
    {
        l_ctx.execute();
    }
},

setAsyncMode : function(b) {
    onlySynchronous = !b;
},

loadDSP : function(anInstance, dspMode, aCallBackFunc) {
	var lParamSet = {"u:dspmode" : dspMode};
	/*if ( anInstance.componentName !== anInstance.instanceName ) {
		lParamSet["u:insname"] = anInstance.instanceName;
    }*/
    UNIFACE.dl.initialCommand( { loaddsp: {  instance : anInstance, args: lParamSet, callback: aCallBackFunc} });
},

postOperation : function(anInstance, anOperName, aParamSet) {
	/*if ( anInstance.componentName !== anInstance.instanceName ) {
		aParamSet["u:insname"] = anInstance.instanceName;
    }*/
    UNIFACE.dl.Notify(anOperName, anInstance, aParamSet, "o");
},
createRequest : function(aTriggerType)
{
	var l_req;
    if (aTriggerType == "FULLPAGE") {
        l_req = new SubmitRequest();
    } else {
        l_req = new AJAXRequest();
        l_req.asyncMode = !onlySynchronous;
    }
    return l_req;
},
AJAXRequest : AJAXRequest, // @c27220
idleEvent : new UNIFACE.Event(),
hadAsyncRequest : function() { return requestManager.hadAsyncRequest(); },
abortAllAsyncRequests :  function() {return requestManager.abortAllReqs(); },
getReq :  function(aId) { return requestManager.getReq(aId); },
getUpcomingReqID : requestManager.getUpcomingRequestId,
requestManager : requestManager,
preCommandEvent : function(aCmd)
{
    if (preCommandEvents[aCmd] === undefined)
    {
        preCommandEvents[aCmd] = new UNIFACE.Event();
    }
    return preCommandEvents[aCmd];   
},

postCommandEvent : function(aCmd)
{
    if (postCommandEvents[aCmd] === undefined)
    {
        postCommandEvents[aCmd] = new UNIFACE.Event();
    }
    return postCommandEvents[aCmd];   
}

}); // end of UNIFACE.dl


(function(){  // @c27361
	var _isInitial = false;
	var _mainCommands = [];
	var _macroQueue = {};
	var _frozen = false;

	function _unregisterMacro(anId)
                {
		var lData = _macroQueue[anId];
		delete _macroQueue[anId];
		return lData;
    }

	function _pendMacro(aMacroData) 
    {
		var id = aMacroData.instancename + "#" + aMacroData.operationName;

		if ( !_macroQueue[id] ) {
			_macroQueue[id] = aMacroData;
	        _mainCommands.push(new Command("macro" , {"macroId" : id}));
        }
    }
    
	function _addMainCommand(aCmdName, aCmdData)
    {
		if ( aCmdName === "macro" && aCmdData.params && aCmdData.params.runOnce ) {
			_pendMacro(aCmdData);
		} else {
	        _mainCommands.push(new Command(aCmdName, aCmdData));
        }
    }
    
    Command.prototype = {
        execute: function()
        {
            var l_cmd = this.cmd.toLowerCase();
            if (preCommandEvents[l_cmd] !== undefined)
            {
                preCommandEvents[l_cmd].fire(l_cmd, this.data, this.req);
            }
            var l_cptName;
            var l_instName;
            var l_data;
            var l_component;
            var l_dspDef;
            var l_Id = "";

            switch(l_cmd)
            {
                case "newdata":
                    UNIFACE.trace("newdata");
                    assertUJSONversion(this.data);
                    for (l_cptName in this.data) if (this.data.hasOwnProperty(l_cptName) && typeof this.data[l_cptName] === "object")
                    {
                        l_component = UNIFACE.luv.getComponent(l_cptName);
                        if (l_component)
                        {
                            if (this.req === undefined || this.req.scope === undefined || this.req.scope.outScope === undefined || this.req.scope.outScope[l_cptName] === undefined)
                            {
                                l_component.render(this.data[l_cptName]);
                        		UNIFACE.trace("rendered: " + l_cptName);
                            }
                            else
                            {
                                var lData = this.data[l_cptName];
                                l_component.mergeData( lData, this.req.scope.outScope);
                                l_component.render(l_component.data);
                        		UNIFACE.trace("rendered: scope " + l_cptName);
                            }
                        }
                    }
                    break;
                case "apptitle":
                    document.title=this.data;
                    break;
                case "formtitle":
                    for (l_cptName in this.data) if (this.data.hasOwnProperty(l_cptName))
                    {
                        l_component = UNIFACE.luv.getComponent(l_cptName);
                        if (l_component)
                        {
                            l_component.setTitle(this.data[l_cptName]);
                        }
                    }
                    break;
                case "instance":
                    assertUJSONversion(this.data);
                    for (l_instName in this.data) if (this.data.hasOwnProperty(l_instName))
                    {
                        if (typeof this.data[l_instName] === "object")
                        {
                    	    l_data = this.data[l_instName];
                        	if ( typeof l_data.componentname === "string") {
                        	    l_cptName = l_data.componentName;
                        	} else {
                        		l_cptName = l_instName;
                        	}
                            l_dspDef = UNIFACE.luv.getDspDef(l_cptName);
                            l_dspDef.def = l_data;
                            l_component = UNIFACE.luv.getComponent(l_instName, l_cptName);
                            l_component.define(l_data);
                        }
                    }
                    break;
                case "webmessage":    
                    UNIFACE.extension.popupWindow.showMessage(this.data.message,this.data.buttontext,this.data.title,parseInt(this.data.xsize,10),parseInt(this.data.ysize, 10),this.data.type);
                    break;
                case "css":
                    addCSS(this.data);
                    break;
                case "js":
                    addJS(this.data);
                    break;
                case "layout":
                    // Send layout to appropriate DSP widget
                    for (l_data in this.data) if (this.data.hasOwnProperty(l_data) && l_data.match(/_I[0-9a-zA_Z]+/))
                    {
                        l_data = this.data[l_data]["#2"].occs[0];
                        var l_layout = l_data["#5"].value;
                        var l_inst = l_data["#3"].value;
                        var l_comp = l_data["#4"].value;
                        var l_targetNode = l_data["#6"].value;
                        l_component = UNIFACE.luv.getComponent(l_inst, l_comp);
                        l_component.setLayout(l_layout, l_targetNode);
                        break;
                    }
                    break;
                    
                case "macro":
                    if ( _isInitial ) {
            	        _addMainCommand( "macro", this.data );
                    } else {
            	        if ( typeof this.data.macroId === "string" ) {
            		        this.data = _unregisterMacro(this.data.macroId);
                        }
                        l_component = UNIFACE.luv.getComponent(this.data.instancename);
                        UNIFACE.dl.postOperation(l_component, this.data.operationName, this.data.params);
                    }
                    break;
                 case "unblock":
                    this.req.scope.unBlock();
                    runBlockedCommands();
                    break;
                 case "loaddsp":
                    if (this.data.instance.targetNode === undefined)
                    {
                 	    UNIFACE.dl.Notify("exec", this.data.instance, this.data.args, "o");
                    }
                    else if (this.data.widget !== undefined)
                    {
                        this.data.instance.widget.doAttach();
                    }
                    break;
                 case "trigger":    
                    UNIFACE.dl.callTrigger(  this.data.field, this.data.triggerName, undefined, this.data.force);
                    break;
           }
           if (postCommandEvents[l_cmd] !== undefined)
           {
               postCommandEvents[l_cmd].fire(l_cmd, this.data, this.req);
           }
        }
    };
	
    function _iCommands() {
	    _isInitial = true;
	    try {
		    while ( !_frozen  && initialCommands.length > 0 ) {
	            initialCommands[0].execute();
	            initialCommands.shift();
		    }
	    } finally {
    	    _isInitial = false;
	    }
    }
	
    var _isRunningCommands = false;  // for avoiding recursive call of runCommands

	UNIFACE.namespace("dl.commands").extend(	    {
	        run : function()
	        {
		        if ( _isRunningCommands ) {
			        return; // no recursive call
		        }
		        
		        _isRunningCommands = true;
        		
		        try 
		        {
			        _iCommands();
        			
			        while ( !_frozen  &&  _mainCommands.length > 0 ) 
			        {
		                _mainCommands[0].execute();
		                _mainCommands.shift();
				        _iCommands();
			        }
		        } 
		        finally 
		        {
			        if (!_frozen) 
			        { 
			            _isRunningCommands = false; 
			        }
			    }
	            if (_mainCommands.length === 0)
	            {
	                runBlockedCommands();   
	            }
	            if ( initialCommands.length === 0 && blockedCommands.length === 0 && requestManager.shouldIdle() ) {
	                UNIFACE.trace("firing IdleEvent: initialCommands.length === " + initialCommands.length  + "blockedCommands.length === "  + blockedCommands.length + " && requestManager.shouldIdle()===" + requestManager.shouldIdle());
	            	requestManager.clearRequestNum();
	            	UNIFACE.dl.idleEvent.fire();
	            }
            },
            freeze : function()
            {
                _frozen = true;           
            },
            thawe : function()
            {
                if (_frozen)
                {
                    _frozen = false;
                    _isRunningCommands = false;
                    UNIFACE.dl.commands.run();      
                }
            },
            isProcessing : function()
            {
                return _isRunningCommands && ! _frozen;
            }
	    }
    );
  }()); // Inner Closure of commands namespace
  
}()); // Outer closure of datalayer namespace



UNIFACE.addOnLoadListener(UNIFACE.bind(UNIFACE.dl.runInitialCommands, UNIFACE));

// For backward compatibility
UNIFACE.initialCommand = UNIFACE.dl.initialCommand;

