﻿// TODO: tidy the structure

//Class PostBox
function PostBox(flag)
{
    //private area
    var _data = new Array();
    var k=1;
    var _gridNameList = "";
   
    //public area
    this.Flag = flag;
    this._gridNameList = "";
    this._dtList = "";
    this.Calls = "";
    this._objList = "";
    this.Delay = 0;
    this.commType = "AJAX"; // AJAX | IFRAME
    this.location = null;
    
/*************************************************************************************

    Communication Data Management
     
/**************************************************************************************/    

    /////////Adding generic types/////////
    this.Add = function(objName,objValue){
        switch (typeof objValue)
        {
            case "number":
            case "string":
            case "boolean":
                _data[k++] = objName + "=" + objValue;
                this._objList += objName + " ";
                break;
            case "object":
                // check if array
                if (objValue.constructor.toString().match(/array/i) != null) {
                    this._objList += objName + " ";
                    
                    var tempstr='';
                    for (var i=0; i<objValue.length; i++) {
                        tempstr += objValue[i] + "^"; 
                    }
                    _data[k++] = objName + "=" + tempstr;
                }
                break;
            default:
                alert('This method does not support adding ' + (typeof objValue) + 'type');
        }
    };

    /////////Adding a form data/////////
    this.AddForm = function(frm){
    
        var elements = frm.elements;
        var type;
        for (var i=0;i<elements.length;i++)
        {
            type=elements[i].type;
            if (type=='text' || type=='hidden' || type=='checkbox' || type=='textarea' || type=='radio' || type=='password' || type=='select-one' || type=='file')
            {
                _data[k++] = elements[i].name + "=" + elements[i].value;
                this._objList += elements[i].name + " ";
            }
        }
    };
    
    ///////// Adding a grid data, this must be used if you want the data to be read into a datatable /////////
    //By default, only add the modified row of grid
    this.AddGrid = function(wgname,rowIndex){
        var wg = document.all(wgname);
        var nColOffset = wgColOffset(wgname);
        var colList = "";
        var curRow = 0;
        
        if (rowIndex != null){      //Only add one row
            _data[k++] =  wg.id + "_0_0" + "=" + wg.TextMatrix(rowIndex,gwgFlgCol);
            for (var j=nColOffset;j<wg.Cols;j++){
                if (wg.ColDataType(j) == flexDTBoolean) {
                    if (wg.Cell(5, i + wg.FixedRows -1, col) == 1) {
                        _data[k++] = wg.id + "_0_" + (j-nColOffset+1) + "=Y";
                    } else {
                        _data[k++] = wg.id + "_0_" + (j-nColOffset+1) + "=N";
                    }
                } else {
                    if (wg.ColData(j)[1]=='DT()' || wg.ColData(j)[1]=='TM()' || wg.ColData(j)[1]=='DTM()') {
                        _data[k++] = wg.id + "_0_" + (j-nColOffset+1) + "=" + wg.TextMatrix(rowIndex,j).replace(/\/|-|:|\s/g,'');
                    } else if (wg.ColData(j)[1].substr(0,2)=='N(') {
                        _data[k++] = wg.id + "_" + rowCount + "_" + (j-nColOffset+1) + "=" + wg.TextMatrix(rowIndex,j).replace(/,/g,'');
                    } else {
                        _data[k++] = wg.id + "_0_" + (j-nColOffset+1) + "=" + wg.TextMatrix(rowIndex,j);
                    }
                }
            }
            curRow = rowIndex;
        }else{
            var rowCount = 0;
            curRow = wg.row;
            for (var i=wg.FixedRows;i<wg.Rows;i++){
                //ignore the queried ("Q") and empty "" rows, include checked rows
                if ((wg.textMatrix(i,gwgFlgCol) != "Q" && wg.textMatrix(i,gwgFlgCol) != "") || wg.isChecked(i)==true){
                    _data[k++] =  wg.id + "_" + rowCount + "_0" + "=" + wg.TextMatrix(i,gwgFlgCol);
                    for (j=wgColOffset(wgname) ;j<wg.Cols;j++){
                         //column indexes incremented by 1 to include INSFLAG column
                        if (wg.ColDataType(j) == flexDTBoolean) {
                            if (wg.Cell(5, i + wg.FixedRows -1, j) == 1) {
                                _data[k++] = wg.id + "_" + rowCount + "_" + (j-nColOffset+1) + "=Y";
                            } else {
                                _data[k++] = wg.id + "_" + rowCount + "_" + (j-nColOffset+1) + "=N";
                            }
                        } else {
                            if (wg.ColData(j)[1]=='DT()' || wg.ColData(j)[1]=='TM()' || wg.ColData(j)[1]=='DTM()') {
                                _data[k++] = wg.id + "_" + rowCount + "_" + (j-nColOffset+1) + "=" + wg.TextMatrix(i,j).replace(/\/|-|:|\s/g,'');
                            } else if (wg.ColData(j)[1].substr(0,2)=='N(') {
                                _data[k++] = wg.id + "_" + rowCount + "_" + (j-nColOffset+1) + "=" + wg.TextMatrix(i,j).replace(/,/g,'');
                            } else {
                                _data[k++] = wg.id + "_" + rowCount + "_" + (j-nColOffset+1) + "=" + wg.TextMatrix(i,j);
                            }
                        }
                    }
                    rowCount++;
                }
            }
            
            // add grid name
            this._gridNameList += wg.id + " ";

            // add grid column names
            colList += wg.id + "_INSFLAG ";
            for (j=nColOffset;j<wg.Cols;j++){
                colList += wg.ColKey(j) + " ";
            }
            _data[k++] = wg.id + "__COLNAMES" + "=" + colList;
            
            // add grid statistics
            _data[k++] = wg.id + "__COLS=" + (wg.Cols-nColOffset+1);  // +1 to include INSFLAG column
            _data[k++] = wg.id + "__ROWS=" + rowCount;
            if (curRow>0) {_data[k++] = wg.id + "__CURROW=" + curRow;}
        }
    };

    this.AddDataTable = function(name, data){
        
        // add grid name
        this._dtList += name + " ";

        // add column names
        var colList = "";
        for (var i=0; i<data[0].length; i++){
            colList += data[0][i] + " ";
        }
        _data[k++] = name + "__COLNAMES" + "=" + colList;

        // start from 2nd row, because 1st row contains column names
        
        for (var i=1; i<data.length; i++) {
            for (var j=0; j<data[i].length; j++) {
                _data[k++] = name + "_" + (i-1) + "_" + j + "=" + data[i][j];
            }
        }
        
        // add grid statistics
        _data[k++] = name + "__COLS=" + data[0].length;
        _data[k++] = name + "__ROWS=" + (data.length-1);

    };
    
    // adds controls specified by virtual form
    this.AddVForm = function(frmname) {
        
        var elements = $("#"+frmname+" "+SEL_ALL_ELEMENTS);
        for (var i=0;i<elements.length; i++)
        {
            this.AddElement(elements[i]);
        }
    };

    // adds all controls
    this.AddVFormAll = function() {
        var inputElements = document.getElementsByTagName('INPUT');
        var listElements = document.getElementsByTagName('SELECT');
        var objElements = document.getElementsByTagName('OBJECT');
        var tareaElements = document.getElementsByTagName('TEXTAREA');
        var elements = new Array(inputElements, listElements, objElements, tareaElements);
        var tag;
        var type;
        var curElement;
        var curElements;
        
        for (var i=0;i<elements.length;i++) {
            if (elements[i]!=null) {
                curElements = elements[i];
                for (var j=0;j<curElements.length; j++) {
                    curElement = curElements[j];
                    this.AddElement(curElement);
                }
            }
        }
    };
    
    this.AddElement = function(element){
        curElement = element;
        tag=curElement.tagName.toUpperCase();
        type=curElement.type.toUpperCase();
        if (tag=='INPUT') {
            if (type=='TEXT' || type=='HIDDEN' || type=='TEXTAREA' || type=='PASSWORD' || type=='SELECT-ONE' || type=='FILE') {
                var cleanVal = curElement.value;
                if (curElement.datatype) { 
                    if (curElement.datatype=='DT()' || curElement.datatype=='TM()' || curElement.datatype=='DTM()') { 
                        cleanVal = curElement.value.replace(/\/|-|:|\s/g,''); 
                    } else if (curElement.datatype.substr(0,2)=='N(') { 
                        cleanVal = curElement.value.replace(/\/|-|:|\s/g,''); 
                    }
                } 
                _data[k++] = curElement.name + "=" + cleanVal;
                this._objList += curElement.name + " ";
            } else if(type=='RADIO') {
                if (curElement.checked) {
                    _data[k++] = curElement.name + "=" + curElement.value;
                }
                this._objList += curElement.name + " ";
            } else if(type=='CHECKBOX') {
                _data[k++] = curElement.name + "=" + ((curElement.checked) ? 'Y' : 'N');
                this._objList += curElement.name + " ";
            }
        } else if (tag=='TEXTAREA') {
            _data[k++] = curElement.name + "=" + curElement.value;
            this._objList += curElement.name + " ";
        } else if (tag=='SELECT') {
            //if (curElement.selectedIndex >= 0) {
                _data[k++] = curElement.name + "=" + curElement.value; //curElement.options(curElement.selectedIndex);
                this._objList += curElement.name + " ";
            //}
        } else {
            if (tag=='OBJECT' && curElement.name.toUpperCase().substr(0,2)=='WG') {
                this.AddGrid(curElement.name);
            }
        }
    };

    this.AddCalls = function(fnName){
        this.Calls += fnName + " ";
        
        for (var i=1; i<arguments.length; i++) {
            this.Add(fnName + '_ARG' + i, arguments[i]);
        }

        this.Add(fnName + "_ARGS", arguments.length-1);
    };

    this.AddCallsArgArray = function(fnName){
        this.Calls += fnName + " ";
        
        var argCnt = 1;
        for (var i=1; i<arguments.length; i++) {
            if (isArray(arguments[i])) {
                for (var j=0; j<arguments[i].length; j++) {
                    this.Add(fnName + '_ARG' + argCnt++, arguments[i][j]);
                }
            } else {
                this.Add(fnName + '_ARG' + argCnt++, arguments[i]);
            }
        }
        argCnt--;

        this.Add(fnName + "_ARGS", argCnt);
    };
    
    /////////Override the toString method for returning a value/////////
    this.ToString = function(){
        _data[0] = "Flag=" + this.Flag;
        for (var i=0;i < _data.length;i++){
            if (typeof _data[i] == "string"){
                _data[i] = _data[i].replace(/&/g,"%26");
             }
        }
        //List of grid
        _data[i++] = "COMM_TYPE=" + this.commType;
        _data[i++] = "GRID_NAME_LIST=" + this._gridNameList;
        _data[i++] = "CALL_LIST=" + this.Calls;
        _data[i++] = "OBJ_LIST=" + this._objList;
        _data[i++] = "DT_LIST=" + this._dtList;
        if (this.Delay>0) {_data[k++]="DELAY=" + this.Delay.toString();}
        var sReturn = _data.join("&");
        //Final handling
        sReturn = sReturn.replace(/'/g,"''");   //single quote
        sReturn = sReturn.replace(/\\/g,"\\\\");
        return sReturn;
    };

    this.ToHiddenForm = function(str){
        var keyValStrList = str.split("&");
        
        var form = document.createElement("form")
//        var form = document.createElement('<form '+
//				'method="post" '+
//				'enctype="multipart/form-data" '+
//				'action="/common/fileexport.aspx" '+
//				'target="POST_IFRAME"'+
//			'></form>'
//        );

        var hiddenInput,key,val,keyVal;
        
        for (var i=0; i<keyValStrList.length; i++) {
//            key = keyValStrList[i].split("=")[0];
//            val = keyValStrList[i].split("=")[1];
//            hiddenInput = document.createElement('<input type="hidden" id="'+key+'" name="'+key+'" value="'+val+'" />');
            keyVal = keyValStrList[i].split("=");
            hiddenInput = document.createElement('<input type="hidden" id="'+keyVal[0]+'" name="'+keyVal[0]+'" value="'+keyVal[1].replace(/%3D/g,'=').replace(/''/g,"'")+'" />');
            form.appendChild(hiddenInput);
        }
        
        return form;
    
    };
    

/*************************************************************************************

    Communication : Normal Ajax
     
/**************************************************************************************/    
    
    /*******************************************************/
    this.PostBack = function(fCallBack)
    {
        var sCurUrl = location.pathname;
        this.PostTo(sCurUrl,fCallBack)
    };
    /*******************************************************/
    this.PostTo = function(toUrl,fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", toUrl, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    unblockUI();
                    debug(xmlHttp.status+':'+decodeXmlHttpStatus(xmlHttp.status),xmlHttp.responseText);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        ParseResponse(rb, fCallBack);
                    }
                    unblockUI();

                }
            }
         };
        xmlHttp.send(sPostData);
    };
    
    function ParseResponse(rb, fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        
        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            RestorePrevState();
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);
            ParseFocus(rb);
            ParseDebug(rb);
            //DiagnoseResult(rb);
            return;
        }

        var result = convertResponse(rb);

        // set values
        SetForm(rb);
        
        // display messages if any
        ParseAlert(rb);
        
        // display debug info if any
        // not necessary here because rb.RESULT will be false for unhandled exceptions
        // ParseDebug(rb);
        
        // display status if any
        ParseStatus(rb);
        
        // set focus if any
        ParseFocus(rb);
        
        // refresh screen if required
        ParseRefresh(rb);
        
        // execute client side script if specified
        ParseClientScript(rb);
        
        // forward to handler if custom handler exists
        if (fCallBack != null){
            if (fCallBack(result.obj)) return;  //Forge stop default handling
        }

    }

    
