﻿var PageMethods = new _PageMethods();

function _PageMethods() {

    function callMethod(postbackUrl, methodName, args) {
        var sig = args.callee.toString();

        var sa = sig.indexOf("(", 0) + 1;
        var ea = sig.indexOf(")", sa);
        var prms = sig.substr(sa, ea - sa).split(",");

        dirty = true;

        var data = "{";

        for (var i = 0; i < prms.length; i++) {
            if (jQuery.trim(prms[i]) == "successCallback") break;
            data += "'" + jQuery.trim(prms[i]) + "':";

            if (typeof (args[i]) == "object") {
                PageMethods.makeMsDates(args[i]);
            }

            if (typeof (args[i]) == "string") data += "'" + args[i] + "'";
            else if (typeof (args[i]) == "object") data += $.toJSON(args[i]);
            else data += args[i];

            if (jQuery.trim(prms[i + 1]) == "successCallback") break;
            if (i < prms.length - 1) data += ", ";
        }

        data += "}";

        var scb = args[args.length - 3];
        var fcb = args[args.length - 2];
        var st = args[args.length - 1];

        document.body.style.cursor = 'wait';

        //url: "idef.aspx/" + methodName,

        $.ajax({
            type: "POST",
            url: postbackUrl + methodName, //"/_cms/cmss.asmx/" + methodName,
            data: data,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            processData: false,
            success: function(data) { //value, ctx, methodName
                //debugger;
                document.body.style.cursor = 'default';

                var msg = eval(data);

                if (msg.hasOwnProperty('d'))
                    msg = msg.d;

                PageMethods.cleanMsDates(msg);

                if (typeof (scb) == 'function')
                    scb(msg, st, methodName);
                else {
                    for (var si = 0; si < scb.length; si++) {
                        var func = scb[si];
                        func(msg, st, methodName);
                    }
                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) { //ex, ctx, methodName
                //debugger;
                document.body.style.cursor = 'default';
                var err = { 'Message': (errorThrown == undefined ? textStatus : errorThrown) };

                try {
                    err = eval("(" + XMLHttpRequest.responseText + ")");
                }
                catch (e) { }

                fcb(err, st, methodName);
            }
        });
    }

    this.Call = callMethod;

    this.cleanMsDates = function(obj) {
        if ($.isArray(obj)) {
            for (var ix = 0; ix < obj.length; ix++) {
                this.cleanMsDates(obj[ix]);
            }
        }
        else {
            for (property in obj) {
                if (typeof (obj[property]) == "string") {
                    if (obj[property].indexOf("/Date(") == 0)
                        obj[property] = this.getMSAjaxDate(obj[property]);
                }
                else if (typeof (obj[property]) == "object")
                    this.cleanMsDates(obj[property]);
            }
        }
    }

    this.makeMsDates = function(obj) {
        if ($.isArray(obj)) {
            for (var ix = 0; ix < obj.length; ix++) {
                this.makeMsDates(obj[ix]);
            }
        }
        else {
            for (property in obj) {
                if (IsDateType(obj[property])) {
                    obj[property] = this.toIsoDate(obj[property]);
                }
                else if (typeof (obj[property]) == "object")
                    this.makeMsDates(obj[property]);
            }
        }
    }

    this.toIsoDate = function(dt) {
        //e.g. "2009-04-12T20:44:55"
        var retval = dt.getUTCFullYear() + "-" + this.padTo2(dt.getUTCMonth() + 1) + "-" + this.padTo2(dt.getUTCDate())
            + "T" + this.padTo2(dt.getUTCHours()) + ":" + this.padTo2(dt.getUTCMinutes()) + ":" + this.padTo2(dt.getUTCSeconds());

        return retval;
    }

    this.padTo2 = function(num) {
        var retval = num < 10 ? "0" + num.toString() : num.toString();

        return retval;
    }

    var reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/;
    var reMsAjax = /^\/Date\((d|-|.*)\)\/$/;

    this.getMSAjaxDate = function(dtString) {
        var a = reISO.exec(dtString);
        if (a)
            return new Date(Date.UTC(+a[1], +a[2] - 1,
                       +a[3], +a[4], +a[5],
                       +a[6]));
        a = reMsAjax.exec(dtString);
        if (a) {
            var b = a[1].split(/[-,.]/);
            return new Date(+b[0]);
        }
        return null;
    }

    this.ajaxClean = function(data) {
        var msg;

        if (typeof (JSON) !== 'undefined' &&
        typeof (JSON.parse) === 'function')
            msg = JSON.parse(data);
        else
            msg = eval('(' + data + ')');

        if (msg.hasOwnProperty('d'))
            return msg.d;
        else
            return msg;

    }
}
