function JWPAlertLogger() {

  this.LEVEL_TRACE = 0;
  this.LEVEL_DEBUG = 1;
  this.LEVEL_INFO = 2;
  this.LEVEL_ERROR = 3;
  this.LEVEL_FATAL = 4;
  this.handle = null;
  this.minLevel = 2;
  this.bg = ["#ffff00","#00ffff","#00ff00","#ffa0a0","#ff0000"];
  this.setMinLevel = function(level) {
    minLevel = level;
  }
  this.trace = function(msg) {
    if (minLevel <= this.LEVEL_TRACE) {
      this.write(msg, this.bg[this.LEVEL_TRACE]);
    }
  }
  this.debug = function(msg) {
    if (minLevel <= this.LEVEL_DEBUG) {
      this.write(msg, this.bg[this.LEVEL_DEBUG]);
    }
  }
  this.info = function(msg) {
    if (minLevel <= this.LEVEL_INFO) {
      this.write(msg, this.bg[this.LEVEL_INFO]);
    }
  }
  this.error = function(msg) {
    if (minLevel <= this.LEVEL_ERROR) {
      this.write(msg, this.bg[this.LEVEL_ERROR]);
    }
  }
  this.fatal = function(msg) {
    if (minLevel <= this.LEVEL_FATAL) {
      this.write(msg, this.bg[this.LEVEL_FATAL]);
    }
  }
  this.write = function(msg, bg) {
    alert(msg);
  }
}
function AjaxPartsTaglib() {

  this.calls = new Array();
  this.uniqIdx = 0;
  this.reqHandlers = new Array();
  this.resHandlers = new Array();
  this.events = new Array();
  this.ctxtPath = "/gmi";
  this.errHandlers = new Array();
  this.log = new JWPAlertLogger();
  this.log.setMinLevel(this.log.LEVEL_ERROR);

  this.regReqHandler = function(handName, func) {
    if (!this.reqHandlers[handName]) {
      this.reqHandlers[handName] = func;
    }
  }

  this.regResHandler = function(handName, func) {
    if (!this.resHandlers[handName]) {
      this.resHandlers[handName] = func;
    }
  }

  this.regErrHandler = function(errCode, groupAR, elemAR, evtType, func) {
    var key = errCode + groupAR +
      (groupAR != "" && elemAR != "" ? "/" : "") +
      elemAR + evtType;
    if (!this.errHandlers[key]) {
      this.errHandlers[key] = func;
    }
  }

  this.getXHR = function() {
    if (window.XMLHttpRequest) {
      return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      return new ActiveXObject("Microsoft.XMLHTTP");
    }
  }

  this.ajaxRequestSender = function(evtDef, pb, qs, xhr, headers) {
    var callKey = "" + this.calls.length;
    if (xhr == null) {
      xhr = this.getXHR();
    }
    var f = function() {
      ajaxPartsTaglib.onResponseStateChange(callKey);
    }
    xhr.onreadystatechange = f;
    var targURI = (evtDef.targURI.indexOf('?') > 0);
    if (!qs) {
      qs = "";
    }
    if (targURI && qs) {
      qs = qs.replace("?", "&");
    }
    if (qs == "" && !targURI) {
      qs = "?";
    } else {
      qs += "&";
    }
    qs  += "uniqIdx=" + new Date().getTime() + this.uniqIdx++;
    qs += "&ajaxRef=" + evtDef.ajaxRef;
    var ajCall = {
      xhr : xhr,
      evtDef : evtDef,
      pb : pb,
      qs : qs
    };
    this.calls[callKey] = ajCall;
    this.log.debug("ajaxRequestSender() called...\n\n" +
      "ajCall:\n" +
      "pb: " + ajCall.pb + "\n" +
      "qs: " + ajCall.qs + "\n\n" +
      "evtDef: (\n" +
      "resHandParams: " + evtDef.resHandParams + "\n" +
      "theForm: " + evtDef.theForm + "\n" +
      "targURI: " + evtDef.targURI + "\n" +
      "reqHandler: " + evtDef.reqHandler + "\n" +
      "reqParam: " + evtDef.reqParam + "\n" +
      "httpMeth: " + evtDef.httpMeth + "\n" +
      "timerObj: " + evtDef.timerObj + "\n" +
      "ajaxRef: " + evtDef.ajaxRef + "\n" +
      "async: " + evtDef.async + "\n" +
      "evtType: " + evtDef.evtType + "\n" +
      "preProc: " + evtDef.preProc + "\n" +
      "postProc: " + evtDef.postProc + "\n)"
    );
    if (evtDef.preProc && evtDef.preProc != "") {
      var ppResult = eval(evtDef.preProc)(ajCall);
      if (ppResult) {
        return;
      }
    }
    xhr.open(evtDef.httpMeth, evtDef.targURI + qs, evtDef.async);
    if (headers != null) {
      for (var hdr in headers) {
        xhr.setRequestHeader(hdr, headers[hdr]);
      }
    }
    xhr.send(pb);
    if (!evtDef.async) {
      this.onResponseStateChange(callKey);
    }
  }

  this.onResponseStateChange = function(callKey) {
    var ajCall = this.calls[callKey];
    if (!callKey || !ajCall) {
      return;
    }
    var xhr = ajCall.xhr;
    var evtDef = ajCall.evtDef;
    if (xhr.readyState < 4) {
      return;
    }
    if (xhr.status == 200) {
      this.log.debug("Call: '" + callKey + "' to: '" + evtDef.targURI +
        "' has returned...\n\nresponseText=\n" + ajCall.xhr.responseText +
        "\n\nAbout to call response handler chain: '" + evtDef.resHandParams);
      var resHandParams = evtDef.resHandParams;
      for (var i = 0; i < resHandParams.length; i = i + 3) {
        var resHandler = this.resHandlers[resHandParams[i]];
        if (!resHandler) {
          var f = function() {
            ajaxPartsTaglib.onResponseStateChange(callKey);
          }
          setTimeout(f, 100);
        } else {
          if (resHandParams[i + 3] == null ||
            ajCall.xhr.responseText.match(resHandParams[i + 3])) {
            var rhResult = resHandler(ajCall, resHandParams[i + 1]);
            if (rhResult) {
              break;
            }
          }
        }
      }
      this.execScripts(xhr.responseText);
      if (evtDef.postProc && evtDef.postProc != "") {
        eval(evtDef.postProc)(ajCall);
      }
      if (evtDef.evtType == "timer") {
        eval("start" + evtDef.ajaxRef.replace("/", "_") + "();");
      }
    } else {
      this.log.debug(xhr.status);
      var eh = this.errHandlers[xhr.status + evtDef.ajaxRef +
        evtDef.evtType];
      if (!eh) {
        eh = this.errHandlers[xhr.status + evtDef.ajaxRef];
      }
      if (!eh) {
        var a = evtDef.ajaxRef.split("/");
        eh = this.errHandlers[xhr.status + a[0]];
      }
      if (eh) {
        eh(ajCall);
      }
    }
    ajCall = null;
    delete this.calls[callKey];
  }

  this.attach = function(ajaxRef, targURI, reqHandler, reqParam,
    resHandParams, httpMeth, theForm, evtType, preProc, postProc,
    async) {

    var targetObject = null;
    var theFormOrigVal = theForm;
    if (evtType != "manual" && evtType != "timer") {
      targetObject = document.getElementById(ajaxRef);
      while ((targetObject = targetObject.previousSibling).nodeType != 1);
      if (theForm == "parent") {
        try {
          theForm = targetObject.form;
        } catch (error) {
        }
      } else {
        theForm = document.forms[theForm];
        if (!theForm) {
          theForm = document.getElementById(theForm);
        }
      }
    } else {
      if (theForm != null && theForm != "" && theForm != "parent") {
        theForm = document.forms[theForm];
        if (!theForm) {
          theForm = document.getElementById(theForm);
        }
      }
    }
    if (theFormOrigVal != null && theFormOrigVal != "" && !theForm) {
      this.log.debug("Unable to find form " + theFormOrigVal +
        " for ajaxRef " + ajaxRef);
    }
    if (targURI.charAt(0) == "/") {
      targURI = this.ctxtPath + targURI;
    }
    var evtDef = {
      resHandParams : resHandParams,
      theForm : theForm,
      targURI : targURI,
      reqHandler : reqHandler,
      reqParam : reqParam,
      httpMeth : httpMeth,
      timerObj : null,
      ajaxRef : ajaxRef,
      async : async,
      evtType : evtType,
      preProc : preProc,
      postProc : postProc
    };
    this.events[ajaxRef + evtType] = evtDef;
    if (evtType != "manual" && evtType != "timer") {
      var newHandler =
        function () { ajaxPartsTaglib.execute(ajaxRef + evtType); };
      var targFunc = targetObject[evtType];
      targetObject.evtRef = ajaxRef + evtType;
      if (targFunc) {
        var oldHandler = targFunc;
        targFunc = function() {
          oldHandler();
          newHandler();
        };
      } else {
        targFunc = newHandler;
      }
      targetObject[evtType] = targFunc;
    }
  }

  this.execute = function(evtRef) {
    var evtDef = this.events[evtRef];
    var reqHandler = this.reqHandlers[evtDef.reqHandler];
    reqHandler(evtDef);
  }

  this.execScripts = function (resText) {
    var si = 0;
    while (true) {
      var ss = resText.indexOf("<" + "script" + ">", si);
      if (ss == -1) {
        return;
      }
      var se = resText.indexOf("<" + "/" + "script" + ">", ss);
      if (se == -1) {
        return;
      }
      si = se + 9;
      var sc = resText.substring(ss + 8, se);
      eval(sc);
    }
  }

}


