/**
 * Ajax object
 *
 * A Javascript Ajax object to handle Ajax communications.
 *
 * @author Wouter Thielen
 * @credits Simon Koster
 *
 **/

var Ajax = {
  m_sUrl : null,
  m_sSection : null,
  m_aData : null,
  m_aRequests : [],
  m_aDataListeners : null,
  m_oHandler : null,
	m_bInitialized : false,
	m_bAsync : true,

  init : function(p_sUrl) {
		if (Ajax.m_bInitialized == true) {
			alert("already inited");
			return;
		}

    // Create HTTP handler
    l_oHTTPHandler = false;
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    // JScript gives us Conditional compilation, we can cope with old IE versions.
    // and security blocked creation of the objects.
    try {
      l_oHTTPHandler = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (l_oException1) {
      try {
        l_oHTTPHandler = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (l_oException2) {
        l_oHTTPHandler = false;
      }
    }
    @end @*/
    if (!l_oHTTPHandler && typeof XMLHttpRequest!='undefined') {
      l_oHTTPHandler = new XMLHttpRequest();
    }
    this.m_oHandler = l_oHTTPHandler;

    // Initialize variables
    this.m_sUrl = p_sUrl;
    this.m_aDataListeners = new Array();
		Ajax.m_bInitialiazed = true;
		Ajax.setAsync(true);
  },

	setAsync : function(p_bAsync) {
		this.m_bAsync = p_bAsync;
	},

  // Adds a listener
  addDataListener : function(p_sIdentifier, p_fFunc) {
    this.m_aDataListeners[p_sIdentifier] = p_fFunc;
  },

  // Sends the request
  send : function(p_aData) {
  	//_e('myDiv').innerHTML += debug(p_aData) + '<br />';
    this.m_aRequests.push(p_aData);
    processQueue();
  },

	isBusy : function() {
    return (this.m_oHandler.readyState > 0 && this.m_oHandler.readyState < 4);
  },

  hasRequests : function() {
    return (this.m_aRequests.length > 0);
  },

  filterRequests : function() {
    var l_aQueued = new Array();
    var l_aRequests = new Array();
    while (l_aData = this.m_aRequests.pop()) {
      if (!l_aQueued[l_aData['identifier']]) {
        l_aQueued[l_aData['identifier']] = true;
	l_aRequests.unshift(l_aData);
      }
    }
    this.m_aRequests = l_aRequests;
  }
}

function processQueue() {
  if (Ajax.hasRequests() == false) return;

  Ajax.filterRequests();

  if (Ajax.isBusy()) {
    setTimeout("processQueue()", 100);
    return;
  }

  Ajax.m_aData = Ajax.m_aRequests.pop();

  // Open a connection and set headers
  Ajax.m_oHandler.open('POST', Ajax.m_sUrl, Ajax.m_bAsync);
  Ajax.m_oHandler.setRequestHeader("Cache-Control", "no-cache");
  Ajax.m_oHandler.setRequestHeader("X_USERAGENT", "Basisshop2Ajax");
  Ajax.m_oHandler.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  Ajax.m_oHandler.setRequestHeader("Connection", "close");

	if (Ajax.m_bAsync === true) {
		// Prepare callback function
		Ajax.m_oHandler.onreadystatechange = function() {
			if (Ajax && Ajax.m_oHandler.readyState == 4) {
				var l_oObject = eval('(' + Ajax.m_oHandler.responseText + ')');
				var l_aReference = (Ajax.m_aData['reference'] ? Ajax.m_aData['reference'] : null);
				if (Ajax.m_aData['identifier']) {
					if (Ajax.m_aDataListeners[Ajax.m_aData['identifier']]) {
						Ajax.m_aDataListeners[Ajax.m_aData['identifier']](l_oObject, l_aReference);
					} else {
	//					alert('Please define a callback for the ' + Ajax.m_aData['identifier'] + ' Ajax call.');
					}
				}
			}
		}
	} else {
		Ajax.m_oHandler.onreadystatechange = null;
	}

  // Send request
  Ajax.m_oHandler.send('data=' + escape(encode_utf8(JSON.encode(Ajax.m_aData))));

	if (Ajax.m_bAsync === false) {
		var l_oObject = eval('(' + Ajax.m_oHandler.responseText + ')');
		var l_aReference = (Ajax.m_aData['reference'] ? Ajax.m_aData['reference'] : null);
		if (Ajax.m_aData['identifier']) {
			if (Ajax.m_aDataListeners[Ajax.m_aData['identifier']]) {
				Ajax.m_aDataListeners[Ajax.m_aData['identifier']](l_oObject, l_aReference);
			} else {
	//			alert('Please define a callback for the ' + Ajax.m_aData['identifier'] + ' Ajax call.');
			}
		}
	}

  if (Ajax.hasRequests()) processQueue();
}
