/*
epsc - entra porco sai chourico
translation: pig in, sausage out
server nfo
Version 1.3.11 - 2007/02/02
  created epscParse: XML parsing and evaluation occurs here instead of in epscProcess
  created epscCheckDOM: checks DOM tree for the IDs in epscWatchIds, parses, executes and cleans up the "content" property
  epscGet && epscPost checks for initialization

Version 1.3.10 - 2007/01/30
  Loading... (reporting)
  needs epsc_statusVisible   = true; to show the label
  needs epsc_statusRefresh   = true; to show the refresh countdown
  epsc_statusStyle describes the style for the label
  function epscUpdateIdWithURL(req, argsString) {
      (.....)
      var objProp    = (args[1])?args[1]:'innerHTML';
  function updateElement ....
      removeElement(container, name); //make sure the object was deleted

Version 1.3.8 - 2007/01/19
  corrected javascript eval code: jsstr = jsstr + decodeURIComponent(evallst[i].getElementsByTagName('js')[0].childNodes[i].data);
  (problem reading more than 4096 bytes of the element's value)

*/
var server_qsSeparator   = "?";

var b_ie4 = (document.all) ? true : false;
var b_ns4 = (document.layers) ? true : false;
var b_ns6 = (document.getElementById && !document.all) ? true : false;

//framework specific
var epsc_initialized     = false;
var epsc_connId          = 0;
var epsc_remotereqs      = true;
var epsc_defaultCallback = epscProcess;
var epsc_separator       = "|;";
var epsc_startupUrl      = "";
var epsc_requestTimeout  = 15000;//timeout of requests in milliseconds
var epsc_handleCookies   = true;
var epsc_objectBroker    = "/cgi-bin/epsc_broker.cgi";
var xmlHttpReqs          = new Array();
var reqQueue             = new Array();
var updtQueue            = new Array(); //queue for objects to be updated
var updtQueueMaxTries    = 10;
var evalQueue            = new Array(); //queue for javascript evaluations
var evalQueueMaxTries    = 10;
var refreshQueue         = new Array(); //queue for refreshable sections
var epsc_sessionName     = 'sessionID';
var epsc_statusVisible   = true;
var epsc_statusRefresh   = true;
var epsc_statusStyle     = 'background-color:#ff0000; color:white; border:1px solid #00cc00; padding:0.2em; position:absolute; top: 0.3em; right: 0.3em;';
var epscWatchIds         = new Array("epscXML");
var epscCacheSize        = 2000000;
var epscCache            = new Array();

function updt_item(objId, objProp, objContent, displayOrder, displayMode) {
  this.objId        = objId;
  this.objProp      = objProp;
  this.objContent   = objContent;
  this.displayOrder = displayOrder;
  this.displayMode  = displayMode;
  this.updated      = false;
  this.sortable     = false;
  this.tries        = 0;
}

function eval_item(str) {
  this.evalStr    = str;
  this.tries      = 0;
}

function slot() {
  epsc_connId++;
  this.state     = 0;
  this.id        = epsc_connId;
  this.timestart = 0;
  this.timeend   = 0;
  this.url       = 0;
  this.ro        = epscCreate();
  this.elapsed   = time_elapsed;
}

function getSlot(reqId) {
  for (i = 0; i < xmlHttpReqs.length; i++) {
    if (xmlHttpReqs[i].id == reqId) return xmlHttpReqs[i];
  }
  return false;
}

function queue_item(fn, url, callback, args, enqueueing_type, enqueueing_val) {
  this.fn              = fn;
  this.url             = url;
  this.callback        = callback;
  this.args            = args;
  this.enqueueing_type = enqueueing_type;
  this.enqueueing_val  = enqueueing_val;
  /*
  if ((typeof(allow_enqueueing) != 'undefined')||(allow_enqueueing != null)) {
    this.allow_enqueueing = allow_enqueueing;
  } else {
    this.allow_enqueueing = -1;
  }
  */
}

function refreshable_item(period, url, target, property) {
  this.period    = period; //Notice: period is in seconds!!
  this.last_updt = (new Date()).getTime();
  this.url       = url;
  this.target    = target;
  this.property  = property;
}

function refreshableEnqueue(period, url, target, property) {
  //check if exists
  var exists = -1;
  for (i = 0; i < refreshQueue.length; i++) {
    if ((period == refreshQueue[i].period)&&(refreshQueue[i].url == url)&&(refreshQueue[i].target == target)&&(refreshQueue[i].property == property)) {
      exists = i;
    }
  }
  //ads refresheable update to the refreshQueue queue.
  if (exists < 0) {
    var item = new refreshable_item(period, url, target, property);
    refreshQueue.push(item);
  }
}

