﻿/*
Future Features:
I) Currently request are sent to the server one by one in the order it was received.
   Performance or the speed of the application can be dramatically improved if multiple requests are sent to the server at the same time for processing.
   Server-side object must also be upgraded in order to implement this.
   This can be done, by creating a new server/client object that can be use by other ajax supported objects. i.e. xloader will have a property indicating that requests will be sent/receive from/to the server using (batch ajax object).
II) Data-compression for the data sent and received between the client and the server. Note: This should only be done for large amount of data in order to prevent unecesary overheard caused by the compression/decompression of the data.    
*/
/* XResponse ------------------------------------------------------------------ */
function XResponse(){
  this.requestId;
  this.action;
  this.content=null;
  this.loadXML=function(xml_node){
        var node;
        if(_bsVariable.isString(xml_node)){
          doc = _bsXML.getDoc(xml_node);
          if(!doc.childNodes[0]) return null;
          node = (doc.childNodes[0].nodeName=='xml')?doc.childNodes[1]:doc.childNodes[0];
        }else if(_bsVariable.isObject(xml_node)){
          node = xml_node;
        }else{
          alert('ERROR: [XItem::loadXML] - Invalid Parameter value (' + xml_node + ').');
        };
        
     /* Attributes xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */
     if(node.attributes){
       this.action=node.attributes.getNamedItem("action").nodeValue;
       this.requestId=node.attributes.getNamedItem("requestId").nodeValue;
     };
     
     var pnode = node.childNodes[0]
     
     if(pnode){
          if(pnode.nodeValue){
            this.content=pnode.nodeValue;
          }else{
             switch (pnode.nodeName){
               case 'item':
                 this.content = new XItem(pnode);
                 break;
               case 'items':
                 this.content = new XItemCollection(pnode);
                 break;
               default:
                 this.content = pnode;
             };
          };
      };
      
  };
};




/* XAjax ------------------------------------------------------------------ */

function XAjax(){
  this.ASPNETCBERef; /* CallBack */
  this.submit=function(action,data,clientFn){
        /* Send Server Request */
        var _self = this;
        var req = new bsAjaxReq(this.ASPNETCBERef,action,data,null,clientFn);
        __BSAjax.submit(req);
  };
};XAjax.inherits(bsObject);


var __bsAjaxReqIndex = 0;

function bsAjaxReq(fnCBRef,action,data,ctrl,fn){
  this.fnCBRef=fnCBRef;
  this.action=action;
  this.data=data==0?"0":data;
  this.ctrl=ctrl;
  this.fn=fn;
  this.status=0; /* 0 = Pending, 1 = Sent, 2 = Complete */
  this.onTimeout;
  this.begin=function(sec,fnTO){
    this.status=1;
    this.onTimeout=fnTO;
    var _self = this;
    setTimeout(function(){if(_self.status==1) _self.onTimeout(_self)},(sec * 1000));
  }
  __bsAjaxReqIndex++;
}