/*************************************************************************************

    Communication : Post to hidden Iframe
     
/**************************************************************************************/    

    // normal http request using hidden iframe
    // currently only used for excel export
    // TODO: cleanup after excel download is complete
    this.Post = function(toUrl, fn, args, target) {
        
        this.commType = "IFRAME";
        toUrl = (toUrl) ? toUrl : location.pathname;

        var postIframeContainer, postIframe, postForm;

        postForm = this.ToHiddenForm(this.ToString());
        postForm.method = 'post';
        postForm.enctype = 'multipart/form-data';
        //postForm.enctype = 'application/x-www-form-urlencoded';
        postForm.action = toUrl;
        
        if (target) {
            switch (target.type) {
                case 'IFRAME':
                    postForm.target = target.name;
                    document.body.appendChild(postForm);
                    postForm.submit();
                    document.body.removeChild(postForm);
                    break;
                    
                case 'NEWWIN':
                    if (target.name) {
                        var features = target.features || "width=1014,height=710,top=0,left=0,scrollbars=auto,status=no,resizable=yes,maximize=1";
                        window.open("",target.name,features);
                        postForm.target = target.name;
                    } else {
                        postForm.target = "_blank";
                    }
                    document.body.appendChild(postForm);
                    postForm.submit();
                    document.body.removeChild(postForm);
                    break;

                default:
                    break;
            }

        } else {
            postForm.target = 'POST_IFRAME';

            // reuse hidden iframe container        
            if (!document.all('POST_IFRAME')) {
                // create iframe container object
                postIframeContainer = document.createElement('<div>');
                postIframeContainer.style.position = 'absolute';
                postIframeContainer.style.zIndex = '10';
                postIframeContainer.style.display = 'none';
                postIframeContainer.style.top = '10px';
                postIframeContainer.style.left = '10px';
                postIframeContainer.style.width = '600px';
                postIframeContainer.style.height = '600px';
                postIframeContainer.style.backgroundColor = "#ff0000";
                postIframeContainer.id = 'POST_DIV';

                // create dummy layers to enable display over activex
                postIframe = document.createElement('<iframe id="POST_IFRAME" name="POST_IFRAME" style="position: absolute; z-index: 1; width: 100%; height: 100%; top: 0; left: 0; scrolling: no; " marginwidth="0" marginheight="0" frameborder="0" src=""></iframe>');

                // append iframe
                postIframeContainer.appendChild(postIframe);
                document.body.appendChild(postIframeContainer);
            } else {
                postIframeContainer = document.all('POST_DIV');
                postIframe = document.all('POST_IFRAME');
            }

            postIframeContainer.appendChild(postForm)

            // submit
            postForm.submit();
            
            // clear temporary form
            postIframeContainer.removeChild(postForm);

		    $(postIframe).unbind().load(function() {
                //Try to evaluate responseText to get Response box
                var rb;                            //Response box
                var hasErr = false;
                try{
                    rb = eval("(" + $(this.contentWindow.document.body).text() + ")");
                }
                catch (err){
                    hasErr = true;
                    unblockUI();
                    RestorePrevState();
                    debug('Invalid response from server!','Err Message: '+ err.description);
                    //toggle debuging information
                }
                
                if (!hasErr) {
                    ParseResponseArgs(rb, fn, args);
                }
                unblockUI();
		    });
        }

    };    