function refreshableProcess() {
  for (i = 0; i < refreshQueue.length; i++) {
    if ((eval("refreshQueue[i].url"))&&(refreshQueue[i].period)) {
      var periodms  = refreshQueue[i].period*1000;
      var time_diff = refreshQueue[i].last_updt + periodms - (new Date()).getTime();
      if (time_diff < 0) {
        refreshQueue[i].last_updt = (new Date()).getTime();
        epscGet(refreshQueue[i].url, epscUpdateIdWithURL, refreshQueue[i].target + epsc_separator + refreshQueue[i].property);
      } else {
        if ((epsc_statusVisible)&&(epsc_statusRefresh)&&(time_diff > 1)) {
          var seconds = Math.round(time_diff/1000);
          updateElement(null, 'epscRefresh', 'Refresh in ' + seconds + "s", epsc_statusStyle);
        }
      }
    }
  }
}

function refreshableClear() {
  if ((epsc_statusVisible)&&(epsc_statusRefresh)) removeElement(null, 'epscRefresh');
  refreshQueue = new Array();
}

function time_elapsed() {
  return  this.timeend - this.timestart;
}

function epscCreate() {
  xmlHttpObj = false;
  try {
    xmlHttpObj = new XMLHttpRequest();
  } catch (trymicrosoft) {
    try {
      xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP");
  }   catch (othermicrosoft) {
      try {
        xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (failed) {
        xmlHttpObj = false;
        alert("Unable to create XMLHttpRequest object");
      }
    }
  }
  return xmlHttpObj;
}

function epscInitialize() {
  if (epsc_initialized == true) return epsc_initialized;

  try {
    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
  } catch (e) {
    epsc_remotereqs = false;
  }

  try {
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  } catch (e) {
    //alert("File upload not permitted." + e);
  }

  epsc_initialized = true;
  queueMonitor();
  epscLifecycleCheck();
  return true;
}

function epscReqEnqueue(fn, url, callback, args, enqueueing_type, enqueueing_val) {
  var item = new queue_item(fn, url, callback, args, enqueueing_type, enqueueing_val);
  reqQueue.push(item);
}

function epscReqDequeue() {
  if (reqQueue.length < 1) return false;
  var item = reqQueue.shift();
  var fn   = item.fn;
  var pfunc= null;
  if (typeof(fn) == "string") pfunc = eval(fn);
  if (fn != null)             pfunc = fn;
  if (pfunc == null)          pfunc = epscGet;
  pfunc(item.url, item.callback, item.args, item.enqueueing_type, item.enqueueing_val);
}

function epscUpdtEnqueue(objId, objProp, objContent, displayOrder, displayMode) {
  var exists = -1;
  if (displayMode == null) {
    displayMode = "change";
  }
  for (i = 0; i < updtQueue.length; i++) {
    if ((objId == updtQueue[i].objId)&&(displayOrder == updtQueue[i].displayOrder)) {
      exists = i;
    }
  }
  if (exists < 0) {
    var item = new updt_item(objId, objProp, objContent, displayOrder, displayMode);
    updtQueue.push(item);
  } else {
    var item = updtQueue[exists];
    if (item.tries >= updtQueueMaxTries) {
      updtQueue.splice(exists,1);
    }
  }
}

function sortUpdtObj(a, b) {
  return a.displayOrder - b.displayOrder;
}

function epscUpdtObj() {
  if (updtQueue.length < 1) return false;
  var items = updtQueue.sort(sortUpdtObj);
  var sorted = false;
  //select item
  for (i = 0; i < items.length; i++) {
    if (sorted == false) {
      if (items[i].displayOrder > 0) {
        items[i].sortable     = true;
        items[i].displayOrder = 0;
        sorted = true;
      }
    }
    if ((items[i].sortable)&&(items[i].displayOrder == 0)) {
      sorted = true;
    }
  }

  //display
  for (i = 0; i < items.length; i++) {
    if (items[i].updated == false) {
      if (items[i].displayOrder == 0) {
        items[i].tries  += 1;
        if (epscSetObjProp(items[i].objId, items[i].objProp, items[i].objContent, items[i].displayOrder, items[i].displayMode)) {
          items[i].updated = true;
        }
      } //end of if item.displayOrder == 0
    } //end of if updated == false
  }

  //cleanup
  updtQueue = new Array();
  for (i = 0; i < items.length; i++) {
    if ((items[i].updated == false)&&(items[i].tries < updtQueueMaxTries)) updtQueue.push(items[i]);
  }
}
/*
function epscUpdtObj() {
  if (updtQueue.length < 1) return false;
  for (i = 0; i < updtQueue.length; i++) {
    var item = updtQueue[i];
  //  var item = updtQueue.sort(sortUpdtObj)
    if (item.tries < updtQueueMaxTries) {
      if (epscSetObjProp(item.objId, item.objProp, item.objContent, item.displayOrder, item.displayMode)) {
        updtQueue.splice(i,1);
        return epscUpdtObj();
      }
    } else {
      updtQueue.splice(i,1);
      return epscUpdtObj();
    }
    item.tries += 1;
  }
  return true;
}
*/
function epscEvalEnqueue(evalStr) {
  var exists = -1;
  for (i = 0; i < evalQueue.length; i++) {
    if (evalStr == evalQueue[i].evalStr) {
      exists = i;
    }
  }
  if (exists < 0) {
    var item = new eval_item(evalStr);
    evalQueue.push(item);
  } else {
    var item = evalQueue[exists];
    if (item.tries >= evalQueueMaxTries) {
      evalQueue.splice(exists,1);
    }
  }
}

function epscEvalObj() {
  if (evalQueue.length < 1) return false;
  for (i = 0; i < evalQueue.length; i++) {
    var item = evalQueue[i];
    if (item.tries < evalQueueMaxTries) {
      if (epscEvalJS(item.evalStr)) {
        evalQueue.splice(i,1);
        return epscEvalObj();
      }
    } else {
      evalQueue.splice(i,1);
      return epscEvalObj();
    }
    item.tries += 1;
  }
  return true;
}

function epscReserve() {
  var _slot = new slot();
  if (epsc_statusVisible) {
    removeElement(null, 'epscRefresh');
    updateElement(null, 'epscStatus', 'Loading ....', epsc_statusStyle);
  }
  xmlHttpReqs.push(_slot);
  return _slot;
}

function epscRelease(req) {
  for (var i = 0; i < xmlHttpReqs.length; i++) {
    if (req.id == xmlHttpReqs[i].id) {
      if ((epsc_statusVisible)&&(xmlHttpReqs.length <= 1)) {
        removeElement(null, 'epscRefresh');
        removeElement(null, 'epscStatus');
      }
      xmlHttpReqs.splice(i,1);
      return true;
    }
  }
  return false;
}

function scriptName(url) {
  var string = unescape(escape(url));
  var parts  = string.split(server_qsSeparator);
  if (parts[0]) return parts[0];
  return url;
}

function processHeaders(headers) {
  var lines      = headers.split(/\r?\n/);
  var in_cookies = false;
  for (i = 0; i < lines.length; i++) {
    if (lines[i].match(/set-cookie:\ +?/i)) {
      in_cookies = true
      var pair = lines[i].split(/^set-cookie:\ +/i);
      document.cookie = pair[1];
    } else {
      if (lines[i].match(/[a-z\-_]+:/i)) {
        in_cookies = false;
      }
      if (in_cookies) {
        document.cookie = lines[i];
      }
    }
  }
}

function validRequest(url, enqueueing_type, enqueueing_val) {
  /*
    0 - only one request (script name)
    1 - only one request with same arguments (url)
    2 - allow enqueueing_val requests (script name)
    3 - allow enqueueing_val requests (url)
    4 - allow any number of requests
    5 - load only if enqueueing_val script is not in process
    6 - load only if enqueueing_val url is not in process
    666 - invalid request!
  */

  if (url.length == 0) return 666;

  var scriptname   = scriptName(url);
  var scriptcount  = 0;
  var urlcount     = 0;
  var scriptcountq = 0;
  var urlcountq    = 0;
  var reqOk        = 0;
  for (i = 0; i < xmlHttpReqs.length; i++) {
    if ((url == xmlHttpReqs[i].url)&&(xmlHttpReqs[i].state != 0)) urlcount++;
    if ((scriptname == scriptName(xmlHttpReqs[i].url))&&(xmlHttpReqs[i].state != 0)) scriptcount++;
  }

  for (i = 0; i < reqQueue.length; i++) {
    if (url == reqQueue[i].url) urlcountq++;
    if (scriptname == scriptName(reqQueue[i].url)) scriptcountq++;
  }

  switch (enqueueing_type) {
    case 0:
      scriptcount += scriptcountq;
      if (scriptcount == 0) reqOk = 1;
      break;
    case 1:
      urlcount += urlcountq;
      if (urlcount == 0) reqOk = 1;
      break;
    case 2:
      scriptcount += scriptcountq;
      if (scriptcount <= enqueueing_val) reqOk = 1;
      break;
    case 3:
      urlcount += urlcountq;
      if (urlcount <= enqueueing_val) reqOk = 1;
      break;
    case 4:
      reqOk = 1;
      break;
    case 5:
      reqOk = 2;
      break;
    case 6:
      if ((urlcount > 0)||(scriptcount > 0)) {
        reqOk = 2;
      } else {
        reqOk = 1;
      }
      break;
    default:
      reqOk = 1;
  }

  return reqOk;
}

function epsc(method, url, callback, args, enqueueing_type, enqueueing_val) {}

function epscGet(url, callback, args, enqueueing_type, enqueueing_val) {
  if (epsc_initialized) {
    var req   = epscReserve();
    var reqOk = true;
    var pfunc = null;
    var count = 0;
    if (typeof(callback) == "string") pfunc = eval(callback);
    if (callback != null) pfunc = callback;
    if (pfunc == null) pfunc = epsc_defaultCallback;
    reqOk = validRequest(url, enqueueing_type, enqueueing_val);
    switch (reqOk) {
      case 1:
        if (req.state == 0) {
          try {
            req.timestart = (new Date()).getTime();
            req.ro.open("GET", url, true);
            req.ro.onreadystatechange = function () { pfunc(req, args) };
            req.ro.send(null);
            req.state     = 1;
            req.timeend   = req.timestart;
            req.url       = url;
          } catch (exception) {
            epscReqEnqueue(epscGet, url, callback, args, enqueueing_type, enqueueing_val);
            epscRelease(req);
          }
        } else {
          epscReqEnqueue(epscGet, url, callback, args, enqueueing_type, enqueueing_val);
          epscRelease(req);
        }
        break;
      case 2: //dependency in progress; enqueue!
        epscReqEnqueue(epscGet, url, callback, args, enqueueing_type, enqueueing_val);
        epscRelease(req);
        break;
      default:
    }
  } else {
    epscInitialize();
    epscReqEnqueue(epscGet, url, callback, args, enqueueing_type, enqueueing_val);
    epscRelease(req);
  }
}

function epscPost(url, callback, args, enqueueing_type, enqueueing_val) {
  if (epsc_initialized) {
    var req   = epscReserve();
    var reqOk = true;
    var pfunc = null;
    var count = 0;
    if (typeof(callback) == "string") pfunc = eval(callback);
    if (callback != null) pfunc = callback;
    if (pfunc == null) pfunc = epsc_defaultCallback;
    reqOk = validRequest(url, enqueueing_type, enqueueing_val);
    switch (reqOk) {
      case 1:
        if (req.state == 0) {
          try {
            req.timestart = (new Date()).getTime();
            req.ro.open("POST", url, true);
            req.ro.onreadystatechange = function () { pfunc(req, args) };
            req.ro.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            req.ro.send(args);
            req.state     = 1;
            req.timeend   = req.timestart;
            req.url       = url;
          } catch (exception) {
            epscReqEnqueue(epscPost, url, callback, args, enqueueing_type, enqueueing_val);
            epscRelease(req);
          }
        } else {
          epscReqEnqueue(epscPost, url, callback, args, enqueueing_type, enqueueing_val);
          epscRelease(req);
        }
        break;
      case 2: //dependency in progress; enqueue!
        epscReqEnqueue(epscPost, url, callback, args, enqueueing_type, enqueueing_val);
        epscRelease(req);
        break;
      default:
    }
  } else {
    epscInitialize();
    epscReqEnqueue(epscPost, url, callback, args, enqueueing_type, enqueueing_val);
    epscRelease(req);
  }
}

//to use with object request brokers
function epscCall(request) {
  if (epsc_initialized != true) epscInitialize();
  //parse request
  request     += ";";
  var lines    = request.split(/;/);
  var callList = new Array();
  var argsList = new Array();
  for (j = 0; j < lines.length; j++) {
    var regexp  = /(([a-z0-9_]+)(:{1}:{1}[a-z0-9_]+)*)->([a-z0-9_]+)\(([a-z0-9_,:\-\. =\%\(\)\n\t]*)\)/i;
    if (regexp.test(lines[j])) {
      var ptree  = regexp.exec(lines[j]);
      var obj    = ptree[1];
      var method = ptree[ptree.length - 2];
      var args   = ptree[ptree.length - 1];
      var tmplst = args.split(",");
      var tmpargs= new Array();
      for (i = 0; i < tmplst.length; i++) {
        var aux = tmplst[i].split("=");
        tmpargs.push(trim(aux[0]));
      }
      callList.push(obj + "->" + method + "(" + tmpargs.join(',') + ")");
      argsList.push(args);
      //var string = "epscMethod=" + escape(method) + "&epscObject=" + escape(obj) + "&";
    }
  }
  var argsStr  = argsList.join(',');
  var callsStr = 'epscCalls' + '=' + callList.join(";");
  epscPost(epsc_objectBroker, null, callsStr + "&" + epscWrapVars(argsStr.replace(/(\ +)?,(\ +)?/g, "|")));
}

function epscUpdateIdWithURL(req, argsString) {
  req.state = req.ro.readyState;
  if (req.ro.readyState == 4) {
    if (req.ro.status == 200) {
      processHeaders(req.ro.getAllResponseHeaders());
      var args       = argsString.split(epsc_separator);
      var objId      = args[0];
      var objProp    = (args[1])?args[1]:'innerHTML';
      var objContent = req.ro.responseText;
      epscSetObjProp(objId, objProp, objContent, 0, null);
    }
    epscRelease(req);
  }
}

//key1=val1|key2=val2|key3=val3 ....
function epscUpdateSelectBox(req, argsString) {
  req.state = req.ro.readyState;
  if (req.ro.readyState == 4) {
    if (req.ro.status == 200) {
      var args       = argsString.split(epsc_separator);
      var objId      = args[0];
      var format     = args[1];
          format     = format?format:'plain';
      var objContent = req.ro.responseText;
      var options    = objContent.split(/\n/);
      var selectbox  = document.getElementById(objId);
      while (selectbox.options.length > 0) {
        selectbox.options[0] = null;
      }
      for (i = 0; i < options.length; i++) {
        var pair = options[i].split(/=/);
        var key  = pair[0];
        var val  = pair[1];
        if (!val) val = key;
        var option = new Option(key, val);
        selectbox.options.add(option);
      }
    }
    epscRelease(req);
  }
}

function epscGetObjProp(objId, objProp) {
  var value = null;
  try {
    value = eval("document.getElementById(\"" + objId + "\")." + objProp);
  } catch (exception) {
    return null;
  }
  return value;
}

//review
function epscSetObjProp(objId, objProp, objContent, displayOrder, displayMode) {
  var content = unescape(objContent);
  if (displayOrder > 0) {
    epscUpdtEnqueue(objId, objProp, objContent, displayOrder, displayMode);
    return false;
  }

  if (eval("document.getElementById(\"" + objId + "\")")) {
    if (displayMode == 'change') {
    } else if (displayMode == 'append') {
      content = epscGetObjProp(objId, objProp) + content;
    } else if (displayMode == 'prepend') {
      content = content + epscGetObjProp(objId, objProp);
    }

    eval("document.getElementById(\"" + objId + "\")." + objProp + " = content;");
    return true;
  } else {
    epscUpdtEnqueue(objId, objProp, objContent, displayOrder, displayMode);
  }
  return false;
}

function epscEvalJS(evalStr) {
  try {
    eval(evalStr);
    return true;
  } catch(exception) {
    epscEvalEnqueue(evalStr);
  }
  return false;
}

function epscCheckDOM() {
  try {
    for (i = 0; i < epscWatchIds.length; i++) {
      var obj = document.getElementById(epscWatchIds[i]);
      if (obj.getAttribute('content').length > 0) {
        epscParse(XMLLoadFromStr(obj.getAttribute('content')));
        obj.setAttribute('content', "");
      }
    }
  } catch (e) {

  }
}

function epscParse(xmldoc) {
  var update   = xmldoc.getElementsByTagName("update");
  for (i = 0; i < update.length; i++) {
    var item = update.item(0);
    for (j = 0; j < item.childNodes.length; j++) {
      if (item.childNodes[j].nodeName == "section") {
        var listVars = new Array('url', 'urlclass', 'target', 'property', 'value', 'require', 'callback', 'mode', 'order', 'refresh');
        for (k = 0; k < listVars.length; k++) {
          eval("var section_" + listVars[k] + " = null"); 
          try {
            var varValue = item.childNodes[j].getElementsByTagName(listVars[k]).item(0).textContent?
                           item.childNodes[j].getElementsByTagName(listVars[k]).item(0).textContent:
                           item.childNodes[j].getElementsByTagName(listVars[k]).item(0).firstChild.data;
            if (varValue != null) eval("section_" + listVars[k] + " = varValue;");
          } catch (exceptionGetvars) {
            //alert("uink (" + listVars[k] + ") " + exceptionGetvars.message);
          }
        }
        if (section_urlclass == null) section_urlclass = 'html';
        if (section_mode     == null) section_mode     = 'change';
        if (section_property == null) section_property = 'innerHTML';
        if (section_order    == null) section_order    = 0;
        if (section_refresh  == null) section_refresh  = 0;
        if (section_require != null) epscLoadJS(section_require);
        if (section_url != null) {
          if (section_callback == null) {
            if (section_urlclass == "html") epscGet(unescape(section_url), epscUpdateIdWithURL, section_target + epsc_separator + section_property + epsc_separator + section_mode);
            if (section_urlclass == "xml") epscGet(unescape(section_url), null, section_target + epsc_separator + section_property);
          } else {
            epscGet(unescape(section_url), section_callback, section_target + epsc_separator + section_property + epsc_separator + section_mode);
          }
        }
        if (section_value != null) {
          if (section_callback == null) {
            epscSetObjProp(section_target, section_property, section_value, section_order, section_mode);
          } else {
            pfunc = eval(section_callback);
            pfunc(unescape(section_value));
          }
        }
        //review: only works with urls
        if (section_refresh > 0) {
          if (section_url != null) {
            refreshableEnqueue(section_refresh, section_url, section_target, section_property);
          }
        }
      }
    }
  }
  //<onload> section!
  var onload   = xmldoc.getElementsByTagName("onload");
  for (i = 0; i < onload.length; i++) {
    var item = onload.item(0);
    for (j = 0; j < item.childNodes.length; j++) {
      if (item.childNodes[j].nodeName == "get") {
        var get_url       = item.childNodes[j].getElementsByTagName('url').item(0)?
                            item.childNodes[j].getElementsByTagName('url').item(0).firstChild.data:null;
        var get_callback  = item.childNodes[j].getElementsByTagName('callback').item(0)?
                            item.childNodes[j].getElementsByTagName('callback').item(0).firstChild.data:null;
        //epscGet(unescape(get_url), get_callback, null, 6, get_url);
        epscReqEnqueue(epscGet, get_url, get_callback, null, 6, req.url); //review!!
      }
    }
  }
  //<eval> section
  var evallst  = xmldoc.getElementsByTagName("eval");
  for (i = 0; i < evallst.length; i++) {
    //javascript evaluations
    try {
      var jsstr = "";
      for (j = 0; j < evallst[i].getElementsByTagName('js')[0].childNodes.length; j++) {
        //epscEvalJS(unescape(evallst[i].getElementsByTagName('js')[0].childNodes[j].data));
        jsstr = jsstr + decodeURIComponent(evallst[i].getElementsByTagName('js')[0].childNodes[j].data);
      }
      epscEvalJS(unescape(jsstr));
    } catch (eval_exception) {
    }
  }
}

function epscProcess(req, args) {
  req.state = req.ro.readyState;
  if (req.ro.readyState == 4) {
    refreshableClear();
    try {
      if (req.ro.status == 200) {
        if (epsc_handleCookies) 
          processHeaders(req.ro.getAllResponseHeaders());
        var isXml    = false;
        var text     = req.ro.responseText;
//document.getElementById('debug_nfo').innerHTML = "<textarea cols=100 rows=20>" + text + "</textarea>";
        if (text.match(/xml version/)) isXml = true;
        if (isXml) {
          //var xmldoc   = req.ro.responseXML;
          //<update> section!
          epscParse(req.ro.responseXML);
        } else {//no XML
          if (eval("document.getElementById(\"" + args + "\")")) {
            epscSetObjProp(args, 'innerHTML', text, 0, null);
          } else {
            //updateElement(container, name, html, style)
            updateElement(null, 'staticContent', text, "");
          }
        }
      } else {
        //error - status unexpected
      }
    } catch (exception) {
      //error accessing object status - FAILED TO PUT CONTENT THERE!?
      //return 0;
      //alert(exception);
    }
    epscRelease(req);
  }

}

function element_exists(array, item) {
  if (array ==null) return false;
  for (i = 0; i < array.length; i++) {
    if (array[i] == item) return true;
  }
  return false;
}

//MARTELO!!! review - review - review - review - review - review
function epscWrapVars(str) {
  if (!str.match("|")) {
    str += "|";
  }
  var keys   = str.split("|");
      keys.push(epsc_sessionName);
  var pairs  = new Array();
  var regexp = /([a-z0-9_]+)=(.*)/i;
  for (var i = 0; i < keys.length; i++) {
    var value = null;
    if (regexp.test(keys[i])){
      var pair = regexp.exec(keys[i]);
      keys[i] = pair[pair.length - 2];
      value   = pair[pair.length - 1];
    } else {
      /*
      try {
        if (document.getElementById(keys[i]).nodeName.match(/^select$/i)) {
          for (k = 0; k < document.getElementById(keys[i]).childNodes.length; k++) {
            var option = document.getElementById(keys[i]).childNodes[k].nodeName;
            if (option.match(/^option$/i)) {
              var selected   = document.getElementById(keys[i]).childNodes[k].selected;
              var localValue = document.getElementById(keys[i]).childNodes[k].value;
              if (selected == true) pairs.push(keys[i] + "=" + localValue);
            }
          }
        } else {
          value = document.getElementById(keys[i]).value;
        }
      } catch (exceptionField) {
        try {
          value = cookieRead(keys[i]);
        } catch (exceptionCookie) {

        }
      }
      */
      try {
        value = cookieRead(keys[i]);
      } catch (exceptionCookie) {

      }
    }//end of if regexp.test

    if (value == null) {
      try {
        var formItems = Array('input','textarea','select');
        for (h = 0; h < formItems.length; h++) {
          var formItem = formItems[h];
          var itemList;
          try {
            itemList = document.getElementById(keys[i]).getElementsByTagName(formItem); //all items inside a form with the given tagname
          } catch (exceptionNotAForm) {
            itemList = document.getElementsByTagName(formItem); //all items by tagname
          }
          if (itemList.length == 0) { //try grabbing if no items are found in the form
            itemList = document.getElementsByTagName(formItem); //all items by tagname
          }
          for (j = 0; j < itemList.length; j++) {
            var nodeName   = itemList[j].nodeName;
            var itemName   = itemList[j].name;
            var itemValue  = escape(itemList[j].value);
            if (itemList[j].type == 'checkbox') {
              if (itemList[j].checked != true) itemValue = "";
            }
            if (itemList[j].type == 'radio') {
              if (itemList[j].checked != true) itemValue = "";
            }
            if ((nodeName.match(/^input$/i))||(nodeName.match(/^textarea$/i))) {
              if (itemValue != "") {
                if (!element_exists(pairs, itemName + "=" + itemValue)) pairs.push(itemName + "=" + itemValue);
                //if ((itemList[j].type == 'text')||(itemList[j].type == 'button')||(nodeName.match(/^textarea$/i))) {
                //} else {
                //  pairs.push(itemName + "=" + itemValue);
                //}
              }
            } else if (nodeName.match(/^select$/i)) {
              var optionList = itemList[j].getElementsByTagName('option');
              for (k = 0; k < optionList.length; k++) {
                var selected   = optionList[k].selected;
                var localValue = optionList[k].value;
                if ((selected == true)&&(!element_exists(pairs, itemName + "=" + localValue))) pairs.push(itemName + "=" + localValue);
              }
            } else {
              //handle other types
            }
          }
        }
      } catch (exceptionForm) {
        alert("Exception: " + exceptionForm.message);
      }
    }

    if ((typeof(value) != 'undefined')&&(value != null)&&(value != "")) {
      if (!element_exists(pairs, keys[i] + "=" + value)) pairs.push(keys[i] + "=" + value);
    } else {
      pairs.push("_undefined_" + keys[i] + "=" + value);
    }
  }
  return pairs.join("&");
}

function queueMonitor() {
  epscUpdtObj(); //check for objects that failed to update
  epscEvalObj(); //check for eval code that did not run yet
  epscReqDequeue();  //check for requests pending
  if ((reqQueue.length > 0)||(updtQueue.length > 0)) {
    setTimeout(queueMonitor,100);
  } else {
    setTimeout(queueMonitor,500);
  }
}

function epscLifecycleCheck() {
  var timenow = (new Date()).getTime();
  var count   = 0;
  for (var i = 0; i < xmlHttpReqs.length; i++) {
    if (xmlHttpReqs[i].state != 0) count++;
  }

  for (var i = 0; i < xmlHttpReqs.length; i++) {
    //cleans requests working for more than epsc_requestTimeout
    if (((timenow - xmlHttpReqs[i].timestart > epsc_requestTimeout)&&(xmlHttpReqs[i].state != 0))||(xmlHttpReqs[i].timestart < 1)) {
      epscRelease(getSlot(xmlHttpReqs[i].id));
    }
  }

  refreshableProcess();
  epscCheckDOM();
  setTimeout(epscLifecycleCheck,1000);
}

//framework functions
//onload=epscStart;
function epscStart(url) {
  epscInitialize();
  if ((typeof(url) != 'undefined')||(url != null)) {
    epscGet(url, null, 0);
  } else {
    epscGet(epsc_startupUrl, null, 0);
  }
}
/*
function epscCreateElement(object) {
  if (epscLibLoaded(url)) return true;
  var e      = document.createElement("epscobj");
  e.name     = object.name;
  e.instance = object;
  document.getElementsByTagName("head")[0].appendChild(e);
}

function epscElementExists {

}
*/
function epscLoadJS(url) {
  if (epscLibLoaded(url)) return true;
  var e = document.createElement("script");
  e.src = url;
  e.type="text/javascript";
  document.getElementsByTagName("head")[0].appendChild(e);
}

function epscLibLoaded(lib) {
  var head = document.getElementsByTagName("script");
  for (i = 0; i < head.length; i++) {
    if (head[i].src.indexOf('/' + lib) >= 0) return true;
  }
}

//DUMP AND DEBUG STUFF!
function dumpState(reqId) {
  var dumpTxt       = "<b>Pool slots state and info.</b><br>";
  var dumpObjDetail = "<table cellpadding=0 cellspacing=2 border=0 width=100%>";
  var dumpObjState  = "<table cellpadding=2 cellspacing=2 border=0 width=100%><tr>";
  var sbgcolor;
  for (var i = 0; i < xmlHttpReqs.length; i++) {
    sbgcolor       = (xmlHttpReqs[i].state == 0)?'#00ff00':
                     (xmlHttpReqs[i].state == 1)?'#cc0000':
                     (xmlHttpReqs[i].state < 4)?'#cccc00':
                     '#cc0000';
    dumpObjState  += "<td align=center bgcolor=" + sbgcolor + ">(" + xmlHttpReqs[i].state + ")</td>";
    dumpObjDetail += "<tr>";
    dumpObjDetail += "<td><b>" + i + "</b></td>";
    dumpObjDetail += "<td>url:" + xmlHttpReqs[i].url + "</td>";
    dumpObjDetail += "<td>state:" + xmlHttpReqs[i].state + "</td>";
    dumpObjDetail += "<td>id:" + xmlHttpReqs[i].id + "</td>";
    dumpObjDetail += "<td>timestart:" + xmlHttpReqs[i].timestart + "</td>";
    dumpObjDetail += "<td>elapsed:" + xmlHttpReqs[i].elapsed() + "</td>";
    dumpObjDetail += "</tr>";
    //dumpTxt = dumpTxt + " -" + xmlHttpReqs[i].elapsed() + "\n";
    //dumpTxt = dumpTxt + " -" + xmlHttpReqs[i].url + "\n";
  }
  dumpObjState  += "</tr></table>";
  dumpObjDetail += "</table>";
  dumpTxt += "<table>";
  dumpTxt += "<tr><td bgcolor=#aaaaaa>" + dumpObjState + "</td></tr>";
  dumpTxt += "<tr><td>" + dumpObjDetail + "</td></tr>";
  dumpTxt += "</table>";
  return dumpTxt;
}

function dumpQueue() {
  var dumpTxt = "";
  for (var i = 0; i < evalQueue.length; i++) {
    dumpTxt = dumpTxt + "+ Queue(E): " + evalQueue[i].evalStr + " - " + evalQueue[i].tries + "\n";
  }
  for (var i = 0; i < updtQueue.length; i++) {
    dumpTxt = dumpTxt + "+ Queue(U): " + updtQueue[i].objId + " - " + updtQueue[i].tries + "\n";
  }
  for (var i = 0; i < reqQueue.length; i++) {
    dumpTxt = dumpTxt + "+ Queue(R): " + reqQueue[i].url + "(" + typeof(reqQueue[i].fn) + ") - " + reqQueue[i].enqueueing_type + "\n";
  }
  return dumpTxt;
}


/**********************************************************/
/**********************************************************/
/************ Auxiliary Functions *************************/
/**********************************************************/
/**********************************************************/
function trim(str) {
  var tmpstr = str.replace(/^\ +/, "");
  return tmpstr.replace(/\ +$/, "");
}

//http://www.quirksmode.org/js/cookies.html
function cookieCreate(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  } else var expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}

