﻿/// <reference path="global.js" />
/*
    Модуль для работы с HTTRequest-ом
*/
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);
	    if($G.Browser.Detect.gecko)
	        if(!async && req.onreadystatechange == null)
	            _toCall();
    }
}
function Preloader()
{
    this.Type = $server.Preloader.Type.ShowHide;
    this.Text = 
    {
        BeginRequest:"",
        Success:"Успешно!",
        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 = 
{
    // добавляет handler в реакцию на генерацию события 
    // семейства AddOn*
    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;
    },
    // obj это либо хэндлер функции которая 
    // добавлялась через AddOn* либо идентификатор хэндлера
    // возвращаемый фунциями семейства AddOn*
    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;
