//#################################################################
// Server Request definitions
//#################################################################

var SERVERREQUEST_RESULT_NORESPONSE = 'NoResponse';
var SERVERREQUEST_RESULT_SUCCESS = 'Success';
var SERVERREQUEST_RESULT_FAILURE = 'Failure';
var SERVERREQUEST_RESULT_NOTFOUND = 'NotFound';
var SERVERREQUEST_RESULT_NOMATCHES = 'NoMatches';
var SERVERREQUEST_RESULT_BADCRITERIA = 'BadCriteria';

var gladstoneServerBaseRequestUrl = '/helpmecook/xmlrequest';
var gladstoneServerNameSpacePrefix = 'hmc';
var gladstoneServerRequestDocSchemaSpec =  '<hmc:hmcUIRequest  xmlns:hmc=\"http://helpmecook.com/hmcUI\">';
var gladstoneServerRequestElementName = 'hmc:hmcUIRequest';
var gladstoneServerResponseNameSpacePrefix = 'hmc';

var gladstoneServerRequestList = new Array();
var gladstoneServerResponseList = new Array();

function gladstoneServerRequest(argRequestID,argCategory,argAction,argRequestData) {
  this.requestID = argRequestID;
  this.category = argCategory;
  this.action = argAction;
  this.requestData = argRequestData;
  this.responseFunctionStack = new Array();
  this.requestObject = null;
  this.resultCode = null;
  this.responseData = null;
  this.errorMessage = null;
  this.waitingMessage = null;
  this.requestTime = 0;  // time request was sent
  this.messageTime = 0;  // time waiting message displayed
}

function gladstoneServerSetBaseUrl(argUrl) {
  gladstoneServerBaseRequestUrl = argUrl;
}

function gladstoneServerSetNameSpacePrefix(argPrefix) {
  gladstoneServerNameSpacePrefix = argPrefix;
}

function gladstoneServerSetRequestDocSchemaSpec(argSpec) {
  gladstoneServerRequestDocSchemaSpec = argSpec;
}

function gladstoneServerSetRequestElementName(argName) {
  gladstoneServerRequestElementName = argName;
}

function gladstoneServerSetResponseNameSpacePrefix(argPrefix) {
  gladstoneServerResponseNameSpacePrefix = argPrefix;
}


//*****************************************************************************
// hmcSendServerRequest
//*****************************************************************************
function gladstoneServerSendRequest(argRequestID,argCategory,argAction,argRequestData,argWaitMessage,argResponseFunction,argCallerParm) {
  var request = new gladstoneServerRequest(argRequestID,argCategory,argAction,argRequestData);
  request.responseFunctionStack.push(argResponseFunction);
  request.waitingMessage = argWaitMessage;
  if ( argCallerParm ) {
    request.callerParm = argCallerParm;
  }
    
  request.requestObject = null;
  
  if (window.ActiveXObject) {
    request.requestObject = new ActiveXObject("Microsoft.XMLHTTP");
  } else {
  // code for Mozilla, etc.
    request.requestObject = new XMLHttpRequest();
    // code for IE
  }

  if (request.requestObject != null) {
    var dt = new Date();
    request.requestTime = dt.getTime();
    request.messageTime = 0;
    gladstoneServerRequestList.push(request);
    request.requestObject.onreadystatechange = gladstoneServerResponseHandler;
    var requestUrl = gladstoneServerBaseRequestUrl;
    request.requestObject.open("POST",requestUrl,true);
    request.requestObject.send( gladstoneServerBuildRequest(request) );
  } else {
    alert("Your browser does not support XMLHTTP.");
  }
}


//*****************************************************************************
// gladstoneServerResponseHandler
//*****************************************************************************
function gladstoneServerResponseHandler() {
  // check each of the active requests
  var changeFlag = true;
  while( changeFlag ) {
    changeFlag = false;
    var x;
    var request;
    for( x=0; x < gladstoneServerRequestList.length; x++ ) {
      request = gladstoneServerRequestList[x];
      if (request.requestObject.readyState==4) {
        changeFlag = true;
        gladstoneServerRequestList.splice(x,1);  // remove from the list
        if ( gladstoneServerProcessResponse(request) == false )
          gladstoneServerResponseList.push(request);
        break;
      }
    }
  }
}