function cookieRead(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

function cookieErase(name) {
  cookieCreate(name,"",-1);
}

function updateElement(container, name, html, style) {
  try {
    if (document.getElementById(name).innerHTML) {
      document.getElementById(name).innerHTML = html;
    }
  } catch (exceptionNoDiv) {
    if (container == null) {
      container = document.body;
    }
    removeElement(container, name); //make sure the object was deleted
    var div = document.createElement('div');
    div.setAttribute('style', style);
    try { //Opera workaround (b_ie4 is true in opera)
      if (b_ie4) div.style.setAttribute('cssText', style);
    } catch (exceptionSetAttr) {}
    div.id = name;
    div.innerHTML = html;
    container.appendChild(div);
  }
}

function removeElement(container, ID) {
  try {
    if (container == null) {
      container = document.body;
    }
    var element = document.getElementById(ID);
    container.removeChild(element);
  } catch (e) {}
}

function nop() {}

/**
 * based on: http://www.webreference.com/programming/javascript/definitive2/index.html
 * Create a new Document object. If no arguments are specified,
 * the document will be empty. If a root tag is specified, the document
 * will contain that single root tag. If the root tag has a namespace
 * prefix, the second argument must specify the URL that identifies the
 * namespace.
 */
function XMLNewDocument(rootTagName, namespaceURL) {
  if (!rootTagName) rootTagName = "";
  if (!namespaceURL) namespaceURL = "";
  if (document.implementation && document.implementation.createDocument) {
    // This is the W3C standard way to do it
    return document.implementation.createDocument(namespaceURL, rootTagName, null);
  }
  else { // This is the IE way to do it
    // Create an empty document as an ActiveX object
    // If there is no root element, this is all we have to do
    var doc = new ActiveXObject("MSXML2.DOMDocument");
    // If there is a root tag, initialize the document
    if (rootTagName) {
      // Look for a namespace prefix
      var prefix = "";
      var tagname = rootTagName;
      var p = rootTagName.indexOf(':');
      if (p != -1) {
        prefix = rootTagName.substring(0, p);
        tagname = rootTagName.substring(p+1);
      }
      // If we have a namespace, we must have a namespace prefix
      // If we don't have a namespace, we discard any prefix
      if (namespaceURL) {
        if (!prefix) prefix = "a0"; // What Firefox uses
      }
      else prefix = "";
      // Create the root element (with optional namespace) as a
      // string of text
      var text = "<" + (prefix?(prefix+":"):"") +  tagname +
          (namespaceURL
           ?(" xmlns:" + prefix + '="' + namespaceURL +'"')
           :"") +
          "/>";
      // And parse that text into the empty document
      doc.loadXML(text);
    }
    return doc;
  }
}

function XMLLoadFromURL(url) {
    // Create a new document with the previously defined function
    var xmldoc = XMLNewDocument();
    xmldoc.async = false;  // We want to load synchronously
    xmldoc.load(url);      // Load and parse
    return xmldoc;         // Return the document
}

/**
 * Parse the XML document contained in the string argument and return
 * a Document object that represents it.
 */
function XMLLoadFromStr(text) {
    if (typeof DOMParser != "undefined") {
        // Mozilla, Firefox, and related browsers
        return (new DOMParser()).parseFromString(text, "application/xml");
    }
    else if (typeof ActiveXObject != "undefined") {
        // Internet Explorer.
        var doc = XMLNewDocument();  // Create an empty document
        doc.loadXML(text);            // Parse text into it
        return doc;                   // Return it
    }
    else {
        // As a last resort, try loading the document from a data: URL
        // This is supposed to work in Safari. Thanks to Manos Batsis and
        // his Sarissa library (sarissa.sourceforge.net) for this technique.
        var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text);
        var request = new XMLHttpRequest();
        request.open("GET", url, false);
        request.send(null);
        return request.responseXML;
    }
}

