  // The McGraw-Hill Companies AJAX JS object
  // Copyright (c) 2006. All Rights Reserved
  

/**********************************************/
/*     Start of new Ajax Code Here            */
/*     Verion: 2.1.5                          */
/*     Changes                                */
/*        2.1.5 - Add .firstChild.data to the column and cell sections for Safari 2.0 support. Updated msxml object list */
/*        2.1.4 - Added MHCAJ2_1_Error function */
/*        2.1.3 - Changed the Response method to check whether the responseMethod member is a function or a string and run it accordingly*/
/*        2.1.2 - Added Children Length check to the ParseResponse function */
/**********************************************/

var msxmlhttp = new Array(
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.3.0',
'Msxml2.XMLHTTP',
'Microsoft.XMLHTTP');

function mhcAJAX2_1(){

  // Private Members 
  this.sessionID = '';        // Stores PHP Session ID
  this.responseData = null;   // Stores the nested data array returned by an AJAX call
  this.responseMethod = '';   // Stores the user defined function called when data is returned 
  this.callStatus = 'idle';   // idle, wait, complete - AJAX status
  this.errorCode = 0;         // 0 = no error, see documentation for complete list of error codes
  this.timeoutID = null;      // Timeout ID handler
  this.timeoutLmt = 150;      // Sets the timeout limit in seconds
  this.running = false;
  this.XMLObject;
}

// Method for requesting an AJAX call to the server
mhcAJAX2_1.prototype.Request = function(pData, pResponse, pMethod){

  // Local variables
  var tPOST = (pMethod == 'GET')?false:true;
  var tQueryStr = [];
  var tIndex = 0;
  var tURL = 'ajservice2.1.php?';
  var tInstance;        // Self reference variable
  
  
  // Check if another call is running
  if(this.running){return false;}
  this.running = true;
  
  // The Response callback method is required
  if(!pResponse || pResponse == ''){
    this.running = false;
    throw new Error('No Response Method Specified.');
    return false;
  }
  
  // Iterate through the data parameter array
  //alert(typeof pData);
  
  // Set the Response method
  this.responseMethod = pResponse;  
  
  // Create the query string
  for(var i in pData){
    tQueryStr[tIndex++] = 'p['+encodeURIComponent(i.toString())+']='+this.ParamsToString(pData[i]);
  }
  if(tQueryStr.length > 0){tQueryStr = tQueryStr.join('&');}
  
  // Set the Session ID if it exists
  if(this.sessionID != ''){ tURL += 'PHPSESSID='+this.sessionID+'&'; }
  
  // Create HTTPRequest Object
  for (i=0;i<msxmlhttp.length;i++) {
    try {this.XMLObject = new ActiveXObject(msxmlhttp[i]);} 
    catch (e) {this.XMLObject = null; }
  }
  if(!this.XMLObject && typeof XMLHttpRequest!= "undefined") {this.XMLObject = new XMLHttpRequest(); }
  if (!this.XMLObject) {
    this.running = false;
    alert('Your browser does not support this page.');
    return false;
  }   
  

  
  
  
  // If the object was created prepare the HTTP request
  if(this.XMLObject){
    this.errorCode = 0;  // Reset error code
    
    // Open the connection
    this.XMLObject.open(tPOST?'POST':'GET', tURL + (tPOST?'':'&'+tQueryStr), true);
    
    // Create reference to parent object
    tInstance = this;
    
    // Create the state handler
    this.XMLObject.onreadystatechange = function(){
    
      switch(tInstance.XMLObject.readyState)
      {
        case 4:
          switch(tInstance.XMLObject.status){
            case (200): 
              tInstance.ParseResponse();
              tInstance.Response();
             break;
            case (404): 
              tInstance.running = false; 
              tInstance.errorCode = 32;
              tInstance.Response();
            break;
            case (500):
              tInstance.errorCode = 33;
              tInstance.Response();
            break;
          }
          tInstance = null;
        break;
        default:
        break;      
      }    
    }
    
    // Send the request
    this.XMLObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    this.XMLObject.send(tPOST?tQueryStr:'');
    
    this.timeoutID = setTimeout(function(){try{tInstance.Status();}catch(e){}}, 500);    
    
  }else{
    this.errorCode = 31;
    this.Response();
  }
  
  // Clear up resources
  tPOST = null;
  tQueryStr = null;
  tIndex = null;
  tURL = null;
}

mhcAJAX2_1.prototype.Response = function(){
  if(this.timeoutID != null){ clearTimeout(this.timeoutID); this.timeoutID = null;}  
  this.running = false;  
  if(this.responseMethod){
    switch(typeof this.responseMethod)
    {
      case 'function':
        this.responseMethod();        
      break;
      default:
        if(this.responseMethod != ''){eval(this.responseMethod);}
      break;
    }

  }  
}