/*************************************************************************************

    Communication : Normal Ajax (with original arguments carried forward to callback)
     
/**************************************************************************************/    
 
     /*******************************************************/
    this.PostBackArgs = function(fCallBack,args)
    {
        var sCurUrl = location.pathname;
        this.PostToArgs(sCurUrl,fCallBack,args)
    };
    /*******************************************************/
    this.PostToArgs = function(toUrl,fCallBack,args){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", toUrl, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    decodeXmlHttpStatus(xmlHttp.status);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        ParseResponseArgs(rb, fCallBack, args);
                    }

                    unblockUI();

                }
            }
         };
        xmlHttp.send(sPostData);
    };

    function ParseResponseArgs(rb, fCallBack,args)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        
        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            RestorePrevState();
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);
            ParseFocus(rb);
            ParseDebug(rb);
            //DiagnoseResult(rb);
            return;
        }
        
        var result = convertResponse(rb);
        
        // set values
        SetForm(rb);
        
        // display messages if any
        ParseAlert(rb);
        
        // display debug info if any
        // not necessary here because rb.RESULT will be false for unhandled exceptions
        // ParseDebug(rb);
        
        // display status if any
        ParseStatus(rb);
        
        // set focus if any
        ParseFocus(rb);
        
        // refresh screen if required
        ParseRefresh(rb);
        
        // execute client side script if specified
        ParseClientScript(rb);
        
        // forward to handler if custom handler exists
        if (fCallBack != null){
            if (fCallBack(result,args)) return;  //Forge stop default handling
        }

    }