function gladstoneServerRequestTimer() {
  var x;
  var request;
  var dt = new Date();
  var ms = dt.getTime();

  // check all requests waiting for a response to see if need to display a waiting message
  for( x=0; x < gladstoneServerRequestList.length; x++ ) {
    request = gladstoneServerRequestList[x];
    if ( request.messageTime == 0 ) {
      var duration = (ms - request.requestTime) / 1000; // calc number of seconds since sent
//      alert('duration=' + duration);
      if ( (duration > 0) && (request.waitingMessage != null) ) {
        gladstoneServerShowWaitMessage(request.waitingMessage);
        request.messageTime = ms;
      }
    }
  }

  // check the response list to see if the waiting message has been displayed for at least
  // the minimum amount of time and if so then remove and process it
  var requestList = new Array();
  for( x=0; x < gladstoneServerResponseList.length; x++ ) {
    request = gladstoneServerResponseList[x];
    if ( gladstoneServerProcessResponse(request) )
      continue;
    requestList.push(request);  // message not displayed long enough so leave on queue
  }
  gladstoneServerResponseList = requestList;
  setTimeout( 'gladstoneServerRequestTimer()', 1000 );
  
}


function gladstoneServerProcessResponse(argRequest) {
  if ( argRequest.messageTime != 0 ) {
    var dt = new Date();
    var ms = dt.getTime();
    var duration = (ms - argRequest.messageTime) / 1000; // calc number of seconds since wait message displayed
    if ( duration < 1 )
      return false;  // not ready to be processed yet
    gladstoneServerHideWaitMessage();
  }

  if (argRequest.requestObject.status==200) {
    var xmltext = argRequest.requestObject.responseText;
//    alert(xmltext);
    var doc = gladstoneXMLParseDoc(xmltext);
    argRequest.resultCode = gladstoneXMLGetChildElementValue(doc.documentElement, gladstoneServerResponseNameSpacePrefix + ':resultCode');
    argRequest.responseData = null;
    argRequest.errorMessage = gladstoneXMLGetChildElementValue(doc.documentElement,gladstoneServerResponseNameSpacePrefix + ':errorMessage');
    var r;
    var respData =  gladstoneXMLGetChildElementByName(doc.documentElement,gladstoneServerResponseNameSpacePrefix + ':responseData' ) ;
    if ( respData ) {
      argRequest.responseData = gladstoneXMLGetFirstChildElement(respData);
    }
//    for( r=0; r < doc.documentElement.childNodes.length; r++ ) {
//      var node = doc.documentElement.childNodes[r];
//      if ( node.nodeName == gladstoneServerResponseNameSpacePrefix + ':responseData' ) {
//        if ( node.childNodes.length > 0 )
//          argRequest.responseData = node.childNodes[0];
//          break;
//      }
//    }      
  } else {
    argRequest.resultCode = REQUEST_RESULT_FAILURE;
    argRequest.errorMessage = 'Server request failed - received status ' + argRequest.requestObject.status;
  }
  var funcObj = argRequest.responseFunctionStack[0];
  argRequest.responseFunctionStack.splice(0,1);
  funcObj.call(funcObj,argRequest,argRequest.callerParm);
  return true;
}

function gladstoneServerBuildRequest(argRequest) {
  var buffer = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>';
  buffer += gladstoneServerRequestDocSchemaSpec;
  buffer += '<' + gladstoneServerNameSpacePrefix + ':category>' + argRequest.category + '</' + gladstoneServerNameSpacePrefix + ':category>';
  buffer += '<' + gladstoneServerNameSpacePrefix + ':action>' + argRequest.action + '</' + gladstoneServerNameSpacePrefix + ':action>';
  buffer += '<' + gladstoneServerNameSpacePrefix + ':requestData>' + argRequest.requestData + '</' + gladstoneServerNameSpacePrefix + ':requestData>';
  buffer += '</' + gladstoneServerRequestElementName + '>\n';
  return buffer;
}

