﻿/// <reference path="global.js" />
function Request(id) {
    this.Id = null;
    if (id) {
        this.Id = id;
        $server.Requests.push(this);
    }
    this.Request = $server.CreateRequest();
    this.Preloader = new Preloader();
    this.Stop = function() {
        this.Request.onreadystatechange = function() { };
        $server.OnAbort(this);
        this.Request.abort();
    }
    this.Send = function(url, onSuccess, onError, postData, text, async) {
        this.Preloader.Begin(text);
        var req = this.Request;
        if (!req) return;
        this.Stop();
        var method = (postData) ? "POST" : "GET";
        req.open(method, url, async);
        if (req.overrideMimeType)
            req.overrideMimeType("text/plain");
        req.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
        if (postData)
            req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        //req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
        var _load = this.Preloader;
        if (postData == null)
            postData = "";
        if (!$G.IsString(postData))
            postData = $server.GetPostString(postData);
        var _toCall = function() {
            if (req.readyState != 4) { return; }
            else {
                try {
                    if (req.status != 200 && req.status != 304) {
                        _load.End(true);
                        if (onError)
                            onError(req);
                        $Server.OnError(req);
                        return;
                    }
                }
                catch (e) {
                    if (onError)
                        onError(req);
                    $Server.OnError(req);
                    return;
                }
                _load.End(false);
                if (onSuccess)
                    onSuccess(req);
                $Server.OnSuccess(req);
            }
        }
        req.onreadystatechange = _toCall;
        if (req.readyState == 4) return;
        $Server.OnStart(req);
        req.send(postData);
        _toCall();
//        if ($G.Browser.Detect.gecko) {
//            if (!async && req.onreadystatechange == null) {
//                _toCall();
//            }
//        }

    }
}
function Preloader() {
    this.Type = $server.Preloader.Type.ShowHide;
    this.Text =
    {
        BeginRequest: "",
        Success: "Success!",
        Error: "Error!"
    }
    this.Panel = null;
    this.PanelClassName = "PreloaderPanel";
    this.TextPanel = null;
    this.Begin = function(text) {
        if (this.Panel == null) {
            this.Panel = document.createElement("div");
            this.Panel.className = this.PanelClassName;
            this.TextPanel = document.createElement("div");
            $global.SetText(this.TextPanel, this.Text.BeginRequest);
            this.Panel.appendChild(this.TextPanel);
            document.body.appendChild(this.Panel);
        }
        if (this.Type == $server.Preloader.Type.SetText) {
            $global.SetText(this.TextPanel, this.Text.BeginRequest);
        }
        $global.Display.Clear(this.Panel);
        if (this.TextPanel && text)
            this.TextPanel.innerHTML = text;
    }
    this.End = function(error) {
        if (this.Type == $server.Preloader.Type.ShowHide) {
            this.Panel.style.display = "none";
        }
        else {
            if (error)
                $global.SetText(this.Panel, this.Text.Error);
            else
                $global.SetText(this.Panel, this.Text.Success);
        }
    }
}
var $server =
{
    AddOnStart: function(handler) {
        this._onStartSubscribers.push(handler);
        return this._onStartSubscribers.length;
    },
    AddOnAbort: function(handler) {
        this._onAbortSubscribers.push(handler);
        return this._onAbortSubscribers.length;
    },
    AddOnSuccess: function(handler) {
        this._onSuccessSubscribers.push(handler);
        return this._onStartSubscribers.length;
    },
    AddOnError: function(handler) {
        this._onErrorSubscribers.push(handler);
        return this._onStartSubscribers.length;
    },
    RemoveOnStart: function(obj) {
        if (typeof (obj) == 'number')
            this._onStartSubscribers.splice(obj, 1);
        else
            this._onStartSubscribers.remove(obj);
    },
    RemoveOnAbort: function(obj) {
        if (typeof (obj) == 'number')
            this._onAbortSubscribers.splice(obj, 1);
        else
            this._onAbortSubscribers.remove(obj);
    },
    RemoveOnSuccess: function(obj) {
        if (typeof (obj) == 'number')
            this._onSuccessSubscribers.splice(obj, 1);
        else
            this._onSuccessSubscribers.remove(obj);
    },
    RemoveOnError: function(obj) {
        if (typeof (obj) == 'number')
            this._onErrorSubscribers.splice(obj, 1);
        else
            this._onErrorSubscribers.remove(obj);
    },
    OnStart: function(request) {
        for (i = 0; i < this._onStartSubscribers.length; i++)
            this._onStartSubscribers[i](request);
    },
    OnSuccess: function(request) {
        for (i = 0; i < this._onSuccessSubscribers.length; i++)
            this._onSuccessSubscribers[i](request);
    },
    OnError: function(request) {
        for (i = 0; i < this._onErrorSubscribers.length; i++)
            this._onErrorSubscribers[i](request);
    },
    OnAbort: function(request) {
        for (i = 0; i < this._onAbortSubscribers.length; i++)
            this._onAbortSubscribers[i](request);
    },
    _onStartSubscribers: new Array(),
    _onSuccessSubscribers: new Array(),
    _onErrorSubscribers: new Array(),
    _onAbortSubscribers: new Array(),
    Requests: new Array(),
    Preloader: {
        Type: {
            ShowHide: "0",
            SetText: "1"
        }
    },
    InStack: function(id) {
        var res = false;
        for (var i = 0; i < this.Requests.length; i++) {
            if ((this.Requests[i].Id == id) && (this.Requests[i].Id != null)) {
                res = true;
                break;
            }
        }
        return res;
    },
    GetRequest: function(id) {
        var result = null;
        for (var i = 0; i < this.Requests.length; i++) {
            if (this.Requests[i].Id == id) {
                result = this.Requests[i];
                break;
            }
        }
        if (result == null)
            result = new Request(id);
        return result;
    },
    HttpFactories: [
        function() { return new XMLHttpRequest() },
	    function() { return new ActiveXObject("Msxml2.XMLHTTP") },
	    function() { return new ActiveXObject("Msxml3.XMLHTTP") },
	    function() { return new ActiveXObject("Microsoft.XMLHTTP") }
    ],
    CreateRequest: function() {
        var xmlhttp = false;
        for (var i = 0; i < $server.HttpFactories.length; i++) {
            try {
                xmlhttp = $server.HttpFactories[i]();
            }
            catch (e) {
                continue;
            }
            break;
        }
        return xmlhttp;
    },
    Send: function(url, success, error, postData, async, id) {
        var req = $server.GetRequest(id); //new Request(id);
        req.Preloader.Panel = $G.Tag("div");
        req.Send(url, success, error, postData, null, async);
    },
    GetPostString: function(obj) {
        var result = new String();
        result = "";
        for (var prop in obj) {
            result += prop + "=" + obj[prop] + "&";
        }
        result = result.substring(0, result.length - 1);
        return result;
    }
}
var $Server = $server;