/*************************************************************************************

    Communication : Code Validation
     
/**************************************************************************************/    
    
    this.PostCodeValidate = function(args,fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        //blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        var codeFile = args.codefile || '/common/codemaster.aspx';
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", codeFile, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    decodeXmlHttpStatus(xmlHttp.status);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        //unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        ParseCodeValidate(rb, args, fCallBack);
                    }
                    //unblockUI();

                }
            }
         };
        xmlHttp.send(sPostData);
    };

    function ParseCodeValidate(rb,codeinfo,fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        
        var blockList = [];
        blockList.push(codeinfo.keycond);
        if (codeinfo.othdesc) {
            blockList = blockList.concat(codeinfo.othdesc);
        }
        blockList = blockList.concat(codeinfo.precond);
        if (codeinfo.optcond) {
            blockList = blockList.concat(codeinfo.optcond);
        }

        $(jqfy(blockList.join(','))).unblock();
        setFocus(document.all(window.lastFocus));

        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);        
            ParseDebug(rb);
            return;
        }

        var retval = ParseReturnValue(rb);
        if (retval == 'null') {
            // display messages if any
            ParseAlert(rb);        
            search_code(codeinfo);
            return;
        }
        
        document.all(codeinfo.keycond).value = retval[0];
        
        for (var i=0; i<codeinfo.othdesc.length; i++) {
            if (document.all(codeinfo.othdesc[i])) document.all(codeinfo.othdesc[i]).value = retval[i+1];
        }
        
        // forward to handler if custom handler exists
        if (fCallBack != null){
            if (fCallBack(rb,args)) return;  //Forge stop default handling
        }

    };