function gladstoneServerShowWaitMessage(argMessage) {
  var buffer = '<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">' +
               '<tr><td colspan=2>' + espyUIBuildSpacer(20,20) + '</td></tr>' +
               '<tr><td>' + espyUIBuildSpacer(5,100) + '</td>' + '<td align=\"center\"><img src=\"' + espyUIGetImagePath('waitingbar.gif') + '\" border=\"0\"></td></tr>' +
               '<tr><td colspan=2>' + espyUIBuildSpacer(10,20) + '</td></tr>' +
               '<tr><td>' + espyUIBuildSpacer(5,100) + '</td>' + '<td align=\"center\" CLASS=\"ReportWaitMessage\">' + argMessage + '</td></tr></table>';
  var msgpanel = espyUIGetTabMessagePanel(argTabIndex);
  var conpanel = espyUIGetTabContentPanel(argTabIndex);
  if ( msgpanel && conpanel ) {
    msgpanel.innerHTML = buffer;
    msgpanel.style.display='block';
    conpanel.style.display='none';
  }
}

function gladstoneServerHideWaitMessage(argTabIndex) {
  var msgpanel = espyUIGetTabMessagePanel(argTabIndex);
  msgpanel.style.display='none';
  var conpanel = espyUIGetTabContentPanel(argTabIndex);
  conpanel.style.display='block';
}



//#############################################################################
//#############################################################################
// XML handling definitions
//#############################################################################
//#############################################################################

function gladstoneXMLRequestData() {
  this.elements = new Array();
  //methods
  this.openElement = function(argName) {
    this.elements.push('<' + argName + '>');
  }
  
  this.closeElement = function(argName) {
    this.elements.push('</' + argName + '>');
  }
  
  this.addTextElement = function(argName,argText) {
    this.elements.push('<' + argName + '>' + argText + '</' + argName + '>');
  }
  
  this.toString = function() {
    return this.elements.join('');
  }
}


//*****************************************************************************
// gladstoneXMLParseDoc
// Gets the XML doc object for the given text
//*****************************************************************************
function gladstoneXMLParseDoc(argXmlText) {
  var xmlDoc = null;
  if (window.ActiveXObject) {
    //load xml file code for IE
    xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc.async=false;
    xmlDoc.loadXML(argXmlText);
    if ( !xmlDoc.documentElement )
       alert('does NOT have doc element - ' + xmlDoc.childNodes.length);

  } else {  
    var parser=new DOMParser();
    xmlDoc=parser.parseFromString(argXmlText,"text/xml");
    if ( !xmlDoc.documentElement )
       alert('Does NOT have doc element - ' + xmlDoc.childNodes.length);
  }
  return xmlDoc;
}

//*****************************************************************************
// espyUIXMLGetDocElement
// Creates an XML doc object for the given file and returns the document
// element from it
//*****************************************************************************
function espyUIXMLGetDocElement(argXmlText) {
  var xmlDoc = null;
  if (window.ActiveXObject) {
    //load xml file code for IE
    xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc.async=false;
    xmlDoc.loadXML(argXmlText);
    
  } else {  
    var parser=new DOMParser();
    xmlDoc=parser.parseFromString(argXmlText,"text/xml");
  }
  if ( xmlDoc ) {
    if ( xmlDoc.documentElement )
      return xmlDoc.documentElement;
    alert('does NOT have doc element - ' + xmlDoc.childNodes.length);
  }
  return null;
}

//*****************************************************************************
// espyUIXMLGetDocFromFile
// Gets the XML doc object for the given file
//*****************************************************************************
function espyUIXMLGetDocFromFile(argFileName) {

  var xmlDoc = null;
  if (window.ActiveXObject) {
    //load xml file code for IE
    xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc.async=false;
    xmlDoc.load(argFileName);
  } else {
    alert('Your browser cannot handle this script');
  }
  return xmlDoc;
}