mhcAJAX2_1.prototype.ParseResponse = function(){
  var tXML = this.XMLObject.responseXML;
  var tTop;
  var tSprocs = [];
  var tName = '';
  var tColGrp;
  var tColumns;
  var tColArr = []
  var tColName;
  var tCells;
  var tRecords;
  var tError;
  this.responseData = [];
  if(tXML){
    tTop  = tXML.getElementsByTagName('ajax');
    if(tTop.length == 1){
      // Check for global error messages
      tError = tTop[0].getElementsByTagName('er');
      if(tError.length>0){this.responseData['error'] =  tError[0].getAttribute('v');}
      else{
        
        tError = null;
        
        tSprocs = tTop[0].getElementsByTagName('sp');
        var n = tSprocs.length;
        if(n>0){
          for(var i=0;i<n;i++){
            tName = tSprocs[i].getAttribute('n');
            this.responseData[tName] = new Object;
            this.responseData[tName].errorCode = 0;
            this.responseData[tName].rowCount = 0;
            this.responseData[tName].columnCount = 0;
            this.responseData[tName].data = []
            this.responseData[tName].destroy = function (){
              if(this.data){
                for(var ind=this.data.length-1;ind>=0;ind=ind-1){
                  delete(this.data[ind]);
                } 
              }
            }
            
            if(tSprocs[i].childNodes.length > 0){
              
              tError = tSprocs[i].getElementsByTagName('er');
              if(tError.length>0){this.responseData[tName].errorCode = tError[0].getAttribute('v');}
              
              tColGrp = tSprocs[i].getElementsByTagName('cols');
              if(tColGrp.length == 1){
                
                // Column Records must be defined
                tColumns = tColGrp[0].getElementsByTagName('col');
                if(tColumns.length > 0){
                  // Something retard
                  this.responseData[tName].columnCount = tColumns.length;
                  for(var j=0,m=tColumns.length;j<m;j++){
                    if(tColumns[j].text){tColArr[tColumns[j].getAttribute('seq')] = tColumns[j].text;}
                    else if(tColumns[j].textContent){tColArr[tColumns[j].getAttribute('seq')] = tColumns[j].textContent;}
                    else if(tColumns[j].firstChild){tColArr[tColumns[j].getAttribute('seq')] = tColumns[j].firstChild.data;}                     
                  }
                  
                  tRecords = tSprocs[i].getElementsByTagName('recs');
                  if(tRecords.length == 1){
                    tRows = tRecords[0].getElementsByTagName('row');
                    var m = tRows.length;
                    this.responseData[tName].rowCount = m;
                    if(m>0){
                      // Loop through each row 
                      for(var j=0;j<m;j++){
                        this.responseData[tName].data[j] = []
                        // Get the cell group
                        tCells = tRows[j].getElementsByTagName('cell');
                        var l = tCells.length;
                        if(l>0){
                          // Loop through each cell
                          for(var k=0;k<l;k++){
                            tColName = tColArr[tCells[k].getAttribute('seq')];
                            if(tCells[k].text){this.responseData[tName].data[j][tColName] = decodeURIComponent(tCells[k].text);}
                            else if(tCells[k].textContent){this.responseData[tName].data[j][tColName] = decodeURIComponent(tCells[k].textContent);}
                            else if(tCells[k].firstChild){this.responseData[tName].data[j][tColName] = decodeURIComponent(tCells[k].firstChild.data);}                            
                          }
                        }
                      }
                    }
                  }
                }
              }
            }                
          }
        }
      }
    }  
  }
  // Clear up resources
  delete(this.XMLObject);
  this.XMLObject = null;
  tXML = null;
  tTop = null;
  tSprocs = null;
  tName = null;
  tColGrp = null;
  tColumns = null;
  tColArr = null;
  tColName = null;
  tCells = null;
  tRecords = null;
  tError = null;
    
}

mhcAJAX2_1.prototype.getResponse = function (pName){
  var ret = false;
  if(this.responseData){
    if(this.responseData['error']){
      ret = new Object();
      ret.errorCode = this.responseData['error'];
    }else if(this.responseData[pName.toString()]){
      ret = this.responseData[pName.toString()];
      this.responseData[pName.toString()] = null;
    }
  }
  return ret;
}

mhcAJAX2_1.prototype.ParamsToString = function (pParams){
  var tString = [];
  var tIndex = 0;
  
  for( var i in pParams){
    tString[tIndex++] = encodeURIComponent(i) + '=' + encodeURIComponent(pParams[i]);
  }
  
  if(tString.length > 0){ tString = tString.join('&'); }
  else{ tString = ''; }
  
  return encodeURIComponent(tString);  
}

function MHCAJ2_1_Error(errorID){
  errorID = parseInt(errorID);
  if(errorID > 0){
    var err_msg = '';
    switch(errorID){
      case 1: err_msg = 'Service requires the users to be logged in.'; break;
      case 2: err_msg = 'No procedures where specified in the AJAX call.'; break;
      case 3: err_msg = 'Procedure is not registered in the service list.'; break;
      case 4: err_msg = 'One or more get param key names exceeds the maximum size.'; break;
      case 5: err_msg = 'One or more get param values exceeds the maximum size.'; break;      
      case 6: err_msg = 'GET string length exceeds maximum size.'; break;
      case 21: err_msg = 'Required Parameter is missing.'; break;
      case 22: err_msg = 'Invalid String.'; break;
      case 23: err_msg = 'Invalid Boolean value.'; break;
      case 24: err_msg = 'Invalid Interger value.'; break;
      case 25: err_msg = 'Invalid Unsigned Interger value.'; break;
      case 26: err_msg = 'Invalid Float value.'; break;
      case 27: err_msg = 'Invalid Unsigned Float value.'; break;
      case 28: err_msg = 'Invalid Numeric value.'; break;
      case 28: err_msg = 'Value failed RegX check.'; break;
      case 28: err_msg = 'Value exceeded specified string length.'; break;
      case 37: err_msg = 'XML Include file not found.'; break;
      case 41: err_msg = 'PHP Invalid Syntax.'; break;
      case 42: err_msg = 'Parameter fields not specified in service list file.'; break;
      
      // Operational error messages 8 though 20 error code block
      case 8: err_msg = 'A required AJAX component has not been initialized.'; break;
      case 9: err_msg = 'Another process is running. \n\nPlease wait for the other process to finish\nbefore submitting your request again.'; break;

      // Default
      default: err_msg = 'An unexpected error has occured.\n\nTry your request again.\n\nContact support if problems exist.';break;                  
    }
    if(err_msg != ''){alert('Error Code: '+errorID+'\n\n'+err_msg);}
    err_msg = null;
  }
}