/*************************************************************************************

    Communication : Code Search (Code Popup) for form and grid
     
/**************************************************************************************/    

    this.PostCodeSearch = function(fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        blockUI( { css: { width:'30%', left: '35%' } } );
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", window.location, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    decodeXmlHttpStatus(xmlHttp.status);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        ParseCodeSearch(rb, fCallBack);
                    }
                    unblockUI();
                    

                }
            }
         };
        xmlHttp.send(sPostData);
    };    

    
    function ParseCodeSearch(rb,fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        
        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);        
            ParseDebug(rb);
            return;
        }

        var retdata = {
            ResultTotal: ParseByName(rb, 'ResultTotal'),
            PageCount:   ParseByName(rb, 'PageCount'),
            PageSize:    ParseByName(rb, 'PageSize'),
            PageSetSize: ParseByName(rb, 'PageSetSize'),
            ResultData:  ParseByName(rb, 'RETVAL'),
            DescList:    ParseByName(rb, 'DescList')
        };


        // forward to handler if custom handler exists
        if (fCallBack != null){
            if (fCallBack(retdata)) return;  //Forge stop default handling
        }

    };    

/*************************************************************************************

    Communication : Code List (Select box)
     
/**************************************************************************************/    

    this.PostCodeList = function(args, obj,fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        //blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");

        var codeFile = args.codefile || '/common/codemaster.aspx';
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", codeFile, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    decodeXmlHttpStatus(xmlHttp.status);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    
                    if (!hasErr) {
                        ParseCodeList(rb, obj, fCallBack);
                    }
                    unblockUI();

                }
            }
         };
        xmlHttp.send(sPostData);
    };    

    
    function ParseCodeList(rb,obj,fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        
        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);        
            ParseDebug(rb);
            return;
        }

        var retdata = {
            ResultData:  ParseByName(rb, 'RETVAL')
        };


        // forward to handler if custom handler exists
        if (fCallBack != null){
            if (fCallBack(obj,retdata)) return;  //Forge stop default handling
        }

    };    
/*************************************************************************************

    Communication : Grid Code Validation
     
/**************************************************************************************/    

    this.PostGridCodeValidate = function(args,fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        //blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        var codeFile = args.codefile || '/common/codemaster.aspx';
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", codeFile, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    decodeXmlHttpStatus(xmlHttp.status);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        ParseGridCodeValidate(rb, args, fCallBack);
                    }

                    unblockUI();

                }
            }
         };
        xmlHttp.send(sPostData);
    };


    function ParseGridCodeValidate(rb,codeinfo,fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        

        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);        
            ParseDebug(rb);
            return;
        }

        var retval = ParseReturnValue(rb);
        if (retval == 'null') {
            // display messages if any
            ParseAlert(rb);        
            wg_search_code(codeinfo);
            return;
        }

        var wg = document.all(codeinfo.gridId);
        var row = codeinfo.gridRow;
        
        wg.setVal(row, codeinfo.keycond, retval[0]);
        
        for (var i=0; i<codeinfo.othdesc.length; i++) {
            wg.setVal(row, codeinfo.othdesc[i], retval[i+1]);
        }
        
        // forward to handler if custom handler exists
        if (fCallBack != null){
            if (fCallBack(rb,args)) return;  //Forge stop default handling
        }

    }