//*****************************************************************************
// gladstoneXMLGetNodeAttribute
// Gets the value of the specified attribute for the given xml node
//*****************************************************************************
function gladstoneXMLGetNodeAttribute(argNode,argAttributeName) {
  var atts = argNode.attributes;
  var a;
  for( a=0; a < atts.length; a++ ) {
    if ( atts[a].name == argAttributeName ) {
      return atts[a].value;
    }
  }
  return null;
}

//*****************************************************************************
// espyUIXMLGetBooleanNodeAttribute
// Gets the boolean value of the specified attribute for the given xml node
//*****************************************************************************
function gladstoneXMLGetBooleanNodeAttribute(argNode,argAttributeName) {
  var atts = argNode.attributes;
  var a;
  for( a=0; a < atts.length; a++ ) {
    if ( atts[a].name == argAttributeName ) {
      if ( (atts[a].value == 'Yes') || (atts[a].value == 'true') )
        return true;
      return false;
    }
  }
  return null;
}


//*****************************************************************************
// gladstoneXMLGetChildElementValue
// Gets the value of the child element with the given name
//*****************************************************************************
function gladstoneXMLGetChildElementValue(argNode,argElementName) {
  var n;
  for( n=0; n < argNode.childNodes.length; n++ ) {
    var node = argNode.childNodes[n];
    if ( node.nodeType == 1 ) {
      if ( node.nodeName == argElementName ) {
        return gladstoneXMLGetNodeTextValue(node);
      }
    }
  }
  return null;
}

function gladstoneXMLGetNodeTextValue(argNode) {
  var n;
  for( n=0; n < argNode.childNodes.length; n++ ) {
    var node = argNode.childNodes[n];
    if ( node.nodeType == 3 ) {
        return node.nodeValue;
    }
  }
  return null;
}

//*****************************************************************************
// espyUIXMLGetChildElementBooleanValue
// Gets the boolean value of the child element with the given name
//*****************************************************************************
function gladstoneXMLGetChildElementBooleanValue(argNode,argElementName) {
  var n;
  for( n=0; n < argNode.childNodes.length; n++ ) {
    var node = argNode.childNodes[n];
    if ( node.nodeType == 1 ) {
      if ( node.nodeName == argElementName ) {
        if ( (node.text) && (node.text == 'true') )
          return true;
      }
    }
  }
  return false;
}


//*****************************************************************************
// espyUIXMLGetChildElementsByName
// Get a list of the child elements with the given name
//*****************************************************************************
function gladstoneXMLGetChildElementsByName(argNode,argElementName) {
  var n;
  var returnList = new Array();
  for( n=0; n < argNode.childNodes.length; n++ ) {
    var node = argNode.childNodes[n];
    if ( node.nodeType == 1 ) {
      if ( node.nodeName == argElementName ) {
        returnList.push(node);
      }
    }
  }
  return returnList;
}


//*****************************************************************************
// espyUIXMLGetChildElementByName
// Get the child element with the given name
//*****************************************************************************
function gladstoneXMLGetChildElementByName(argNode,argElementName) {
  var n;
  for( n=0; n < argNode.childNodes.length; n++ ) {
    var node = argNode.childNodes[n];
    if ( node.nodeType == 1 ) {
      if ( node.nodeName == argElementName ) {
        return node;
      }
    }
  }
  return null;
}

//*****************************************************************************
// gladstoneXMLGetFirstChildElement
// Gets the first child element of the given node
//*****************************************************************************
function gladstoneXMLGetFirstChildElement(argNode) {
  var n;
  for( n=0; n < argNode.childNodes.length; n++ ) {
    var node = argNode.childNodes[n];
    if ( node.nodeType == 1 ) {
        return node;
    }
  }
  return null;
}


function gladstoneXMLAddChildElement(argName,argValue) {
  return '<' + gladstoneServerNameSpacePrefix + ':' + argName + '>' + encodeURIComponent(argValue) + '</' + gladstoneServerNameSpacePrefix + ':' + argName + '>';
}