var ajaxPartsTaglib = new AjaxPartsTaglib();
function JWPGetElementValue(field) {
  if (field.length != null) {
    var type = field[0].type;
  }
  if ((typeof(type) == 'undefined') || (type == 0)) {
    var type = field.type;
  }
  var result = new Array();
  switch(type) {
    case 'undefined': break;
    case 'radio':
      for (var x=0; x < field.length; x++) {
        if (field[x].checked == true) {
           result[0] = field[x].value;
        }
      }
      break;
    case 'select-multiple':
      for(var x=0; x < field.length; x++) {
        if (field[x].selected == true) {
          result[result.length] = field[x].value;
        }
      }
      break;
    case 'checkbox':
      result[0] = field.checked;
      break;
    default:
      result[0] = field.value;
  }
  return result;
}



function StdPoster(evtDef) {
  pb = "";
  addition = "";
  nvp = evtDef.reqParam.split(",");
  i = 0;
  while (i < nvp.length) {
    nav = nvp[i].split("=");
    if (nav[1].charAt(0) == "\'") {
      fe = nav[1].substring(1, nav[1].length - 1);
      pb += addition + nav[0] + "=" + escape(fe);
    } else {
      fe = eval("document." + evtDef.theForm.name + "[\"" + nav[1] + "\"]");
      feValues = JWPGetElementValue(fe);
      j = 0;
      while (j < feValues.length) {
        pb += addition + nav[0] + '=' + escape(feValues[j]);
        addition = "&";
        j++;
      }
    }
    addition = "&";
    i++;
  }
  ajaxPartsTaglib.ajaxRequestSender(evtDef, pb, null, null,
    {"Content-Type":"application/x-www-form-urlencoded"});
}


function StdInnerHTML(ajCall, resParam) {
  var a = resParam.split(",");
  for (var i = 0; i < a.length; i++) {
    document.getElementById(a[i]).innerHTML = ajCall.xhr.responseText;
  }
}


ajaxPartsTaglib.attach("SurveyForm/SendRating", "/RateSite", "StdPoster", "url=url,title=title,rating=rating,comments=comments,successHtml=successHtml,errorHtml=errorHtml", [ "StdInnerHTML", "surveyFormSpan", null ], "post", "parent", "onclick", "", "postSubmitSurveyForm", true);

ajaxPartsTaglib.regReqHandler("StdPoster", StdPoster);

ajaxPartsTaglib.regResHandler("StdInnerHTML", StdInnerHTML);