/*************************************************************************************

    Communication : Calling Server Function
     
/**************************************************************************************/    

    /*******************************************************/
    this.PostBackFn = function(fCallBack)
    {
        var sCurUrl = this.location || location.pathname;
        this.PostToFn(sCurUrl,fCallBack)
    };
    /*******************************************************/
    this.PostToFn = function(toUrl,fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        //blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", toUrl, true);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    //unblockUI();
                    debug(xmlHttp.status+':'+decodeXmlHttpStatus(xmlHttp.status),xmlHttp.responseText);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        //unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        ParseResponseFn(rb, fCallBack);
                    }
                    //unblockUI();
                    

                }
            }
         };
        xmlHttp.send(sPostData);
    };    
    
    function ParseResponseFn(rb,fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return;
        }
        

        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);        
            ParseDebug(rb);
            return;
        }

        var retval = ParseReturnValue(rb);
        if (retval == 'null') {
            // display messages if any
            ParseAlert(rb);        
            return;
        }
        
        // forward to handler if custom handler exists
        if (fCallBack){
            if (fCallBack(retval)==false) return;  //Forge stop default handling
        }

    };

/*************************************************************************************

    Communication : Calling Server Function (Synchronous)
     
/**************************************************************************************/    

    /*******************************************************/
    this.SPostBackFn = function(fCallBack)
    {
        var sCurUrl = location.pathname;
        this.SPostToFn(sCurUrl,fCallBack)
    };
    /*******************************************************/
    this.SPostToFn = function(toUrl,fCallBack){
        var sPostData;
        sPostData = this.ToString();
	    //Change the state to running
        blockUI();
        var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        
        // ASYNCHRONOUS
        xmlHttp.open("POST", toUrl, false);
        
        // if SYNCHRONOUS is required, set the last argument to false
        // and onreadystatechange does not have to be managed
        // xmlHttp.open("POST", toUrl, false);
        
        xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
        
        xmlHttp.onreadystatechange = function()
        {
            if (xmlHttp.readyState == 4)
            {
                // if the returned status of the request is anything other than OK
                if (xmlHttp.status != 200) { 
                    unblockUI();
                    debug(xmlHttp.status+':'+decodeXmlHttpStatus(xmlHttp.status),xmlHttp.responseText);
                    return;
                }
                
                if (xmlHttp.responseText)
                {
                    //Try to evaluate responseText to get Response box
                    var rb;                            //Response box
                    var hasErr = false;
                    try{
                        rb = eval("(" + xmlHttp.responseText + ")");
                    }
                    catch (err){
                        hasErr = true;
                        unblockUI();
                        RestorePrevState();
                        debug('Invalid response from server! Err Message: '+ err.description,xmlHttp.responseText);
                        //toggle debuging information
                    }
                    
                    if (!hasErr) {
                        SParseResponseFn(rb, fCallBack);
                    }
                    unblockUI();
                    

                }
            }
         };
        xmlHttp.send(sPostData);
    };    
    
    function SParseResponseFn(rb,fCallBack)
    {
        if (rb == null){
            alert('Communicator returned from server with no reponse!'); 
            return null;
        }
        

        // if server passes false then halt all processing
        if (ParseResult(rb) == false) {
            if(ParseSessionTimeOut(rb)) {return;}
            ParseAlert(rb);        
            ParseDebug(rb);
            return null;
        }

        var retval = ParseReturnValue(rb);
        if (retval == 'null') {
            // display messages if any
            ParseAlert(rb);        
            return null;
        }
        
        return retval;
        
        // forward to handler if custom handler exists
//        if (fCallBack){
//            if (fCallBack(retval)==false) return;  //Forge stop default handling
//        }

    };