function _BSAjax(){
  this.fnCBRef;
  this.timeout=20;//Seconds
  this.pendingRequests=0;
  this.onTimeout=function(req){
      var msgBox = new bsMsgBox();
        msgBox.isModal=true;
        msgBox.width='400px';
        msgBox.height='200px';
         var req_desc = '</br></br><b>Request Details:</b><br><br>';
         req_desc += '<b>Action:</b> ' + req.action + '<br>';
         req_desc += '<font color="gray">';
         if(!req.data) req_desc += 'Null<br>';
         else{
           if(req.data.getXML) req_desc += _bsString.encodeHTML(req.data.getXML());
           else req_desc += _bsString.encodeHTML(req.data);
         }
         req_desc += '</font>';
         req_desc += '<br><br>';
         setTimeout(function(){msgBox.show("Your ajax request has timed out as the result of prolonged inactivity. Please exit the application and <a href='login.aspx'>login</a> again. If the problem persists, please contact your system administrator.<br><br>" + req_desc,"Session Expired",'ok',1,"Warning!");},1);
  }
  this._loading=false;
  this.requestChange=function(n){
    this.pendingRequests +=n;
      if(this._loading && this.pendingRequests == 0){
        this._loading=false;
        __ShowLoading(this._loading); //Loading
        if(typeof __PopWinPage !='undefined') __PopWinPage.setButtonBlockState(this._loading);
      }else if(!this._loading && this.pendingRequests != 0){
        this._loading=true;
        __ShowLoading(this._loading); //Loading
        if(typeof __PopWinPage !='undefined') __PopWinPage.setButtonBlockState(this._loading);
      }
    
  };
  this.onServerError=function(error,context){
     var _err_dec = '';
     var req = null;
     if(context) req=context;
       if(req){
         _err_dec += '<b>Request Details:</b><br><br>';
         _err_dec += '<b>Action:</b> ' + req.action + '<br>';
         _err_dec += '<font color="gray">';
         if(!req.data) _err_dec += 'Null<br>';
         else{
           if(req.data.getXML) _err_dec += _bsString.encodeHTML(req.data.getXML());
           else _err_dec += _bsString.encodeHTML(req.data);
         }
         _err_dec += '</font>';
         _err_dec += '<br><br>';
         req.status=2;
       }
       _err_dec += '<b>Server Error Details:</b><br><br>';
       _err_dec += '<font color="red">' + _bsString.encodeHTML(error) + '</font>';
       this.displayError("Critical Error",_err_dec);
       this.requestChange(-1);
  }
  this.displayError=function(title,errDesc){
      var msgBox = new bsMsgBox();
        msgBox.isModal=true;
        msgBox.width='400px';
        msgBox.height='200px';
        setTimeout(function(){msgBox.show(errDesc,title,'ok',2,title);},1);
  }
   this.displayMessage=function(title,text){
      var msgBox = new bsMsgBox();
        msgBox.isModal=true;
        msgBox.width='400px';
        msgBox.height='200px';
        setTimeout(function(){msgBox.show(text,title,'ok',1,title);},1);
  }
  this.onServerResponse=function(result, context){
    var _self = this;
    var req = context;
        req.status=2; //Track Timeout
      if (req.ctrl) req.ctrl._ajaxServerResponse(result,context);
      var res;
      if(result.indexOf('<response') != -1){
         var res = new XResponse();
             res.loadXML(result);
        switch(res.action){
          case "SYS_PAGE_REDIRECT":
            _bsWindow.navigateTo(res.content);
            return;
          case "SYS_EXEC_CODE":
            eval(res.content);
            break;
          case "SYS_CLIENT_ERR":
            setTimeout(function(){_self.displayError("Error",res.content);},1);
            break;
          case "SYS_CLIENT_MSG":
            setTimeout(function(){_self.displayMessage("Notice!",res.content);},1);
        };  
       if (req.fn) req.fn(result,res);
    }
    this.requestChange(-1);
  }

  this.packData=function(reqId, action, data){
     if(!data) data='';
     var xml = '<request id="' + reqId + '" action="' + _bsXML.encodeAttribute(action) + '">';
         if(_bsVariable.isObject(data)){
           if(data.getXML){
            xml += data.getXML();
           };
         }else{
            xml += _bsXML.encodeValue(data);
         };
         xml += '</request>';
         
         return xml;
  };
  this.submit=function(req){
     this.requestChange(1);
     if(!req.cbRef) req.cbRef=this.cbRef;
     var _req = req
     var _self = this;
     
     var fn = function(){
      var _data = _req.action?_self.packData(_req.key,_req.action,_req.data):_req.data;
     _req.begin(_self.timeout,_self.onTimeout); //Track Timeout
     
     _req.fnCBRef(_data,_req,function(result, context){setTimeout(function(){_self.onServerResponse(result, _req)},1)},function(error,context){_self.onServerError(error,_req)});
     };
     setTimeout(fn,1);
  }
};_BSAjax.inherits(bsObject);


var __btnSubmit;
var __btnSubmitText;
function __ShowLoading(dis){
 if(!__btnSubmit) return;
 var btn = _bsElement.getRef(__btnSubmit);
 
 if(dis==true){
   if(btn.value == 'Loading...') return;
   __btnSubmitText=btn.value;
   btn.value='Loading...';
 }else{
   if(btn.value != 'Loading...') return;
   btn.value=__btnSubmitText;
 }
   _bsElement.setDisabled(__btnSubmit,dis);
};


var __BSAjax = new _BSAjax();
