﻿function AjaxRuntime(submitMethodValue, asynchronousPostbackValue) {
    this.submitMethod; this.asynchronousPostback; this.handlerFunction; this.errorHandlerFunction; if (typeof (submitMethodValue) == "string" && (trim(submitMethodValue).toUpperCase() == "GET" || trim(submitMethodValue).toUpperCase() == "")) { this.submitMethod = "GET"; }
    else if (typeof (submitMethodValue) == "string" && trim(submitMethodValue.toUpperCase()) == "POST") { this.submitMethod = "POST"; }
    else if (typeof (submitMethodValue) == "undefined") { this.submitMethod = "GET"; }
    else { displayError("No valid submit method (GET or POST) was assigned to the Ajax Runtime Object."); }
    if (typeof (asynchronousPostbackValue) == "boolean" && !asynchronousPostbackValue) { this.asynchronousPostback = false; }
    else if (typeof (asynchronousPostbackValue) == "boolean" && asynchronousPostbackValue) { this.asynchronousPostback = true; }
    else if (typeof (submitMethodValue) == "undefined") { this.asynchronousPostback = true; }
    else { displayError("Asynchronous postback property was not assigned to the Ajax Runtime Object."); }
    function displayError(errorMessage) { alert("Ajax Library Error Occurred: " + errorMessage); }
    function trim(str) {
        while (str.substring(0, 1) == " ") { str = str.substring(1, str.length); }
        while (str.substring(str.length - 1, str.length) == " ") { str = str.substring(0, str.length - 1); }
        return str;
    }
    function is_ie() { var agent = navigator.userAgent.toLowerCase(); return (agent.indexOf("msie") != -1 && agent.indexOf("opera") == -1); }
    function getFunctionName(functionObject) {
        if (functionObject && typeof (functionObject) == "function") {
            var functionName = functionObject.toString(); functionName = functionName.substring("function ".length)
            functionName = functionName.substring(0, functionName.indexOf("(")); return trim(functionName);
        }
        else { displayError("Invalid Function Object was provided."); } 
    }
    function createJSONObject(JSONString) {
        try {
            if (typeof (JSONString) == "string" && /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(JSONString)) { return eval('(' + JSONString + ')'); }
            else { return JSONString; } 
        }
        catch (e) { return JSONString; } 
    }
    function JSONStringify(arg) {
        var s = ""; if (typeof (arg) == "object") {
            var v = ""; if (arg.______array == '______array') {
                for (var i = 0; i < arg.length; ++i) {
                    v = JSONStringify(arg[i]); if (s) { s += ','; }
                    s += v;
                }
                return '[' + s + ']';
            }
            else if (typeof (arg.toString) != 'undefined') {
                for (var i in arg) {
                    v = arg[i]; if (typeof (v) != 'undefined' && typeof (v) != 'function') {
                        v = JSONStringify(v); if (s) { s += ','; }
                        s += JSONStringify(i) + ':' + v;
                    } 
                }
                if (s == "" && arg.toString() != "" && arg.toString() != "[object Object]") { s = arg.toString(); }
                return '{' + s + '}';
            } 
        }
        else if (typeof (arg) == "string") {
            var l = arg.length; s = '"'; for (i = 0; i < l; i += 1) {
                c = arg.charAt(i); if (c >= ' ') {
                    if (c == '\\' || c == '"') { s += '\\'; }
                    s += c;
                }
                else { switch (c) { case '\b': s += '\\b'; break; case '\f': s += '\\f'; break; case '\n': s += '\\n'; break; case '\r': s += '\\r'; break; case '\t': s += '\\t'; break; default: c = c.charCodeAt(); s += '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); } } 
            }
            return s + '"';
        }
        else if (typeof (arg) == "number") { return isFinite(arg) ? String(arg) : 'null'; }
        else if (typeof (arg) == "boolean") { return arg.toString(); }
        else { return null; } 
    }
    function serializeArguments(obj) {
        if (!obj) { return ""; }
        else if (typeof (obj) == "string") { return encodeURIComponent(trim(obj)); }
        else if (typeof (obj) == "number" || typeof (obj) == "boolean") { return obj.toString(); }
        else if (typeof (obj) == "object") { return encodeURIComponent(trim(JSONStringify(obj))); }
        else { displayError("Invalid object type provided as an a postback input argument."); } 
    }
    function makeServerSideCallSync(submitMethod, url, functionName, functionParameters, errorHandlerFunction) {
        var queryString = "sender=ajaxSync&method=" + encodeURIComponent(trim(functionName)) + functionParameters; var XMLHttpPostback; try { XMLHttpPostback = new XMLHttpRequest(); }
        catch (e) { displayError("XML Http Request object could not be created. Usually it means that the web browser does not support AJAX/client side postbacks."); }
        if (submitMethod == "GET") { XMLHttpPostback.open("GET", trim(url) + "?" + queryString + "&timestamp=" + new Date().getTime(), false); XMLHttpPostback.send(""); }
        else if (submitMethod == "POST") { XMLHttpPostback.open("POST", trim(url), false); XMLHttpPostback.setRequestHeader("content-type", "application/x-www-form-urlencoded"); XMLHttpPostback.setRequestHeader("content-length", queryString.length); XMLHttpPostback.setRequestHeader("pragma", "no-cache"); XMLHttpPostback.setRequestHeader("cache-control", "no-cache, no-store, must-revalidate"); XMLHttpPostback.send(queryString); }
        else { displayError("Submit method (GET or POST) was not assigned to the Ajax Method call."); }
        if (XMLHttpPostback.readyState < 4 || XMLHttpPostback.status != 200) {
            var errorMessage; if (!XMLHttpPostback.responseText) { errorMessage = "Postback to URL " + url + "?" + decodeURIComponent(queryString) + " has failed. Make sure a non-private static function \"" + trim(functionName) + "\" with a valid declaration and AjaxEnabled attribute is implemented in the code behind page. You might need to set \"ValidateRequest\" property of the web page to \"false\" in certain scenarios involving textbox controls."; }
            else { errorMessage = "Postback to URL " + url + "?" + decodeURIComponent(queryString) + " has failed. " + XMLHttpPostback.responseText; }
            if (errorHandlerFunction) {
                if (typeof (errorHandlerFunction) == "function") { setTimeout(getFunctionName(errorHandlerFunction) + "('" + errorMessage.replace(/\'/g, "\\'").replace(/\r/g, "").replace(/\n/g, " ") + "')", 0); return; }
                else { displayError("No valid error handler function has been assigned."); } 
            }
            else { displayError(errorMessage); } 
        }
        var ajaxResponse = createJSONObject(trim(XMLHttpPostback.responseText)); if (!ajaxResponse) { return "void"; }
        else if (typeof (ajaxResponse) == "object") { return ajaxResponse; }
        else if (typeof (ajaxResponse) == "string") {
            if (trim(ajaxResponse) == "") { return "void"; }
            else { return ajaxResponse; } 
        }
        else if (typeof (ajaxResponse) == "boolean" || typeof (ajaxResponse) == "number") { return ajaxResponse.toString(); }
        else { displayError("Invalid object type returned."); } 
    }; function makeServerSideCallAsync(submitMethod, url, functionName, functionParameters, handlerFunction, errorHandlerFunction) {
        if (handlerFunction && typeof (handlerFunction) != "function") { displayError("No valid handler function provided for the postback."); }
        var queryString = "sender=ajaxAsync&method=" + encodeURIComponent(trim(functionName)) + functionParameters; var XMLHttpPostback; try { XMLHttpPostback = new XMLHttpRequest(); }
        catch (e) { displayError("XML Http Request object could not be created. Usually it means that the web browser does not support AJAX/client side postbacks."); }
        XMLHttpPostback.onreadystatechange = executeAjaxCallback; if (submitMethod == "GET") { XMLHttpPostback.open("GET", trim(url) + "?" + queryString + "&timestamp=" + new Date().getTime()); XMLHttpPostback.send(""); }
        else if (submitMethod == "POST") { XMLHttpPostback.open("POST", trim(url), true); XMLHttpPostback.setRequestHeader("content-type", "application/x-www-form-urlencoded"); XMLHttpPostback.setRequestHeader("content-length", queryString.length); XMLHttpPostback.setRequestHeader("pragma", "no-cache"); XMLHttpPostback.setRequestHeader("cache-control", "no-cache, no-store, must-revalidate"); XMLHttpPostback.send(queryString); }
        else { displayError("Submit method (GET or POST) was not assigned to the Ajax Method call."); }
        function executeAjaxCallback() {
            if (XMLHttpPostback && XMLHttpPostback.readyState == 4) {
                if (XMLHttpPostback.status == 200) {
                    if (handlerFunction && typeof (handlerFunction) == "function" && handlerFunction.length == 1) {
                        var handlerFunctionName = getFunctionName(handlerFunction); var ajaxResponse = createJSONObject(trim(XMLHttpPostback.responseText)); if (!ajaxResponse) { setTimeout(handlerFunctionName + "('void')", 0); }
                        else if (typeof (ajaxResponse) == "object") { setTimeout(handlerFunctionName + "(" + XMLHttpPostback.responseText + ")", 0); }
                        else if (typeof (ajaxResponse) == "string") {
                            if (trim(ajaxResponse) == "") { setTimeout(handlerFunctionName + "('void')", 0) }
                            else { setTimeout(handlerFunctionName + "('" + ajaxResponse.replace(/\'/g, "\\'").replace(/\r/g, "").replace(/\n/g, " ") + "')", 0); } 
                        }
                        else if (typeof (ajaxResponse) == "boolean" || typeof (ajaxResponse) == "number") { setTimeout(handlerFunctionName + "('" + ajaxResponse.toString() + "')", 0); }
                        else { displayError("Invalid object type returned."); } 
                    } 
                }
                else {
                    var errorMessage; if (!XMLHttpPostback.responseText) { errorMessage = "Postback to URL " + url + "?" + decodeURIComponent(queryString) + " has failed. Make sure a non-private static function \"" + trim(functionName) + "\" with a valid declaration and AjaxEnabled attribute is implemented in the code behind page. You might need to set \"ValidateRequest\" property of the web page to \"false\" in certain scenarios involving textbox controls."; }
                    else { errorMessage = "Postback to URL " + url + "?" + decodeURIComponent(queryString) + " has failed. " + XMLHttpPostback.responseText; }
                    if (errorHandlerFunction) {
                        if (typeof (errorHandlerFunction) == "function") { setTimeout(getFunctionName(errorHandlerFunction) + "('" + errorMessage.replace(/\'/g, "\\'").replace(/\r/g, "").replace(/\n/g, " ") + "')", 0); return; }
                        else { displayError("No valid error handler function has been assigned."); } 
                    }
                    else { displayError(errorMessage); } 
                } 
            } 
        } 
    }
    function makeHttpHandlerCallSync(submitMethod, url, errorHandlerFunction) {
        var XMLHttpPostback; try { XMLHttpPostback = new XMLHttpRequest(); }
        catch (e) { displayError("XML Http Request object could not be created. Usually it means that the web browser does not support AJAX/client side postbacks."); }
        if (submitMethod == "GET") { XMLHttpPostback.open("GET", trim(url) + "?timestamp=" + new Date().getTime(), false); XMLHttpPostback.send(""); }
        else if (submitMethod == "POST") { XMLHttpPostback.open("POST", trim(url), false); XMLHttpPostback.setRequestHeader("content-type", "application/x-www-form-urlencoded"); XMLHttpPostback.setRequestHeader("content-length", 0); XMLHttpPostback.setRequestHeader("pragma", "no-cache"); XMLHttpPostback.setRequestHeader("cache-control", "no-cache, no-store, must-revalidate"); XMLHttpPostback.send(""); }
        else { displayError("Submit method (GET or POST) was not assigned to the Ajax Method call."); }
        if (XMLHttpPostback.readyState < 4 || XMLHttpPostback.status != 200) {
            var errorMessage; if (!XMLHttpPostback.responseText) { errorMessage = "Postback to URL " + url + " has failed. Make sure a non-private static function \"" + trim(functionName) + "\" with a valid declaration and AjaxEnabled attribute is implemented in the code behind page. You might need to set \"ValidateRequest\" property of the web page to \"false\" in certain scenarios involving textbox controls."; }
            else { errorMessage = "Postback to URL " + url + " has failed. " + XMLHttpPostback.responseText; }
            if (errorHandlerFunction) {
                if (typeof (errorHandlerFunction) == "function") { setTimeout(getFunctionName(errorHandlerFunction) + "('" + errorMessage.replace(/\'/g, "\\'").replace(/\r/g, "").replace(/\n/g, " ") + "')", 0); return; }
                else { displayError("No valid error handler function has been assigned."); } 
            }
            else { displayError(errorMessage); } 
        }
        var ajaxResponse = createJSONObject(trim(XMLHttpPostback.responseText)); if (!ajaxResponse) { return "void"; }
        else if (typeof (ajaxResponse) == "object") { return ajaxResponse; }
        else if (typeof (ajaxResponse) == "string") {
            if (trim(ajaxResponse) == "") { return "void"; }
            else { return ajaxResponse; } 
        }
        else if (typeof (ajaxResponse) == "boolean" || typeof (ajaxResponse) == "number") { return ajaxResponse.toString(); }
        else { displayError("Invalid object type returned."); } 
    }; function makeHttpHandlerCallAsync(submitMethod, url, handlerFunction, errorHandlerFunction) {
        if (handlerFunction && typeof (handlerFunction) != "function") { displayError("No valid handler function provided for the postback."); }
        var XMLHttpPostback; try { XMLHttpPostback = new XMLHttpRequest(); }
        catch (e) { displayError("XML Http Request object could not be created. Usually it means that the web browser does not support AJAX/client side postbacks."); }
        XMLHttpPostback.onreadystatechange = executeAjaxCallback; if (submitMethod == "GET") { XMLHttpPostback.open("GET", trim(url) + "?timestamp=" + new Date().getTime()); XMLHttpPostback.send(""); }
        else if (submitMethod == "POST") { XMLHttpPostback.open("POST", trim(url), true); XMLHttpPostback.setRequestHeader("content-type", "application/x-www-form-urlencoded"); XMLHttpPostback.setRequestHeader("content-length", 0); XMLHttpPostback.setRequestHeader("pragma", "no-cache"); XMLHttpPostback.setRequestHeader("cache-control", "no-cache, no-store, must-revalidate"); XMLHttpPostback.send(""); }
        else { displayError("Submit method (GET or POST) was not assigned to the Ajax Method call."); }
        function executeAjaxCallback() {
            if (XMLHttpPostback && XMLHttpPostback.readyState == 4) {
                if (XMLHttpPostback.status == 200) {
                    if (handlerFunction && typeof (handlerFunction) == "function" && handlerFunction.length == 1) {
                        var handlerFunctionName = getFunctionName(handlerFunction); var ajaxResponse = createJSONObject(trim(XMLHttpPostback.responseText)); if (!ajaxResponse) { setTimeout(handlerFunctionName + "('void')", 0); }
                        else if (typeof (ajaxResponse) == "object") { setTimeout(handlerFunctionName + "(" + XMLHttpPostback.responseText + ")", 0); }
                        else if (typeof (ajaxResponse) == "string") {
                            if (trim(ajaxResponse) == "") { setTimeout(handlerFunctionName + "('void')", 0) }
                            else { setTimeout(handlerFunctionName + "('" + ajaxResponse.replace(/\'/g, "\\'").replace(/\r/g, "").replace(/\n/g, " ") + "')", 0); } 
                        }
                        else if (typeof (ajaxResponse) == "boolean" || typeof (ajaxResponse) == "number") { setTimeout(handlerFunctionName + "('" + ajaxResponse.toString() + "')", 0); }
                        else { displayError("Invalid object type returned."); } 
                    } 
                }
                else {
                    var errorMessage; if (!XMLHttpPostback.responseText) { errorMessage = "Postback to URL " + url + " has failed. Make sure a non-private static function \"" + trim(functionName) + "\" with a valid declaration and AjaxEnabled attribute is implemented in the code behind page. You might need to set \"ValidateRequest\" property of the web page to \"false\" in certain scenarios involving textbox controls."; }
                    else { errorMessage = "Postback to URL " + url + " has failed. " + XMLHttpPostback.responseText; }
                    if (errorHandlerFunction) {
                        if (typeof (errorHandlerFunction) == "function") { setTimeout(getFunctionName(errorHandlerFunction) + "('" + errorMessage.replace(/\'/g, "\\'").replace(/\r/g, "").replace(/\n/g, " ") + "')", 0); return; }
                        else { displayError("No valid error handler function has been assigned."); } 
                    }
                    else { displayError(errorMessage); } 
                } 
            } 
        } 
    }
    this.doClientSidePostback = function(functionName) {
        var url = document.location.href; if (url.indexOf("?") > 0) { url = url.substring(0, url.indexOf("?")) }
        else if (url.indexOf("#") > 0) { url = url.substring(0, url.indexOf("#")) }
        if (!url || trim(url) == "") { displayError("Postback Url is undefined."); }
        if (!functionName || trim(functionName) == "") { displayError("Invalid Function Name provided."); }
        var functionParameters = ""; if (arguments.length > 0) { for (var i = 1; i < arguments.length; i++) { if (arguments[i] != null && typeof (arguments[i]) != "undefined") { functionParameters += "&arg" + i + "=" + serializeArguments(arguments[i]); } } }
        if (this.asynchronousPostback) { makeServerSideCallAsync(this.submitMethod, url, functionName, functionParameters, this.handlerFunction, this.errorHandlerFunction); }
        else { return makeServerSideCallSync(this.submitMethod, url, functionName, functionParameters, this.errorHandlerFunction); } 
    }
    this.doClientSidePostbackToPage = function(functionName, pageUrl) {
        var newUrl = ""; try {
            if (document.location.href.indexOf("?") > 0) { newUrl = trim(document.location.href.substring(0, document.location.href.indexOf("?") + 1)); newUrl = trim(newUrl.substring(0, newUrl.lastIndexOf("/") + 1)); }
            else { newUrl = trim(document.location.href.substring(0, document.location.href.lastIndexOf("/") + 1)); } 
        }
        catch (e) { displayError("Invalid Page Url is provided."); }
        if (trim(newUrl) == "" || newUrl.indexOf("/") <= 0 || newUrl.indexOf("http") != 0) { displayError("Invalid Page Url is provided."); }
        if (!pageUrl || trim(pageUrl) == "") { displayError("Invalid Page Url is provided."); }
        var url = newUrl + trim(pageUrl); if (url.indexOf("?") > 0) { url = url.substring(0, url.indexOf("?")) }
        else if (url.indexOf("#") > 0) { url = url.substring(0, url.indexOf("#")) }
        if (!url || trim(url) == "") { displayError("Postback Url is undefined."); }
        if (!functionName || trim(functionName) == "") { displayError("Invalid Function Name provided."); }
        var functionParameters = ""; if (arguments.length > 1) { for (var i = 2; i < arguments.length; i++) { if (arguments[i] != null && typeof (arguments[i]) != "undefined") { functionParameters += "&arg" + (i - 1) + "=" + serializeArguments(arguments[i]); } } }
        if (this.asynchronousPostback) { makeServerSideCallAsync(this.submitMethod, url, functionName, functionParameters, this.handlerFunction, this.errorHandlerFunction); }
        else { return makeServerSideCallSync(this.submitMethod, url, functionName, functionParameters, this.errorHandlerFunction); } 
    }
    this.doClientSidePostbackToHttpHandler = function(pageUrl) {
        var newUrl = ""; try {
            if (document.location.href.indexOf("?") > 0) { newUrl = trim(document.location.href.substring(0, document.location.href.indexOf("?") + 1)); newUrl = trim(newUrl.substring(0, newUrl.lastIndexOf("/") + 1)); }
            else { newUrl = trim(document.location.href.substring(0, document.location.href.lastIndexOf("/") + 1)); } 
        }
        catch (e) { displayError("Invalid Page Url is provided."); }
        if (trim(newUrl) == "" || newUrl.indexOf("/") <= 0 || newUrl.indexOf("http") != 0) { displayError("Invalid Page Url is provided."); }
        if (!pageUrl || trim(pageUrl) == "") { displayError("Invalid Page Url is provided."); }
        var url = newUrl + trim(pageUrl); if (url.indexOf("#") > 0) { url = url.substring(0, url.indexOf("#")) }
        if (!url || trim(url) == "") { displayError("Postback Url is undefined."); }
        if (this.asynchronousPostback) { makeHttpHandlerCallAsync(this.submitMethod, url, this.handlerFunction, this.errorHandlerFunction); }
        else { return makeHttpHandlerCallSync(this.submitMethod, url, this.errorHandlerFunction); } 
    }
    this.serializeDate = function(dateToSerialize) {
        if (!dateToSerialize) { return undefined; }
        dateToSerialize.setTimezoneOffset(3000); return "/Date(" + Date.UTC(dateToSerialize.getFullYear(), dateToSerialize.getMonth(), dateToSerialize.getDay(), dateToSerialize.getHours(), dateToSerialize.getMinutes(), dateToSerialize.getSeconds(), dateToSerialize.getMilliseconds()) + ")/";
    }
    this.deserializeDate = function(dateString) {
        if (!dateString) { return undefined; }
        return eval('(' + dateString.replace(new RegExp('\\/Date\\((.*)\\)\\/', 'g'), "new Date($1)") + ')');
    } 
}