﻿function Ajax(callBack, header) {
    this.XmlHttp = this.GetHttpObject();
    if (callBack) {
        this.OnComplete = callBack;
    }
    this.ContentType = "application/x-www-form-urlencoded";
    this.Header = header;
}

Ajax.prototype = {
    Asynchronism: true,

    GetHttpObject: function() {
        var xmlhttp;
        /*@cc_on
        @if (@_jscript_version >= 5)
        try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (E) {
                xmlhttp = false;
            }
        }
        @else
        xmlhttp = false;
        @end
        @*/
        if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
            try {
                xmlhttp = new XMLHttpRequest();
            }
            catch (e) {
                xmlhttp = false;
            }
        }
        return xmlhttp;
    },
    DoRequest: function(URL, PostData, RequestType) {
        if (this.XmlHttp) {
            if (this.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0) {
                if (!RequestType) {
                    RequestType = "get";
                }
                var oThis = this;
                var ct = this.ContentType;
                if (PostData == null || PostData == undefined) {
                    PostData = "";
                }
                if (PostData.nodeName && PostData.nodeName == "#document") {
                    ct = "text/xml";
                }
                this.XmlHttp.open(RequestType, URL, this.Asynchronism);
                this.XmlHttp.onreadystatechange = function() { oThis.ReadyStateChange(); };
                this.XmlHttp.setRequestHeader('Content-Type', ct); //application/x-www-form-urlencoded
                this.XmlHttp.setRequestHeader('Ajax', 'true');
                if (this.Header) {
                    for (var x = 0; x < this.Header.length; x++) {
                        this.XmlHttp.setRequestHeader(this.Header[x].name, this.Header[x].value);
                    }
                }
                this.XmlHttp.send(PostData);
            }
        }
    },

    AbortRequest: function() {
        if (this.XmlHttp)
            this.XmlHttp.abort();
    },

    OnLoading: function() { },
    OnLoaded: function() { },
    OnInteractive: function() { },
    OnComplete: function() { },
    OnAbort: function() { },
    OnError: function(status, statusText) { window.status = "对不起,程序运行出现错误,请刷新页面后重试!"; },

    ReadyStateChange: function() {
        if (this.XmlHttp.readyState == 1) {
            this.OnLoading();
        }
        else if (this.XmlHttp.readyState == 2) {
            this.OnLoaded();
        }
        else if (this.XmlHttp.readyState == 3) {
            this.OnInteractive();
        }
        else if (this.XmlHttp.readyState == 4) {
            if (this.XmlHttp.status == 0)
                this.OnAbort();
            else if (this.XmlHttp.status == 200 && this.XmlHttp.statusText == "OK")
                this.OnComplete(this.XmlHttp.responseText, this.XmlHttp.responseXML);
            else
                this.OnError(this.XmlHttp.status, this.XmlHttp.statusText, this.XmlHttp.responseText);
        }
    }
};

//提供一些Ajax操作的封装.
K2046.Ajax = {

    //发起一个Ajax请求
    //参数:
    //      options : object参数,包含请求相关的信息.
    //options可接受的属性:
    //      url         : string,请求的url地址.
    //      data        : string或xml文档,要传输的内容.
    //      method      : string,可为get或post.
    //      header      : Array,一个object数组,object有两个属性name和value.
    //      callback    : function,请求成功后回调的方法,回调的方法可接收到text和xml两个参数.
    Request: function(options) {
        if (!options) {
            return;
        }
        new Ajax(options.callback, options.header).DoRequest(options.url, options.data, options.method);
    }



    //发起一个Ajax请求向服务端提交数据
    //说明:服务端返回字符串必须是{success:true}/{success:false,msg:'server error!'}等json字符串.
    //参数:
    //      options : object参数,包含请求相关的信息.
    //options可接受的属性:
    //      url         : string,请求的url地址.
    //      data        : string或xml文档,要传输的内容.
    //      method      : string,可为get或post.
    //      header      : Array,一个object数组,object有两个属性name和value.
    //      callback    : function,请求成功后回调的方法,回调的方法可接收到一个text参数包含服务端返回的所有内容.
    //      success     : function,服务端返回成功后调用的方法,可接收到一个json对象.
    //      failed      : function,服务端返回失败后的回调方式,可接收到一个json对象.
    , Post: function(options) {
        options = options || {};
        if (!options.url) {
            return;
        }
        var ajax = new Ajax(function(text) {
            if (options.callback && typeof (options.callback) == "function") {
                if (options.callback(text) == false) {
                    return;
                }
            }
            var result = K2046.JsonParse(text);
            if (result.success) {
                if (options.success && typeof (options.success) == "function") {
                    options.success(result, text);
                }
            }
            else {
                if (options.failed && typeof (options.failed) == "function") {
                    options.failed(result, text);
                }
            }
        }, options.header);
        if (options.data && typeof (options.data) != 'string') {
            ajax.ContentType = "text/xml";
        }
        ajax.DoRequest(options.url, options.data, options.method);
    }

    //发起一个Ajax请求,并将返回的数据更新到指定的dom.
    //参数:
    //      element     : string/object,要更新的dom或dom的id.
    //      options     : object参数,包含请求相关的信息.
    //options可接受的属性:
    //      url         : string,请求的url地址.
    //      data        : string或xml文档,要传输的内容.
    //      method      : string,可为get或post.
    //      header      : Array,一个object数组,object有两个属性name和value.
    //      callback    : function,更新前的回调方法,接收一个参数,内容为原始的返回信息,如果想在执行callback后取消后面的操作,则callback方法应返回false.
    //      complete    : function,更新完成后的回调方法.不提供任何参数,如果callback返回false,则该方法不会被执行.
    , Update: function(element, options) {
        if (!options || !element) {
            return;
        }
        new Ajax(function(text) {
            var cp = true;
            if (options.callback && typeof (options.callback) == "function") {
                cp = options.callback(text);
            }
            if (cp != false) {
                if (options.regex) {
                    if (options.regex.test(text)) {
                        K2046.$(element).innerHTML = text.replace(options.regex, options.replace);
                    }
                }
                else {
                    K2046.$(element).innerHTML = text;
                }
                if (options.complete && typeof (options.complete) == "function") {
                    options.complete(element, text);
                }
            }
        }, options.header).DoRequest(options.url, options.data, options.method);
    }
};