/*************************************************************************************

    Communication : Utilities
     
/**************************************************************************************/    
    
    //replace "return" char
    function replaceCrlf(sInput,replaceWith){
        var sRet = escape(sInput);
        for(i=0; i<sRet.length; i++){
            if(sRet.indexOf("%0D%0A") > -1){
                sRet=sRet.replace("%0D%0A",replaceWith);
            }
            else if(sRet.indexOf("%0A") > -1){
                sRet=sRet.replace("%0A",replaceWith);
            }
            else if(sRet.indexOf("%0D") > -1){
                sRet=sRet.replace("%0D",replaceWith);
            }
        }
        sRet=unescape(sRet);
        return sRet;
    }

    
    
    // When result false, try to show msg
    // unused
    function DiagnoseResult(rb)
    {
        var arToDo = rb.Flag.split(",")
        if (arToDo.length==0) {return;}
        for (var i=0;i<arToDo.length;i++)
        {
            switch (trim(arToDo[i])){
                case "ALERT":   // display messages if any
                    alert(rb.MSG);
                    break;
               case "DEBUG":     // display debug info if any
                    debug(rb.DEBUGMSG,rb.DEBUGDATA);
                    break;
               case "STATUS":   // Set the status bar if required
                    setStatus(rb.STATUS);
                    break;
            }
         }
    }
    
    function ParseReport(rb) {
        var sUrl = "/Report/REPORTER.aspx";
        //Passing the parameter to window
        sUrl += '?F=' + rb.Format + '&RF=' + rb.ReportFile + '&RN=' + rb.ReportName + '&Z=' + rb.Zoom + '&WC=' +  rb.WhereCond;
        if (rb.ReportView == 'NewWindow'){
            var nWidth = rb.Width;
            var nHeight = rb.Height;
            var nTop = (screen.availHeight - nHeight) / 2;
            var nLeft = (screen.availWidth - nWidth) / 2;
            window.open (sUrl,"YJITReporter","width=" + nWidth + ",height=" + nHeight + ",top=" + nTop + ",left=" + nLeft + ",scrollbars=yes,status=no,resizable=yes,maximize=0"); 
        }else if (rb.ReportView == 'Self')
        {
            window.location=sUrl;
        }else if (rb.ReportView == 'NewTab')
        {
            parent.openMenu("YJIT Reporter",sUrl);       //must be replaced with new tab
        }else if (rb.ReportView == 'AutoPrint') //not support yet
        {
            window.location=sUrl;   
        }
    }

    function ParseSessionTimeOut(rb) {
        var data = rb.RAW;
        if (data.length==0) {return false;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "ATTR":
                    if (data[i].NAME == 'SESSIONTIMEOUT') {
                        if (data[i].VALUE == 'Y') {
                            top.window.IsSessionTimeOut = true;
                            top.window.OpenReLogin();
                            return true;
                        } else {
                            return false;
                        }
                    }
                break;
            }
        }
        return false;
    }
    
    function ParseAlert(rb) {
        var data = rb.RAW;
        if (data.length==0) {return;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "INSTR":
                    if (data[i].NAME == 'ALERT') {
                        alert(data[i].VALUE);
                    }
                    break;
            }
        }
        return;
    }
    
    function ParseDebug(rb) {
        var data = rb.RAW;
        var debugMsg = '';
        var debugData = '';
        
        if (data.length==0) {return;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "INSTR":
                    if (data[i].NAME == 'DEBUGMSG') {
                        debugMsg = data[i].VALUE;
                    } else if (data[i].NAME == 'DEBUGDATA') {
                        debugData = data[i].VALUE;
                    }
                    break;
            }
        }
        
        if (debugMsg != '') {
            debug(debugMsg,debugData);
        }
        return;

    }

    function ParseStatus(rb) {
        var data = rb.RAW;
        if (data.length==0) {return;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "INSTR":
                    if (data[i].NAME == 'STATUS') {
                        setStatus(data[i].VALUE);
                    }
                    break;
            }
        }
        return;
    }

    function ParseFocus(rb) {
        var data = rb.RAW;
        if (data.length==0) {return;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "INSTR":
                    if (data[i].NAME == 'FOCUS') {
                        var fObj = document.all(data[i].VALUE);
                        if (fObj!=null) {setFocus(fObj);}
                    }
                    break;
            }
        }
        return;
    }

    function ParseRefresh(rb) {
        var data = rb.RAW;
        if (data.length==0) {return;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "INSTR":
                    if (data[i].NAME == 'REFRESH') {
                        var sURL = unescape(window.location);
                        window.location.reload();
                    }
                    break;
            }
        }
        return;
    }
    
    function ParseClientScript(rb) {
        var data = rb.RAW;
        if (data.length==0) {return;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "INSTR":
                    if (data[i].NAME == 'JSCALL') {
                        try{eval(data[i].VALUE)}
                        catch (Error) {setStatus('Failed to invoke server JSCall');}
                    }
                    break;
            }
        }
        return;

    }
    
    function ParseResult(rb) {
        var data = rb.RAW;
        if (data.length==0) {return true;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "ATTR":
                	  if (data[i].NAME == 'RESULT') {
                	  	  if (data[i].VALUE == 'false') {
                	  	      return false;
                	  	  }
                	  }
                    break;
            }
        }
        return true;
    }
    
    // Sets value of controls on the form based on the list of controls and values stored in response
    function SetForm(rb) {
        var data = rb.RAW;
        var objnm, objval;
        
        if (data.length==0) {return false;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "OBJ":
                    objnm = data[i].NAME;
                    objval = data[i].VALUE;

                    if (document.all(objnm)) { 
                        if (objnm.substr(0,2)=="WG") {
                            wgLoadArray(objnm, objval);
                            // set grid row if available
                            //if (eval("rb."+ctls[i]+"_ROW")) {
                            //    eval('wgSetRow("'+objnm+'",'+eval('rb.'+ctls[i]+'_ROW')+');'); 
                            //}
                        } else {
                            element = document.all(objnm);
                            switch (element.tagName.toUpperCase()) {
                                case 'INPUT':
                                    switch (element.type.toUpperCase()) {
                                        case 'BUTTON':
                                            break;
                                        case 'CHECKBOX':
                                            element.checked = (objval == 'Y') ? true : false;
                                            break;
                                        default:
                                            if (element.datatype) {
                                                element.value = FormatVal(objval, element.datatype);
                                            } else {
                                                element.value = objval;
                                            }
                                            break;
                                    }
                                    break;
                                case 'TEXTAREA':
                                    element.value = objval;
                                    break;
                                case 'SELECT':
                                    //element.selectedIndex = -1;
                                    var selectedIndex = element.options(objval);
                                    element.selectedIndex = selectedIndex;
                                    element.value = objval;
                                    break;
                                case 'OBJECT':
                                    break;
                                default:
                                    break;
                            }
                        }
                    } else {
                        switch (objnm.toUpperCase()) {
                            // codesearch related
                            case 'PAGEVOLUME':
                            case 'PAGECOUNT':
                            case 'RESULTDATA':
                            case 'RESULTTOTAL':
                            case 'DESCLIST':
                            // codecheck related
                            case 'COUNT':
                            case 'DATA':
                            case 'WGNAME':
                                break;
                            default:
                                alert("PostBox: SetForm: Cannot set value to invalid control: " + objnm);
                                break;
                        }
                    }                    
                    break;
            }
        }
        return false;

    }

    function ParseReturnValue(rb) {
        var data = rb.RAW;
        var objnm, objval;
        
        if (data.length==0) {return false;}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "OBJ":
                    if (data[i].NAME == 'RETVAL') {
                        return data[i].VALUE;
                    }
                    break;
            }
        }
        return 'null';

    }

    // retrieves item by name
    function ParseByName(rb, key) {
        var data = rb.RAW;
        var objnm, objval;
        
        if (data.length==0) {return 'null';}
        for (var i=0;i<data.length;i++)
        {
            switch (data[i].TYPE){
                case "OBJ":
                    if (data[i].NAME == key.toUpperCase()) {
                        return data[i].VALUE;
                    }
                    break;
            }
        }
        return 'null';

    }    
    
    var xErr = 
				    {"100": {"Description":"Continue"},
				     "101": {"Description":"Switching protocols"},
				     "200": {"Description":"OK"},
				     "201": {"Description":"Created"},
				     "202": {"Description":"Accepted"},
				     "203": {"Description":"Non-Authoritative Information"},
				     "204": {"Description":"No Content"},
				     "205": {"Description":"Reset Content"},
				     "206": {"Description":"Partial Content"},
				     "300": {"Description":"Multiple Choices"},
				     "301": {"Description":"Moved Permanently"},
				     "302": {"Description":"Found"},
				     "303": {"Description":"See Other"},
				     "304": {"Description":"Not Modified"},
				     "305": {"Description":"Use Proxy"},
				     "307": {"Description":"Temporary Redirect"},
				     "400": {"Description":"Bad Request"},
				     "401": {"Description":"Unauthorized"},
				     "402": {"Description":"Payment Required"},
				     "403": {"Description":"Forbidden"},
				     "404": {"Description":"Not Found"},
				     "405": {"Description":"Method Not Allowed"},
				     "406": {"Description":"Not Acceptable"},
				     "407": {"Description":"Proxy Authentication Required"},
				     "408": {"Description":"Request Timeout"},
				     "409": {"Description":"Conflict"},
				     "410": {"Description":"Gone"},
				     "411": {"Description":"Length Required"},
				     "412": {"Description":"Precondition Failed"},
				     "413": {"Description":"Request Entity Too Large"},
				     "414": {"Description":"Request-URI Too Long"},
				     "415": {"Description":"Unsupported Media Type"},
				     "416": {"Description":"Requested Range Not Suitable"},
				     "417": {"Description":"Expectation Failed"},
				     "500": {"Description":"Internal Server Error"},
				     "501": {"Description":"Not Implemented"},
				     "502": {"Description":"Bad Gateway"},
				     "503": {"Description":"Service Unavailable"},
				     "504": {"Description":"Gateway Timeout"},
				     "505": {"Description":"HTTP Version Not Supported"}}
               ;
               
    function decodeXmlHttpStatus(status){
        if(xErr[status.toString()]) {
            return xErr[status.toString()].Description;
        } else {
            return '';
        }
    }

// end of postbox    
}

    

