// The ajax module also requires the files html2dom.js and o2escape.js (formFunctions.js)

var o2xmlHttpRequest = new Array();
var ajaxIframeId = "o2ajaxIframe";

function o2ajaxAddIframe() {
  if (window.XMLHttpRequest) {
    return;
  }
  var body = document.body;
  var iframe = document.createElement("iframe");
  iframe.setAttribute("id", ajaxIframeId);
  iframe.setAttribute("onload", "ajaxHandleServerResponseIframe();");
  iframe.style.display = "none";
  body.appendChild(iframe);
}

function ajaxCall(params) {
  var paramsString = "";

  // Make it possible to use css to do something with target, so the user can see that something is going to happen.
  // Setting class=activeAjaxTarget on all targets
  var targets = _ajaxGetTargetsAsArray( params["target"] );
  for (var i = 0; i < targets.length; i++) {
    var elm = document.getElementById( targets[i] );
    if (elm) {
      addClassName(elm, "activeAjaxTarget");
    }
  }

  var src = params["serverScript"];
  if (src.indexOf("?") != -1) {
    var queryString = src.substring( src.indexOf("?")+1 );
    var parameters = queryString.split("&");
    for (var i = 0; i < parameters.length; i++) {
      var paramAndValue = parameters[i].split("=");
      var name  = paramAndValue[0];
      var value = paramAndValue[1];
      paramsString += o2escape(name) + "=" + o2escape(value) + "&";
    }
    src = src.substring( 0,  src.indexOf("?") );
  }
  
  if(typeof(params["params"]) != 'string'){
      var qsp= new Array();
      for (var key in params["params"]) {
          qsp.push (key+'='+params["params"][key]);
      }
      params["params"]=qsp.join('&');
  }

  if (params["params"]) {
    paramsString += params["params"] + "&";
  }
  // Escape params:
  for (var key in params) {
    if (key != "params") { // Håkon, 20070808. Added the if.
      params[key] = o2escape(params[key]);
    }
  }
  paramsString += "target="  + params["target"]  + "&handler=" + params["handler"] + "&where="     + params["where"]
    + "&history=" + params["history"] + "&onError=" + params["onError"] + "&onSuccess=" + params["onSuccess"]
    + "&ignoreMissingTarget=" + params["ignoreMissingTarget"] + "&debug="   + params["debug"]   + "&isAjaxRequest=1"
    + "&ajaxId=" + params['ajaxCallId'] + "&errorHandler=" + params["errorHandler"];
  var ajaxId = params['ajaxCallId']  ||  parseInt( 1000000*Math.random() );
  delete o2xmlHttpRequest[ajaxId];
  if (window.XMLHttpRequest) {
    try {
      o2xmlHttpRequest[ajaxId] = new XMLHttpRequest();
    }
    catch (e) {
      delete o2xmlHttpRequest[ajaxId];
    }
  }
  else if (window.ActiveXObject) { // branch for IE/Windows ActiveX version
    try {
      o2xmlHttpRequest[ajaxId] = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e) {
      try {
        o2xmlHttpRequest[ajaxId] = new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch (e) {
	delete o2xmlHttpRequest[ajaxId];
      }
    }
  }
  if (o2xmlHttpRequest[ajaxId]) {
    paramsString += "&xmlHttpRequestSupported=1";
    o2xmlHttpRequest[ajaxId].onreadystatechange = ajaxHandleServerResponseXmlHttp;
    o2xmlHttpRequest[ajaxId].open("POST", src, true); // Third parameter: true. That's to say explicitely that we want it to be asynchronous. Otherwise it'll be synchronous with Firebug enabled!
    o2xmlHttpRequest[ajaxId].send(paramsString);
  }
  else { // Use a hidden iframe (xmlHttpRequest not supported)
    if (src.indexOf("?") == -1) {
      src += "?";
    }
    else {
      src += "&";
    }
    src += paramsString + "&xmlHttpRequestSupported=0";
    document.getElementById(ajaxIframeId).src = src;
  }
}

function ajaxHandleServerResponseXmlHttp() {
  // only if o2xmlHttpRequest shows "loaded"
  for (ajaxId in o2xmlHttpRequest) {
    if (o2xmlHttpRequest[ajaxId] && o2xmlHttpRequest[ajaxId].readyState == 4) {
      // only if "OK"
      // alert(o2xmlHttpRequest.readyState+" "+o2xmlHttpRequest.status+" "+o2xmlHttpRequest.responseText);
      if (o2xmlHttpRequest[ajaxId].status == 200) {
	var response = unescape(o2xmlHttpRequest[ajaxId].responseText);
	var result;
	try {
	  eval(response);
	}
	catch (e) {
	  _ajaxAlert(o2xmlHttpRequest[ajaxId].responseText, "o2XmlHttpRequest Error", "error");
	  // alert("o2XmlHttpRequest Error:\n"+o2xmlHttpRequest.responseText);
	  return;
	}
	delete o2xmlHttpRequest[ajaxId]; // Very important that this line comes before ajaxHandleServerResponse(result)!
	// o2xmlHttpRequest[ajaxId] = false; // 20070526 nilschd when u callback is handled we should mark it as done?
	ajaxHandleServerResponse(result);
      }
      else {
	if (document.location.href.indexOf("debug") != -1) {
	  _ajaxAlert(o2xmlHttpRequest[ajaxId].statusText + "\n\n" + o2xmlHttpRequest[ajaxId].responseText, "There was a problem retrieving the XML data", "error");
	  // alert("There was a problem retrieving the XML data:\n" + o2xmlHttpRequest.statusText + "\n\n" + o2xmlHttpRequest.responseText);
	}
	// alert("There was a problem retrieving the XML data:\n" + o2xmlHttpRequest.statusText);
      }
    }
  }
}

function ajaxHandleServerResponseIframe(response) {
  ajaxHandleServerResponse(response);
}

function ajaxHandleServerResponse(result) {
  if (!result) {
    _ajaxRemoveClassNameActiveAjaxTarget( result["target"] );
    return;
  }
  if (result["debug"] == "1") {
    var debugString = "DEBUG:\n";
    for (var key in result) {
      debugString += key + " => " + result[key] + "\n";
    }
    _ajaxAlert(debugString);
  }
  if (result["result"] == "error") {
    _ajaxRemoveClassNameActiveAjaxTarget( result["target"] );
    if (result["onError"] == "ignore") {
      return;
    }
    if (result["onError"] && result["onError"] !== "undefined") {
      eval(result["onError"]);
    }
    else if (result["errorHandler"] && result["errorHandler"] !== "undefined") {
      eval(result["errorHandler"] + "(result);");
    }
    else if (result["errorMsg"] && result["onError"] !== "ignore") {
      _ajaxAlert(result["errorMsg"], result["errorHeader"], "error");
    }
    return;
  }
  if ((result["html"] && result["html"] != "undefined")   ||   (result["target"] && result["target"] != "undefined")) {
    var where   =   result["where"]   ?   result["where"]   :   "replace";
    ajaxUpdateContent({
      "target"  : result["target"],
      "content" : result["html"],
      "where"   : where,
      "ignoreMissingTarget" : result["ignoreMissingTarget"]
    });
  }
  else if (result["target"] && result["target"] != "undefined" && result["where"] == "delete") {
    ajaxUpdateContent({
      "target" : result["target"],
      "where" : "delete",
      "ignoreMissingTarget" : result["ignoreMissingTarget"]
    });
  }
  if (result["handler"] && result["handler"] != "undefined" && result["handler"] != "") {
    eval(result["handler"] + "(result);");
  }
  if (result["onSuccess"] && result["onSuccess"] != "undefined") {
    eval(result["onSuccess"]);
  }
  _ajaxRemoveClassNameActiveAjaxTarget( result["target"] );
}
function _ajaxRemoveClassNameActiveAjaxTarget(target) {  // Target elements should no longer have the className "activeAjaxTarget" (it's not active anymore)
  if (target) {
    var targets = _ajaxGetTargetsAsArray( target );
    for (var i = 0; i < targets.length; i++) {
      var elm = document.getElementById( targets[i] );
      if (elm) {
        removeClassName(elm, "activeAjaxTarget");
      }
    }
  }
}
function _ajaxGetTargetsAsArray(targetStr) {
  if (!targetStr) {
    return new Array();
  }
  var targets = targetStr.split(",");
  for (var i = 0; i < targets.length; i++) {
    targets[i] = targets[i].replace(/^\s+/, "");
    targets[i] = targets[i].replace(/\s+$/, "");
  }
  return targets;
}

function ajaxUpdateContent(params) {
  var content = params["content"];
  var where   = params["where"];
  var ids = params["target"].split(",");
  for (var i = 0; i < ids.length; i++) {
    var target = ids[i].replace(/^\s+/, "");
    var elm = document.getElementById(target);
    if (!elm) {
      if (!params["ignoreMissingTarget"]) {
        alert("ajaxUpdateContent (ajax.js): Target element \"" + target + "\" does not exist");
      }
      continue;
    }
    if (where == "replace") {
      setInnerHtml(elm, content);
    }
    else if (where == "delete") {
      elm.parentNode.removeChild(elm);
    }
    else {
      addInnerHtml(elm, content, where);
    }
  }
  /*
    if (params["history"] == "store"
            || (params["where"] == "replace"   &&   params["history"] != "noStore")) {
        var id = params["target"];
        o2ajaxHashVars[id] = params["content"];
    }
  */
}

function _o2AjaxSubmitForm(f, functionName, postFunction) {
  if (!f) {
    return; // vonheim@20060308 <form onsubmit> and <input type=submit> both calls this method. one of them does not include "f"
  }

  if (f.name && _o2OnSubmitEval[f.name]) {
    eval(_o2OnSubmitEval[f.name]);
  }

  verifyForm(f);
  if (formHasErrors) {
    var errorTitle = ''; //XXX - Was "Error in input data". Removed because it was difficult to support different languages. vonheim@20060518
    if (f.getAttribute('ruleTitle')) {
      errorTitle = f.getAttribute('ruleTitle');
    }
    var errorBody = '';
    if (functionName) {
      if (formErrors && formErrors.length) {
        errorBody = formErrors.join("<br>");
      }
      eval(functionName+"('"+errorTitle+"','"+errorBody+"');");
    }
    else {
      if (formErrors && formErrors.length) {
        errorBody = formErrors.join("\n");
      }
      _ajaxAlert(errorBody, errorTitle, "error");
    }
    return false;
  }
  else {
    if (window._o2MultilingualSubmitForm) {
      _o2MultilingualSubmitForm();
    }
    return true;
  }
}

function _ajaxAlert(msg, title, type) {
  // return alert(msg);
  if (!top.displayMessage) {
    if (navigator.appVersion.toLowerCase().match(/msie 6/)) {
      if (title) {
        msg = title + "\n\n" + msg;
      }
      return alert("Ajax Alert:"+msg);
    }
    var div = document.getElementById("ajaxMessageDiv");
    if (!div) {
      div = _createMessageDiv();
    }
    var html = "<pre>" + _encodeHtml(msg) + "</pre>";
    if (title) {
      html = "<h1>" + title + "</h1>" + html;
    }
    html += "<p><input type='button' value='OK' id='ajaxMessageDivCloseButton' onClick='document.getElementById(\"ajaxMessageDiv\").style.display = \"none\";'></p>";
    div.innerHTML = html;
    div.style.display = "";
    document.getElementById("ajaxMessageDivCloseButton").focus();
    div.scrollTop = 0;
    return;
  }
  title = title || type || "Info";
  if (type) {
    type = type.toLowerCase();
  }
  if (!type || type == "info") {
    top.displayMessage(title, msg);
  }
  else if (type == "error") {
    top.displayError(title, msg);
  }
}

function _createMessageDiv() {
  var div = document.createElement("div");
  div.id = "ajaxMessageDiv";
  document.body.appendChild(div);
  return div;
}

function _encodeHtml(html) {
  html = html.replace(/</g, "&lt;");
  html = html.replace(/>/g, "&gt;");
  return html;
}
