// The ajax module also requires a version of o2escape.js (formFunctions.js? temporaryMessage.js?)
// XXX Find out where the "undefined" strings come from and get rid of them.

require("/o2www/js/html2dom.js");

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

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

// Synchronous "ajax" call
function sAjaxCall(params) {
  return ajaxCall(params, true);
}

function ajaxCall(params, isSynchronous) {
  isSynchronous = isSynchronous || false;
  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" &&  typeof(params[key]) != 'function' ) { // 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, !isSynchronous); // Third parameter: true means asynchronous, false is synchronous
    o2xmlHttpRequest[ajaxId].send(paramsString);
    if( typeof(params['handler']) == 'function' ) {
        o2xmlHttpRequest[ajaxId].o2AjaxCallbackHandler = params['handler'];
    }  
  }
  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");
	  return;
	}
        if(  o2xmlHttpRequest[ajaxId].o2AjaxCallbackHandler ) { // doing this here to make sure that ajaxHandleServerResponse has it
            result.handler = o2xmlHttpRequest[ajaxId].o2AjaxCallbackHandler;
        }
	delete o2xmlHttpRequest[ajaxId]; // Very important that this line comes before ajaxHandleServerResponse(result)!
        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");
	}
      }
    }
  }
}

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 != "") {
      if( typeof(result.handler) == 'function' ) {
          result.handler(result);
      }
      else {
          eval(result.handler + "(result);");
      }
  }

  if (result.onSuccess && result.onSuccess != "undefined") {
    eval(result.onSuccess);
  }
  if (result.javascriptsToExecute) {
    for (var i = 0; i < result.javascriptsToExecute.length; i++) {
      eval( result.javascriptsToExecute[i] );
    }
  }
  if (result.javascriptFiles) {
    for (var i = 0; i < result.javascriptFiles.length; i++) {
      // console.log( " " + result.javascriptFiles[i] );
      require( result.javascriptFiles[i] );
    }
  }
  if (result.cssFiles) {
    for (var i = 0; i < result.cssFiles.length; i++) {
      require( result.cssFiles[i] );
    }
  }
  _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;
}

