﻿function docEl(id) {
    if (document.getElementById) {
        // send back object
        return document.getElementById(id);
    } else if (document.layers) {
        // send back object
        return document.layers[id];
    } else if (document.all)
        return document.all(id);
}
// object to check statuses on Ajax Requests
var XhrStatus = { Loading: 1, Loaded: 2, Interactive: 3, Completed: 4 };

// system to post XHR to ASP.NET
var XhrSystem = {
    CallbackUrl: null
      , AspNetForm: null
      , GetForm: function() {
          if (this.AspNetForm == null)
              this.AspNetForm = document.forms[0];
          return this.AspNetForm;
      }
    , RaiseOnError: function(errorHandle, msg) {
        if (errorHandle)
            errorHandle(msg);
        else
            alert('There was an error while processing your request.  Please try your request again, and if the problem continues, please report the error to in the contact us section.');
    },
    GetXhr: function() {
        var xhr = false;
        // Mozilla, Safari, IE 7...
        if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); }
        // IE 6
        else if (window.ActiveXObject) { try { xhr = new ActiveXObject("MSXml2.XMLHttp"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHttp"); } catch (e) { } } }
        if (!xhr) return true;
        // send back the object
        return xhr;
    },
    ProcessArgs: function(args, clientId, theAspNetForm) {
        function Param(name, value, ampersand) {
            var val = (encodeURIComponent) ? encodeURIComponent(value) : escape(value);
            return name + "=" + val + ((ampersand) ? "&" : "");
        }

        var callbackParams = '';
        // process all the forms and elements on the page
        for (var x = 0; x < theAspNetForm.elements.length; x++) {
            var element = theAspNetForm.elements[x];
            // add the parameter
            var tagName = element.tagName.toLowerCase();
            if (tagName == "input") {
                var type = element.type;
                if ((type == "text" || type == "hidden" || type == "password" ||
                ((type == "checkbox" || type == "radio") && element.checked)) &&
                (element.id != "__EVENTVALIDATION")) {
                    callbackParams += Param(element.name, element.value, true);
                }
            }
            else if (tagName == "select") {
                var selectCount = element.options.length;
                for (var j = 0; j < selectCount; j++) {
                    var selectChild = element.options[j];
                    if (selectChild.selected == true) {
                        callbackParams += Param(element.name, selectChild.value, true);
                    }
                }
            }
            else if (tagName == "textarea") {
                callbackParams += Param(element.name, element.value, true);
            }
        }

        // process the incoming JSON argument into the call
        for (var p in args) { callbackParams += Param(p, args[p], true); }

        var params = Param('__CALLBACKPARAM', callbackParams, true);
        params += Param('__CALLBACKID', clientId, true);
        params += Param('__VIEWSTATE', theAspNetForm["__VIEWSTATE"].value, true);
        if (theAspNetForm["__EVENTVALIDATION"]) { params += Param('__EVENTVALIDATION', theAspNetForm["__EVENTVALIDATION"].value); }

        return params;
    },
    ProcessControls: function(controls) {
        if (controls) {
            function setHtml(id, html) {
                var obj = docEl(id);
                if (obj)
                    try { obj.innerHTML = html; } catch (e) { alert('This HTML [' + id + '] element does not support innerHTML property'); }
            }
            function appendHtml(id, html) {
                var obj = docEl(id);
                var div = document.createElement('div');
                div.innerHTML = html;
                if (obj)
                    try { obj.innerHTML = ''; obj.appendChild(div); } catch (e) { alert('This HTML [' + id + '] element does not support innerHTML property'); }
            }

            for (var c in controls) {
                // setHtml(c, controls[c].Text);
                appendHtml(c, controls[c].Text);
            }
        }
    },
    ProcessCallback: function(xhr, callback, errorHandler) {
        if (xhr.readyState != XhrStatus.Completed)
            return;

        var response = xhr.responseText;
        var retObj = null;
        if (response.charAt(0) == "s") {
            // just a string returned
            retObj = eval(response.substring(1));
        }
        else if (response.charAt(0) == "e") {
            // handle the error
            XhrSystem.RaiseOnError(errorHandler, response.substring(1));
        }
        else {
            var theAspNetForm = XhrSystem.GetForm();
            var separatorIndex = response.indexOf("|");
            if (separatorIndex != -1) {
                var validationFieldLength = parseInt(response.substring(0, separatorIndex));
                if (!isNaN(validationFieldLength)) {
                    var validationField = response.substring(separatorIndex + 1, separatorIndex + validationFieldLength + 1);
                    if (validationField != "") {
                        var validationFieldElement = theAspNetForm["__EVENTVALIDATION"];
                        if (!validationFieldElement) {
                            validationFieldElement = document.createElement("INPUT");
                            validationFieldElement.type = "hidden";
                            validationFieldElement.name = "__EVENTVALIDATION";
                            theAspNetForm.appendChild(validationFieldElement);
                        }
                        validationFieldElement.value = validationField;
                    }
                    retObj = eval(response.substring(separatorIndex + validationFieldLength + 1));
                }
            }
        }

        if (retObj) {
            if (retObj.ServerError) {
                XhrSystem.RaiseOnError(errorHandler, retObj.ServerError);
                return;
            }
        }

        // process the control json object and updates divs when the Ids match
        XhrSystem.ProcessControls(retObj.Controls);

        if (callback) {
            callback(retObj);
        }
    },
    CallServer: function(clientId, args, xhr_callback, xhr_init, xhr_error) {
        var theAspNetForm = XhrSystem.GetForm();
        var xhr = XhrSystem.GetXhr();
        // init the request
        if (xhr.preserveWhitespace)
            xhr.preserveWhitespace = true;

        var xhrEnvelope = new XhrEnvelope(args);
        if (xhr_init != null)
            xhrEnvelope.SendRequest = xhr_init(xhrEnvelope);

        xhrEnvelope.ShowLoader();

        if (xhrEnvelope.SendRequest) {
            var params = XhrSystem.ProcessArgs(xhrEnvelope.Params, clientId, theAspNetForm);
            function xhr_stateChange() { XhrSystem.ProcessCallback(xhr, xhr_callback, xhr_error); }

            var url = (this.CallbackUrl) ? this.CallbackUrl : theAspNetForm.action;
            xhr.open('POST', url, true);
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
            xhr.setRequestHeader("Content-Length", params.length);
            xhr.onreadystatechange = xhr_stateChange;
            xhr.send(params);
        }
    }
};

function XhrEnvelope(args) {
    this.SendRequest = true;
    this.LoaderImage = 'WebResource.axd?d=GIhCanDocpYu6N5_fFtbI9JWEbQI7o9qNWRWHG-0jit8EXejvHUxKHXm-3puhSJjW3H7L9wVV9J0zRCsBFc28rhveYUsUs5y5dMXmJCI0AM1&t=633780004200000000';
    this.LoaderDivId = null;
    this.Params = (args) ? args : {};
    this.AddParameter = function(name, value) { eval('this.Params["' + name + '"] = value;'); }
    this.AddParameters = function(json) { for (var p in json) { this.AddParameter(p, eval('json["' + p + '"]')); } }
    this.ShowLoader = function(divId, img) {
        this.LoaderDivId = (divId) ? divId : this.LoaderDivId;
        this.LoaderImage = (img) ? img : this.LoaderImage;
        if (this.LoaderDivId) {
            var div = docEl(this.LoaderDivId);
            if (div) {
                div.innerHTML = '<img src="' + this.LoaderImage + '" alt="Loading..." Border="0" />';
            }
        }
    }
}
