
/**
 * File contains JS Library for AJAX management
 *
 * JavaScript  version 1
 * @category   JavaScript Libraries
 * @author     Eugene A. Kalosha <aristarch@zfort.net>
 * @copyright  (c) 2004-2006 by ZFort Group
 * @version    SVN: $Id: 208$
 * @link       http://www.zfort.net
 * @since      File available since Release 2.3.0
 */

/**
 * PHP2Ajax is the namespace for AJAX JavaScript functions and Classes.
 *
 * @author   Eugene A. Kalosha <aristarch@zfort.net>
 * @version  $Id: ajax.js, v 2.3.0 2006/09/14 $
 * @access   public
 * @package  php2
 */
var PHP2Ajax = new Object();

    /**
     * Request method Constants
     */
    PHP2Ajax.REQUEST_METHOD_POST = 'POST';
    PHP2Ajax.REQUEST_METHOD_GET  = 'GET';

    /**
     * Ready State Object Constatnts
     */
    PHP2Ajax.READY_STATE_UNINITIALIZED  = 0;
    PHP2Ajax.READY_STATE_LOADING        = 1;
    PHP2Ajax.READY_STATE_LOADED         = 2;
    PHP2Ajax.READY_STATE_INTERACTIVE    = 3;
    PHP2Ajax.READY_STATE_COMPLETE       = 4;

    /**
     * HTTP Status Constants
     */
    PHP2Ajax.HTTP_STATUS_OK             = 200;
    PHP2Ajax.HTTP_STATUS_FOUND          = 302;

    /**
     * AJAX main Constants
     */
    PHP2Ajax.CALL_REQUEST_PARAMETER      = '__callHandler';
    PHP2Ajax.CALLBACK_HANDLER_PARAMETER  = '__callbackHandler';

    /**
     * Added Parameters Pair to the Current Instanse of Object
     *
     * @param   string name
     * @param   string value
     * @return  void
     */
    PHP2Ajax.add = function(name, value)
    {
      // -- Add a new pair object to the Parameters Array --- //
      this.parameters[this.parametersCount] = new PHP2Ajax.ParametersPair(name,value);
      this.parametersCount++;
    }

    /**
     * Clear Parameters Pair in the Current Instanse of Object
     *
     * @return  void
     */
    PHP2Ajax.clearRequest = function()
    {
      this.parameters = new Object();
      this.parametersCount = 0;
    }

    /**
     * Sets Server method to Call
     *
     * @param   string functionName Called method name
     * @return  void
     */
    PHP2Ajax.call = function(functionName)
    {
      this.add(PHP2Ajax.CALL_REQUEST_PARAMETER, functionName);
    }

    /**
     * Ajax Request Execute method
     *
     * @return  void
     */
    PHP2Ajax.execute = function()
    {
        currentObject = this;

        // --- Trying to create XMLHttpRequest Object --- //
        try
        {
            this.httpRequest = this.createXMLHttp();
        }
        catch (eConnectionError)
        {
            alert('Error creating the connection to the Server!');

            return false;
        }

        // --- Making the connection and send our data --- //
        try
        {
            var requestData = "1";
            for(var i in this.parameters)
            {
                var tmpString = new String(this.parameters[i].value);
                if ((tmpString.indexOf('&') != -1) || (tmpString.indexOf('+') != -1))
                {
                    this.parameters[i].value = encodeURIComponent(tmpString);
                }

                requestData = requestData + '&'+this.parameters[i].name + '=' + this.parameters[i].value;
            }

            // --- Setting onReadyStateChange Event Handler --- //
            if (typeof(currentObject.onReadyStateChange) == 'function')
            {
                this.httpRequest.onreadystatechange = function()
                {
                    currentObject.onReadyStateChange();
                }
            }

            if (this.requestMethod == PHP2Ajax.REQUEST_METHOD_GET)
            {
                this.httpRequest.open(PHP2Ajax.REQUEST_METHOD_GET, this.server + "?" + requestData, true);
                this.httpRequest.setRequestHeader('content-type', 'text/xml');
                this.httpRequest.send('');
            }
            else
            {
                this.httpRequest.open(PHP2Ajax.REQUEST_METHOD_POST, this.server, true);
                this.httpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                this.httpRequest.send(requestData);
            }

        }
        catch (eAjaxRequestError)
        {
            alert('An error has occured calling the external site: ' + eAjaxRequestError);

            return false;
        }

    }

    /**
     * Set AJAX Request Method
     *
     * @param   string methodName
     * @return  void
     */
    PHP2Ajax.setRequestMethod = function(methodName)
    {
        if (methodName == PHP2Ajax.REQUEST_METHOD_GET)
        {
            this.requestMethod = PHP2Ajax.REQUEST_METHOD_GET;
        }
        else
        {
            this.requestMethod = PHP2Ajax.REQUEST_METHOD_POST;
        }
    }

    /**
     * Set AJAX Response Handler
     *
     * @param   function responseHandler
     * @return  void
     */
    PHP2Ajax.setHandler = function(responseHandler)
    {
        this.responseHandler = responseHandler;
    }

    /**
     * Creates XMLHttpRequest Object and
     *
     * @return  XMLHttpRequest
     */
    PHP2Ajax.createXMLHttp = function()
    {
        // --- Triyng to create Standard IE XMLHttpRequest Objects --- //
        try
        {
            httpRequest = new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch (eClassNotExistsError)
        {
            try
            {
                httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
            }
            catch (eClassNotExistsError1)
            {
                httpRequest = null;
            }
        }

        // --- Triyng to create Object of the Standard XMLHttpRequest Class (Mozilla, Safary, etc) --- //
        if ((!httpRequest) && (typeof(XMLHttpRequest) != undefined))
        {
            httpRequest = new XMLHttpRequest();
        }

        return httpRequest;
    }

    /**
     * Parameters Pair Class
     *
     * @param   string name
     * @param   string value
     * @return  void
     */
    PHP2Ajax.ParametersPair = function(name, value)
    {
      this.name   = name;
      this.value  = value;
    }


    /**
     * Simple To String Convert method.
     *
     * @return  void
     */
    PHP2Ajax.toStringSimple = function(sTracedObject, initTab)
    {
        var tracedObject = ((sTracedObject != null) ? sTracedObject : this);
        var currTab = ((initTab != null) ? initTab + '    ' : '    ');
        result = "{\n";

        for (var propertyName in tracedObject)
        {
            if (typeof(tracedObject[propertyName]) == 'string')
            {
                result += currTab + "\"" + propertyName + "\": \"" + tracedObject[propertyName] + "\",\n";
            }
            else if ((typeof(tracedObject[propertyName]) != 'function') && (typeof(tracedObject[propertyName]) == 'object'))
            {
                result += currTab + "\"" + propertyName + "\":\n" + currTab + this.toStringSimple(tracedObject[propertyName], currTab) + ",\n";
            }
        }

        result = new String(result);
        result = result.substr(0, result.length - 2) + "\n";
        result += ((initTab != null) ? initTab : '') + "}";

        return result;
    }

    /**
     * Traces Data to the End of the Document
     *
     * @return  void
     */
    PHP2Ajax.trace = function(clear)
    {
        var traceDiv = document.getElementById('mainTraceDiv');
        if (traceDiv == null)
        {
            document.body.insertAdjacentHTML("beforeEnd", '<center><div id="mainTraceDiv" style="width: 800px; background-color: #fff; text-align: left;"></div></center>');
            traceDiv = document.getElementById('mainTraceDiv');
        }

        if (clear)
        {
            traceDiv.innerHTML  = "<pre>" + PHP2Ajax.toStringSimple(this) + "</pre>";
        }
        else
        {
            traceDiv.innerHTML += "<pre>" + PHP2Ajax.toStringSimple(this) + "</pre>";
        }
    }


    // --- XMLRequest - Response Class Area --- //

    /**
     * Creates AJAX Request with XML Response
     *
     * @param   string serverUrl
     * @param   string ID
     * @return  integer
     */
    PHP2Ajax.XMLRequest = function(serverUrl, ID)
    {
        this.id               = ID;
        this.httpRequest      = null;
        this.parameters       = new Array();
        this.parametersCount  = 0;
        this.responseHandler  = null;
        this.responseXML      = null;
        this.server           = serverUrl;
        this.setRequestMethod(PHP2Ajax.REQUEST_METHOD_POST);
    }

    /**
     * Setting On Ready State Change event handler
     *
     * @param   DOMElement htmlObject
     * @return  integer
     */
    PHP2Ajax.XMLRequest.prototype.onReadyStateChange = function()
    {
        if (this.httpRequest.readyState != PHP2Ajax.READY_STATE_COMPLETE) return;

        if (this.httpRequest.status == PHP2Ajax.HTTP_STATUS_OK)
        {
            // --- Create XMLDocument Object --- //

            if (typeof(this.httpRequest.responseXML.documentElement) != undefined)
            {
                this.responseXML = this.httpRequest.responseXML.documentElement;
            }
            else
            {
                // --- Parsing XML in IE --- //
                XMLDocument = new ActiveXObject("Microsoft.XMLDOM");
                XMLDocument.loadXML(this.httpRequest.responseText);

                this.responseXML = XMLDocument.documentElement;
            }

        }
        else
        {
            alert('The server respond with a bad status code: ' + this.httpRequest.status);

            return false;
        }

        // --- Load current handler--- //
        if (typeof(this.responseHandler) == 'function') this.responseHandler();

        return this.responseXML;
    }

    /**
     * Setting On Ready State Change event handler
     *
     * @param   DOMElement htmlObject
     * @return  integer
     */
    PHP2Ajax.XMLRequest.prototype.getXML = function()
    {

    }

    /**
     * Setting On Ready State Change event handler
     *
     * @param   DOMElement htmlObject
     * @return  integer
     */
    PHP2Ajax.XMLRequest.prototype.getNodes = function(nodeName, idAttribute)
    {
        var nodeData = this.responseXML.getElementsByTagName(nodeName);

        var result = new PHP2Ajax.RResultArray();
        for (i = 0; i < nodeData.length; i++)
        {
            var currentItem = new PHP2Ajax.RResultObject();

            for (j = 0; j < nodeData[i].attributes.length; j++)
            {
                currentItem[nodeData[i].attributes[j].name] = nodeData[i].attributes[j].value;
            }

            if ((nodeData[i].firstChild != null) && (nodeData[i].firstChild.data != null))
            {
                currentItem.text = nodeData[i].firstChild.data;
            }
            else
            {
                currentItem.text = null;
            }

            if ((typeof(idAttribute) != undefined) && (idAttributeValue = nodeData[i].getAttribute(idAttribute)))
            {
                result.add(idAttributeValue, currentItem);
            }
            else
            {
                result.add(i, currentItem);
            }
        }

        return result;
    }

    /**
     * Return Node Text by Unique Node Name
     *
     * @param   string  nodeName
     * @param   DOMElement  xmlDocElement
     * @return  string
     */
    PHP2Ajax.XMLRequest.prototype.getUNodeText = function(nodeName, xmlDocElement)
    {
        nodesArray = (xmlDocElement) ? xmlDocElement : this.responseXML.getElementsByTagName(nodeName);
        if ((nodesArray != null) && (nodesArray[0] != null) && (nodesArray[0].firstChild != null) && (nodesArray[0].firstChild.data != null))
        {
            return nodesArray[0].firstChild.data;
        }
        else
        {
            return null;
        }
    }

    PHP2Ajax.XMLRequest.prototype.add               = PHP2Ajax.add;
    PHP2Ajax.XMLRequest.prototype.call              = PHP2Ajax.call;
    PHP2Ajax.XMLRequest.prototype.clear             = PHP2Ajax.clearRequest;
    PHP2Ajax.XMLRequest.prototype.trace             = PHP2Ajax.trace;
    PHP2Ajax.XMLRequest.prototype.createXMLHttp     = PHP2Ajax.createXMLHttp;
    PHP2Ajax.XMLRequest.prototype.setRequestMethod  = PHP2Ajax.setRequestMethod;
    PHP2Ajax.XMLRequest.prototype.setHandler        = PHP2Ajax.setHandler;
    PHP2Ajax.XMLRequest.prototype.execute           = PHP2Ajax.execute;


    /**
     * Creates AJAX Request with JSON Response
     *
     * @param   string serverUrl
     * @param   string ID
     * @return  integer
     */
    PHP2Ajax.JSONRequest = function(serverUrl, ID)
    {
        // --- Initializing default Parameters --- //
        this.id               = ID;
        this.httpRequest      = null;
        this.parameters       = new Array();
        this.parametersCount  = 0;
        this.responseHandler  = null;
        this.response         = null;
        this.reportAJAXErrors = true;
        this.server           = serverUrl;
        this.setRequestMethod(PHP2Ajax.REQUEST_METHOD_POST);
    }

    /**
     * Setting On Ready State Change event handler
     *
     * @return  Object
     * @since   Since v. 2.4.0 JSON Client/Server protocol was changed in accordance with JSON (rfc4627) Standard
     */
    PHP2Ajax.JSONRequest.prototype.onReadyStateChange = function()
    {
        // --- If Ready State is Not Complete - Return with Error --- //
        if (this.httpRequest.readyState != PHP2Ajax.READY_STATE_COMPLETE) return;

        if (this.httpRequest.status == PHP2Ajax.HTTP_STATUS_OK)
        {
            // --- Create JSON Object --- //
            // sJSONResponse                 = eval("(" + this.httpRequest.responseText + ")");
            // this.response                 = this.prepareJSONData(sJSONResponse);

            // --- Triyng safety Evaluate Response Data --- //
            try
            {
                this.response  = eval("(" + this.httpRequest.responseText + ")");
            }
            catch (eEvalException)
            {
                // --- Generating Response Error Event --- //
                var errorEvalData    = new String(this.httpRequest.responseText);
                this.response        = new Object();
                this.response.Error  = new Object({'Code': 1501, 'Message': ''});
                this.response.Error.Message   = "Server returns Invalid Request! Please contact to the System Administrator. \n <br /> <br /> ";
                this.response.Error.Message  += "Response trace: <div style=\"padding: 7px 3px; font-weight: normal;\">" + errorEvalData.substr(0, 4095) + ((errorEvalData.length > 4096 ) ? ' ...' : '') + "</div>";
            }

            // --- Checking Server Error --- //
            if (this.response.Error.Code > 0)
            {
                if (typeof(this.onResponseError) == 'function') this.onResponseError();

                return false;
            }

            // --- Attaching Some Trace Methods to the Responce Object --- //
            this.response.toStringSimple  = PHP2Ajax.toStringSimple;
            this.response.trace           = PHP2Ajax.trace;
        }
        else
        {
            // alert('The server respond with a bad status code: ' + this.httpRequest.status);
            if (typeof(this.onHTTPError) == 'function') this.onHTTPError();

            return false;
        }

        // --- Load current handler--- //
        if (typeof(this.responseHandler) == 'function') this.responseHandler();

        return this.response;
    }

    /**
     * On Response Error handler
     *
     * @return  void
     */
    PHP2Ajax.JSONRequest.prototype.onResponseError  = function()
    {
        this.alert = new PHP2Controls.Alert("Error: " + this.response.Error.Code + ". " + this.response.Error.Message);
    }

    /**
     * Simple To String Convert method.
     *
     * @return  void
     */
    PHP2Ajax.JSONRequest.prototype.prepareJSONData = function(sJSONObject)
    {
        var tmpJSONObject = sJSONObject;

        for (var propertyName in sJSONObject)
        {
            if (typeof(sJSONObject[propertyName]) == 'string')
            {
                tmpJSONObject[propertyName] = String(sJSONObject[propertyName]).replace(/\{\{rn\}\}/g, "\r\n");
                tmpJSONObject[propertyName] = String(tmpJSONObject[propertyName]).replace(/\{\{n\}\}/g, "\n");
            }
            else if ((typeof(sJSONObject[propertyName]) != 'function') && (typeof(sJSONObject[propertyName]) == 'object'))
            {
                tmpJSONObject[propertyName] = this.prepareJSONData(sJSONObject[propertyName]);
            }
        }

        return tmpJSONObject;
    }

    /**
     * Return Server Response AS JSON Object
     *
     * @return  Object
     */
    PHP2Ajax.JSONRequest.prototype.getResponse = function()
    {
        return this.response;
    }

    /**
     * Return Server Response AS JSON Object
     *
     * @return  Object
     */
    PHP2Ajax.JSONRequest.prototype.setPageCallBackHandler = function(callbackHandler)
    {
        this.add(PHP2Ajax.CALLBACK_HANDLER_PARAMETER, callbackHandler);
    }

    PHP2Ajax.JSONRequest.prototype.add               = PHP2Ajax.add;
    PHP2Ajax.JSONRequest.prototype.call              = PHP2Ajax.call;
    PHP2Ajax.JSONRequest.prototype.clear             = PHP2Ajax.clearRequest;
    PHP2Ajax.JSONRequest.prototype.trace             = PHP2Ajax.trace;
    PHP2Ajax.JSONRequest.prototype.createXMLHttp     = PHP2Ajax.createXMLHttp;
    PHP2Ajax.JSONRequest.prototype.setRequestMethod  = PHP2Ajax.setRequestMethod;
    PHP2Ajax.JSONRequest.prototype.setHandler        = PHP2Ajax.setHandler;
    PHP2Ajax.JSONRequest.prototype.execute           = PHP2Ajax.execute;


    // --- PHP2Ajax.RResult structures --- //

    /**
     * Result Array structure.
     *
     * @return  void
     */
    PHP2Ajax.RResultArray  = function()
    {
        this.data                 = new Array();
        // this.data.toStringSimple  = PHP2Ajax.toStringSimple;
    }
    PHP2Ajax.RResultArray.prototype.add = function(key, value)
    {
        this.data[key] = value;
    }
    PHP2Ajax.RResultArray.prototype.getData = function()
    {
        return this.data;
    }
    PHP2Ajax.RResultArray.prototype.toStringSimple = PHP2Ajax.toStringSimple;

    /**
     * Result Array Object. Used as Element of the RResultArray structure.
     *
     * @return  void
     */
    PHP2Ajax.RResultObject = function()
    {

    }
    PHP2Ajax.RResultObject.prototype.toStringSimple = PHP2Ajax.toStringSimple;

