﻿/// <reference path="global.js" />
/// <reference path="effects.js" />
/*************************************************
*												 *
*		Модуль всевозможных UI Элементов         *
*												 *
*		Дата:				Автор:               *
*		02.11.2007			Агроник А.Ю.         *
*											   	 *
*                                                *
*	    Внимание! данный файл является           *
*	    частью программного продукта SCSC        *
*       и не поставляется отдельно. Права        *
*       на программный продукт SCSC              *
*       принадлежат компании A2 www.a2soft.ru    *
*											   	 *
*************************************************/

$UI = {
    _old: null,
    _resOld: null,
    Resize:
	{
	    _bodyClassName: "",
	    Init: function()
	    {
	    },
	    Current: null,
	    OnChange: function() { }
	},
    Wheel:
    {
        _handlers: {},
        Register: function(obj, formal, func, prevent)
        {
            $UI.Wheel._handlers[formal] = { obj: obj, func: func, prevent: prevent };
        },
        UnRegister: function(formal)
        {
            $UI.Wheel._handlers[formal] = null;
        },
        Process: function(event)
        {
            var delta = 0;
            var event = event ? event : window.event;
            var obj = $G.Event.Target(event);
            obj = obj.tagName ? obj : obj.parentNode;
            if (event.wheelDelta)
            {
                delta = event.wheelDelta / 120;
                if (window.opera) delta = -delta;
            } else if (event.detail)
            {
                delta = -event.detail / 3;
            }
            var prevent = false;
            if (delta)
            {
                for (var i in $UI.Wheel._handlers)
                {
                    if ($UI.Wheel._handlers[i] != null)
                    {
                        if ($G.IsChildOf($UI.Wheel._handlers[i].obj, obj, 5) || $UI.Wheel._handlers[i].obj == obj)
                        {
                            $UI.Wheel._handlers[i].func(delta);
                            prevent = prevent || $UI.Wheel._handlers[i].prevent;
                        }
                    }
                }
            }
            if (prevent)
            {
                if (event.preventDefault)
                    event.preventDefault();
                event.returnValue = false;
            }
        },
        Invoke: function()
        {
        },
        Init: function()
        {
            if (window.addEventListener)
                window.addEventListener('DOMMouseScroll', $UI.Wheel.Process, false);
            window.onmousewheel = document.onmousewheel = $UI.Wheel.Process;
        }
    },
    Hotkey:
	{
	    Keys:
		{
		    Ctrl: 17,
		    Alt: 18,
		    Space: 32,
		    Shift: 16,
		    CapsLock: 20,
		    Tab: 9,
		    Esc: 27,
		    Enter: 13,
		    ArrowLeft: 37,
		    ArrowRight: 39,
		    ArrowUp: 38,
		    ArrowDown: 40
		},
	    Pressed: new Array(),
	    Combinations: new Array(),
	    _old: null,
	    _oldU: null,
	    Init: function()
	    {
	        var keys = "0123456789abcdefghijklmnopqrstuvwxyz";
	        var codes = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90];
	        for (var k = 0; k < keys.length; k++)
	            $UI.Hotkey.Keys[keys.charAt(k).toUpperCase()] = codes[k];
	        codes = keys = null;
	        this._old = $G.Browser.Detect.gecko ? window.onkeydown : document.body.onkeydown;
	        if ($G.Browser.Detect.gecko)
	            window.onkeydown = $UI.Hotkey.Process.bind(this);
	        else
	            document.body.onkeydown = $UI.Hotkey.Process.bind(this);
	        var _oldU = $G.Browser.Detect.gecko ? window.onkeyup : document.body.onkeyup;
	        this._oldU = _oldU;
	        if ($G.Browser.Detect.gecko)
	            window.onkeyup = $UI.Hotkey.Clear.bind(this);
	        else
	            document.body.onkeyup = $UI.Hotkey.Clear.bind(this);
	        if ($G.Browser.Detect.ie)
	            try { document.execCommand("BackgroundImageCache", false, true); } catch (e) { };
	    },
	    UnRegister: function(keys, uid)
	    {
	        var array = new Array();
	        for (var i = 0; i < this.Combinations.length; i++)
	            if (!this.Compare(this.Combinations[i].keys, keys) && (uid != null ? (this.Combinations[i].uid != uid) : true))
	            array.push(this.Combinations[i]);
	        this.Combinations = array;
	    },
	    Register: function(keys, func, uid)
	    {
	        this.UnRegister(keys, uid);
	        this.Combinations.push({ keys: keys, func: func, uid: uid });
	        return func;
	    },
	    Clear: function(e)
	    {
	        this.Pressed = new Array();
	    },
	    Compare: function(val1, val2)
	    {
	        if (val1.length == val2.length)
	        {
	            var res = true;
	            for (var i = 0; i < val1.length; i++)
	                res = res && (val1[i] == val2[i]);
	            return res;
	        }
	        return false;
	    },
	    GetFuncs: function(keys)
	    {
	        var result = new Array();
	        for (var i = 0; i < this.Combinations.length; i++)
	            if (this.Compare(this.Combinations[i].keys, keys))
	            result.push(this.Combinations[i].func);
	        return result;
	    },
	    Invoke: function(functions)
	    {
	        for (var i = 0; i < functions.length; i++)
	            functions[i]();
	        return functions.length == 0;
	    },
	    Process: function(e)
	    {
	        if (this._old)
	            this._old(e);
	        var _code = $G.GetKeyCode(e);
	        this.Pressed.push(_code);
	        return this.Invoke(this.GetFuncs(this.Pressed));
	    }
	},
    Move:
	{
	    _ieStop: function()
	    {
	    },
	    Init: function()
	    {
	        var _ad = document.onmousedown;
	        document.onmousedown = function(e)
	        {
	            if (_ad)
	                _ad(e);
	            $UI.Move.Start(e);
	        }
	        var _au = document.onmouseup;
	        document.onmouseup = function(e)
	        {
	            if (_au)
	                _au(e);
	            $UI.Move.Stop(e);
	        }
	        var _am = document.onmousemove;
	        document.onmousemove = function(e)
	        {
	            if (_am)
	                _am(e);
	            $UI.Move.Move(e);
	        }
	        return;
	    },
	    Current: null,
	    Drags: new Array(),
	    GetDragByObject: function(obj)
	    {
	        var result = null;
	        for (var i = 0; i < this.Drags.length; i++)
	            if ((this.Drags[i].Parent.Holder == obj) && (_UIDrag.prototype.isPrototypeOf(this.Drags[i])))
	            return this.Drags[i];

	        return result;
	    },
	    GetByObject: function(obj)
	    {
	        var result = new Array();
	        for (var i = 0; i < this.Drags.length; i++)
	            if (this.Drags[i].Parent.Holder == obj)
	            result.push(this.Drags[i]);

	        return result;
	    },
	    HighestDepth: function()
	    {
	        var record = 0;
	        for (var i = 0; i < this.Drags.length; i++)
	        {
	            var d = this.GetDepth(this.Drags[i]);
	            record = record < d ? d : record;
	        }
	        return record || 1;
	    },
	    OrganizeDialogs: function(modal)
	    {
	        for (var i = 0; i < this.Drags.length; i++)
	        {
	            var drag = this.Drags[i];
	            if (drag.Parent && drag.Parent.DeActivate)
	            {
	                if (drag.Parent.HasModal && drag.Parent.HasModal(modal))
	                    drag.Parent.DeActivate();
	            }
	        }
	        var max = $UI.Move.GetHighest();
	        if (max && max.Parent && max.Parent.Activate)
	            max.Parent.Activate();
	    },
	    GetHighest: function()
	    {
	        var record = 0;
	        var result = null;
	        for (var i = 0; i < this.Drags.length; i++)
	        {
	            var d = this.GetDepth(this.Drags[i]);
	            result = record < d ? this.Drags[i] : result;
	            record = record < d ? d : record;
	        }
	        return result;
	    },
	    GetWithUpLimit: function(limit)
	    {
	        var record = 0;
	        var result = null;
	        for (var i = 0; i < this.Drags.length; i++)
	        {
	            var d = this.GetDepth(this.Drags[i]);
	            result = ((record < d) && (limit > d)) ? this.Drags[i] : result;
	            record = ((record < d) && (limit > d)) < d ? d : record;
	        }
	        return result;
	    },
	    SetDepth: function(drag, depth)
	    {
	        drag.Holder.style.zIndex = depth;
	        
	        if (drag.IeFrame)
	            drag.IeFrame.style.zIndex = (depth - 1);
	            
	        for (var i = 0; i < this.Drags.length; i++)
	        {
	            var d = this.GetDepth(this.Drags[i]);
	            if ((d == depth) && (this.Drags[i].Parent.Holder != drag.Holder))
	                this.SetDepth(this.Drags[i].Parent, depth - 1);
	        }
	    },
	    GetDepth: function(drag)
	    {
	        var d = $G.GetStyle(drag.Parent.Holder, "zIndex", true);
	        if (d == 0)
	        {
	            try
	            {
	                d = Number(drag.Parent.Holder.style.zIndex);
	            }
	            catch (e) { }
	        }
	        return d;
	    },
	    In: function(drag)
	    {
	        var res = false;
	        for (var i = 0; i < this.Drags.length; i++)
	        {
	            res = res || (this.Drags[i].Holder == drag.Holder);
	        }
	        return res;
	    },
	    Add: function(drag)
	    {
	        if (!this.In(drag))
	            this.Drags.push(drag);
	        return;
	    },
	    _ss: function() { },
	    _operaTimeOut: null,
	    Start: function(e)
	    {
	        var e = e ? e : event;
	        var obj = e.target ? e.target : e.srcElement;
	        var drag = (this.Get(obj) || this.Get(obj.parentNode));
	        if (drag != null)
	        {
	            drag.Start();
	            this.Current = drag;
	        }
	        return false;
	    },
	    Stop: function(e)
	    {
	        if (this.Current != null)
	        {
	            if (this.Current.Stop)
	                this.Current.Stop(this.Current);
	            this.Current = null;
	        }
	        return false;
	    },
	    Move: function()
	    {
	        if (this.Current != null)
	        {
	            this.Current.Process();
	        }

	    },
	    Get: function(obj)
	    {
	        var result = null;
	        for (var i = 0; i < this.Drags.length; i++)
	            if (this.Drags[i].Holder == obj)
	        {
	            result = this.Drags[i];
	            break;
	        }
	        return result;
	    },
	    Remove: function(obj)
	    {
	        var tmp = new Array();
	        for (var i = 0; i < this.Drags.length; i++)
	            if (this.Drags[i].Holder != obj)
	            tmp.push(this.Drags[i]);
	        this.Drags = tmp;
	        return this;
	    }
	},
    Body: new UIControl(),
    TopFixedPanel: null,
    Content: null,
    Styles: null,
    Init: function()
    {
        //Инициализация модулей UI
        $UI.Move.Init();
        $UI.Hotkey.Init();
        this.Body.Content = this.Body.Holder = document.body;
        //$UI.Resize.Init();
        $UI.Wheel.Init();
    }
}
$UI._old = window.onload;
window.onload = function()
{
    if ($UI._old)
        $UI._old();
    $UI.Init();
}

function UIControl(_holder, _content)
{
    this._defaultClassName = new String();
    this._operafix = $G.Tag("input");
    this.Parent = null;
    this.Controls = new Array();
    this.FromArguments = function(_holder, _content)
    {
        this.Holder = _holder;
        this.Content = _content ? _content : _holder;
    }
    this.FromArguments(_holder, _content);
    this.SetText = function(text)
    {
        if (this.Content.value != null)
            this.Content.value = text;
        else
            this.Content.innerHTML = text;
        return this;
    }
    this.GetText = function()
    {
        if (this.Content.value != null)
            return this.Content.value;
        return this.Content.innerHTML;
    }
    this.AddControl = function(control, anchor, before, noinit)
    {
        if (!UIControl.prototype.isPrototypeOf(control) && control.tagName != null)
            control = new A2.UI.Control(control);

        if (this.Controls.contains(control) && control.Parent && control.Parent.Content != this.Content)
            this.Controls.remove(control); // Отслеживаем ситуацию с возвращением контрола в иерархию данного
            
        if (!this.Controls.contains(control))
        {
            if (!UIControl.prototype.isPrototypeOf(control))
                return $G.Append(this.Content, control);
            this.Controls.push(control);
            control.Parent = this;
            //Event-flow ;)
            if (control.OnInit && !noinit)
                control.OnInit();
            if (control.Visualize)
                control.Visualize(anchor, before);
            if (control.OnLoad && !noinit)
                control.OnLoad();
            if (this.OnChildAdded)
                this.OnChildAdded(control);
            return control;
        }
    }
    this.AddControls = function(array)
    {
        for (var i in array)
            this.AddControl(array[i]);
    }
    this.OnLoad = function() { }; // Срабатывает при загрузке
    this.OnUnload = function() { }; // Срабатывает при выгрузке	
    this.OnInit = function() { };
    this.OnResize = function() { };
    this.OnChildAdded = function() { }; // Срабатывает, если добавить контрол в данный контрол
    this.OnClearControls = function() { }; // Срабатывает, если вызвать метод ClearControls после того, как очистить коллекцию контролов
    this._onMoveStart = function()
    {
        for (var i = 0; i < this.Controls.length; i++)
            this.Controls[i]._onMoveStart.bind(this.Controls[i])();
        this.OnMoveStart();
    }
    this.OnMoveStart = function() { };
    this.Resize = function(size)
    {
        var _size;
        if (size == null)
            _size = new _UISize(this.Content.offsetWidth, this.Content.offsetHeight);
        else
            _size = new _UISize((this.Content.offsetWidth != 0 ? this.Content.offsetWidth : size.Width)
	                         , (this.Content.offsetHeight != 0 ? this.Content.offsetHeight : size.Height));
        this.OnResize(_size);
        for (var i = 0; i < this.Controls.length; i++)
            this.Controls[i].Resize.bind(this.Controls[i])(_size);
    }
    this.Visualize = function(anchor, before)
    {
        if (this.Parent)
            $G.Append(this.Parent.Content, this.Holder, anchor, before);
        else
            $G.Append(document.body, this.Holder, anchor, before);
    }
    this.GetControlByObject = function(obj)
    {
        for (var i = 0; i < this.Controls.length; i++)
        {
            if (this.Controls[i].Holder == obj)
                return this.Controls[i];
        }
        return null;
    }
    this.GetControlsByObject = function()
    {
        var result = new Array();
        for (var i = 0; i < this.Content.childNodes.length; i++)
        {
            var ctrl = this.GetControlByObject(this.Content.childNodes[i]);
            if (ctrl)
            {
                result.push(ctrl);
            }
        }
        return result;
    }
    this.GetControl = function(obj)
    {
        var result = null;
        for (var i = 0; i < this.Controls.length; i++)
        {
            if (this.Controls[i] == obj)
            {
                result = this.Controls[i];
                break;
            }
        }
        return result;
    }
    this.RemoveControl = function(control)
    {
        this.Controls.remove(control);
        control.OnUnload();
        control.Dispose();
    }
    this.ClearControls = function()
    {
        while (this.Controls.length > 0)
        {
            this.RemoveControl(this.Controls[0]);
        }
        this.Controls = new Array();

        if (this.OnClearControls)
            this.OnClearControls();
    }
    this.ParentDeleted = function()
    {
        this.OnParentDeleted();
        for (var i = 0; i < this.Controls.length; i++)
        {
            this.Controls[i].ParentDeleted();
        }
    }
    this.OnParentDeleted = function() { };
    this.Dispose = function()
    {
        this.Holder.style.display = "none";
        for (var i = 0; i < this.Controls.length; i++)
            this.Controls[i].ParentDeleted();
        if (this.Holder.parentNode != null)
            this.Holder.parentNode.removeChild(this.Holder);
    }
    this.SetClass = function(className)
    {
        this.Holder.className = this._defaultClassName + " " + className;
        return this;
    }
    this.RemoveClassName = function(className)
    {
        this.Holder.className = this.Holder.className.replace(className, "");
    }
    this.Visible = function(st)
    {
        this.Holder.style.display = st;
        return this;
    }
    this.AddEvent = function(type, func)
    {
        $G.Event.Add(this.Holder, type, func);
        return this;
    }
    this.ContainsElement = function(elem)
    {
        var res = false;
        var elems1 = this.Holder.childNodes;
        var elems2 = this.Content.childNodes;
        for (var i = 0; i < elems1.length; i++)
        {
            if (elem == elems1[i])
            {
                res = true;
                break;
            }
        }
        for (var i = 0; i < elems2.length; i++)
        {
            if (elem == elems2[i])
            {
                res = true;
                break;
            }
        }
        if (!res)
        {
            for (var i = 0; i < this.Controls.length; i++)
            {
                res = this.Controls[i].ContainsElement(elem);
                if (res)
                    break;
            }
        }
        return res;
    }
}
function UISystemControl(_holder, _content)
{
    this.Controls = new Array();
    this.FromArguments(_holder, _content);
    this.Visualize = function()
    {
        if (this.Parent)
            this.Parent.Holder.appendChild(this.Holder);
        else
            document.body.appendChild(this.Holder);
    }
}
UISystemControl.prototype = new UIControl();
function UIFixed(top, right, bottom, left)
{
    this.OnInit = function()
    {
        if (this.Content)
            this.Content.className += (this.Content.className.indexOf("fixed") == -1) ? " fixed" : ""
    }
    this.SetPosition = function(_top, _right, _bottom, _left)
    {
        this.Holder.style.top = (_top != null) ? _top + "px" : "";
        this.Holder.style.bottom = (_bottom != null) ? _bottom + "px" : "";
        this.Holder.style.left = (_left != null) ? _left + "px" : "";
        this.Holder.style.right = (_right != null) ? _right + "px" : "";
    }
}
UIFixed.prototype = new UIControl();
function UIMove(_obj, _subj, onStart, onEnd, onMove)
{
    this.Subject = _subj;
    this.OnStart = onStart;
    this.OnEnd = onEnd;
    this.OnMove = onMove;

    this.InitX = 0;
    this.InitY = 0;
    this.Bounds = new UIBounds();
    this.Init = function()
    {
        $UI.Move.Add(this);
    }
    this.Fixed = false;
}
UIMove.prototype = new UISystemControl();
function _UIDrag()
{
    this.LockH = false;
    this.LockV = false;
    this.Process = function()
    {
        if (!this.Fixed)
        {
            var px = (Number($G.Mouse.X) - this.InitX);
            var py = (Number($G.Mouse.Y) - this.InitY);
            if (!this.LockV && this.Parent.DragBounds.InY(py + this.Parent.Holder.offsetHeight) && this.Parent.DragBounds.InY(py))
                this.Parent.Holder.style.top = py + "px";
            if (!this.LockH && this.Parent.DragBounds.InX(px + this.Parent.Holder.offsetWidth) && this.Parent.DragBounds.InX(px))
                this.Parent.Holder.style.left = px + "px";
            if (this.OnMove)
                this.OnMove(this, px, py);
            if ($G.Browser.Detect.opera)
                this._operafix.focus();
        }

    }
    this.Start = function()
    {
        if (!this.Fixed)
        {
            $G.Selection.Disable(document.body);
            var b = $G.GetTopLeft(this.Parent.Holder);
            if (this.Parent.Holder.className.indexOf("fixed") != -1)
            {
                b.x = $G.GetStyle(this.Parent.Holder, "left", true);
                b.y = $G.GetStyle(this.Parent.Holder, "top", true);
            }
            this.InitX = Number($G.Mouse.X) - b.x;
            this.InitY = Number($G.Mouse.Y) - b.y;
            if (this.OnStart)
                this.OnStart(this);
        }
    }
    this.Stop = function()
    {
        if (!this.Fixed)
        {
            $G.Selection.Enable(document.body);
            if (this.OnStop)
                this.OnStop(this);
        }
    }
    this._Init = function()
    {
        var _d = this.Parent;
        var _c = this.Parent.Holder.onmousedown;
        _d.Holder.onmousedown = function(e)
        {
            if (_c)
                _c(e);
            if ((_d.HasModal && !_d.HasModal($UI.Move.GetHighest().Parent)) || !_d.HasModal)
            {
                $UI.Move.SetDepth(_d, $UI.Move.HighestDepth());
            }
        }
        this.Init();
        $UI.Move.SetDepth(_d, $UI.Move.HighestDepth() + 1);
    }
    var _oldLoad = this.OnLoad.bind(this);
    this.OnLoad = function()
    {
        _oldLoad(arguments);
        this._Init();
    }
}
_UIDrag.prototype = new UIMove();
function _UIResize(inversX, inversY)
{
    this.InversX = inversX != null ? inversX : false;
    this.InversY = inversY != null ? inversY : false;
    this.InitW = 0;
    this.InitH = 0;
    this.InitOX = 0;
    this.InitOY = 0;
    this.LockH = false;
    this.LockV = false;
    this.Process = function()
    {
        if (!this.Fixed)
        {
            var dmx = (Number($G.Mouse.X) - this.InitX);
            var dmy = (Number($G.Mouse.Y) - this.InitY);
            var py = (this.InitH + dmy * (this.InversY ? -1 : 1));
            var px = (this.InitW + dmx * (this.InversX ? -1 : 1));
            var lx = Number($G.Mouse.X) - this.InitOX;
            var ly = Number($G.Mouse.Y) - this.InitOY;
            if ($G.Browser.Detect.opera)
                this.Parent.Holder.style.display = "none";
            if (!this.LockV && this.Parent.ResizeBounds.InY(py))
            {
                this.Parent.Holder.style.height = py + "px";
                if (this.InversY)
                    this.Parent.Holder.style.top = ly + "px";
            }
            if (!this.LockH && this.Parent.ResizeBounds.InX(px))
            {
                this.Parent.Holder.style.width = px + "px";
                if (this.InversX)
                    this.Parent.Holder.style.left = lx + "px";
            }
            if ($G.Browser.Detect.opera)
                this.Parent.Holder.style.display = "block";
            if (this.OnMove)
                this.Current.OnMove(this);
            if ($G.Browser.Detect.opera)
                this._operafix.focus();
            if (this.Parent.Resize)
                this.Parent.Resize();
        }
    }
    this.Start = function()
    {
        if (!this.Fixed)
        {
            document.body.onselectstart = function() { return false; };
            window.onselectstart = function() { return false; };
            this.InitX = Number($G.Mouse.X);
            this.InitY = Number($G.Mouse.Y);
            if (this.InversX || this.InversY)
            {
                var b = $G.GetTopLeft(this.Parent.Holder);
                if (this.Parent.Holder.className.indexOf("fixed") != -1)
                {
                    b.x = $G.GetStyle(this.Parent.Holder, "left", true);
                    b.y = $G.GetStyle(this.Parent.Holder, "top", true);
                }
                if (this.InversX)
                    this.InitOX = this.InitX - b.x;
                if (this.InversY)
                    this.InitOY = this.InitY - b.y;
            }
            this.InitW = Number($G.GetStyle(this.Parent.Holder, "width", true));
            this.InitH = Number($G.GetStyle(this.Parent.Holder, "height", true));
            if (this.OnStart)
                this.OnStart(this);
        }
    }
    this.OnStop = function() { };
    this.Stop = function()
    {
        if (!this.Fixed)
        {
            document.body.onselectstart = function() { };
            window.onselectstart = function() { };
            if (this.OnStop)
                this.OnStop(this);
        }
    }
    this.OnLoad = function()
    {
        this.Init();
    }
}
_UIResize.prototype = new UIMove();
function UILinkButton(text)
{
    this._defaultClassName = "UILinkButton";
    this.Holder = $G.Tag("a");
    this.Content = this.Holder;
    this.Content.href = "javascript:void(0)";
    this.SetText = function(text)
    {
        this.Content.innerHTML = text;
    }
    if (text)
        this.SetText(text);
}
UILinkButton.prototype = new UIControl();
function UIIconButton(text, icon, onclick)
{
    this.Holder = $G.Tag("span");
    this.Icon = $G.Append(this.Holder, $G.Tag("img"));
    this.Content = $G.Append(this.Holder, $G.Tag("a", "btn", { href: "javascript:void(0)" }));
    this.SetIcon = function(img, w, h)
    {
        if ($G.isString(img))
        {
            if ((img.indexOf(".png") != -1) && ($G.Browser.Detect.ie))
            {
                var _img = new Image();
                _img.src = img;
                this.Icon.style.width = (w || _img.width) + "px";
                this.Icon.style.height = (h || _img.height) + "px";
                this.Icon.style.background = "url(resource/px.gif) repeat left top";
                this.Icon.src = "resource/px.gif";
                this.Icon.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img + "', SizingMethod='scale')";
            }
            else
                this.Icon.src = img;
        }
    }
    this.GetIcon = function()
    {
        if (this.Icon.src.indexOf("px.gif") != -1)
        {
            if (this.Icon.style.backgroundImage.indexOf("px.gif") != -1)
                return this.Icon.style.filter.replace("progid:DXImageTransform.Microsoft.AlphaImageLoader(src='", "").replace("', SizingMethod='scale')", "");
            else
                return this.Icon.style.backgroundImage.replace("url(", "").replace(")", "");
        }
        else
            return this.Icon.src;
    }
    var _baseSetText = this.SetText.bind(this);
    this.SetText = function(text)
    {
        _baseSetText(text);
        this.Icon.alt = text;
    }
    this.SetIcon("resource/px.gif");
    if (text)
        this.SetText(text);
    if (icon)
    {
        if ($G.isString(icon))
            this.SetIcon(icon);
        else
            this.SetIcon(icon.src, icon.w, icon.h);
    }
    if (onclick)
        $G.Event.Add(this, "click", onclick.bind(this));
    this.SetClass("");
}
UIIconButton.prototype = new UILinkButton();
function UIBounds(minx, miny, maxx, maxy)
{
    this.MinX = minx ? minx : 0;
    this.MinY = miny ? miny : 0;
    this.MaxX = maxx ? maxx : 0;
    this.MaxY = maxy ? maxy : 0;
    this.In = function(point)
    {
        return this.InX(point.x) && this.InY(point.y);
    }
    this.Undef = function()
    {
        return this.UndefX() || this.UndefY();
    }
    this.UndefX = function()
    {
        return (this.MinX == this.MaxX);
    }
    this.UndefY = function()
    {
        return (this.MinY == this.MaxY);
    }
    this.InX = function(x)
    {
        return this.UndefX() || ((x > this.MinX) && (x < this.MaxX));
    }
    this.InY = function(y)
    {
        return this.UndefY() || ((y > this.MinY) && (y < this.MaxY));
    }
}
function UIDialogDragBounds()
{
}
function UIDialogResizeBounds()
{
}
function UIDialogResizeBoundsH()
{
}
function UIDialogResizeBoundsV()
{
}
UIDialogDragBounds.prototype = new UIBounds(6, 0, 9999, 9999);
UIDialogResizeBounds.prototype = new UIBounds(50, 50, 9999, 9999);
UIDialogResizeBoundsH.prototype = new UIBounds(50, 1, 9999, 0);
UIDialogResizeBoundsV.prototype = new UIBounds(1, 50, 0, 9999);
A2 = {
    UI: {
        Url: "",
        ColorChooser: function(onChange)
        {
            this.OnChange = onChange;
            this.Holder = this.Content = $G.Tag("div", "UIColorChooser");
            this.Controls = [];
            this.Selected = null;
            this.AlternateColors = ["#000000", "#333333", "#666666", "#999999", "#CCCCCC", "#FFFFFF",
		                             "#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#00FFFF", "#FF00FF"];
            this.OnLoad = function()
            {
                var _wrap = new A2.UI.Control($G.Tag("div", "wrap"));
                for (var r = 0; r < 6; r++)
                {
                    var _rdiv = $G.Tag("div", "Side floatLeft");
                    for (var b = 0; b < 6; b++)
                    {
                        for (var g = 0; g < 6; g++)
                        {
                            var color = $G.Color.fromRGB({ r: r * 51, g: g * 51, b: b * 51 });
                            var _cdiv = $G.Append(_rdiv, $G.Tag("div", "Color floatLeft"));
                            _cdiv.style.background = color;
                            _cdiv.onclick = this.OnChange != null
		                        ? function()
		                        {
		                            this.th.OnChange(this.color.toUpperCase());
		                        } .bind({ color: color, th: this })
		                        : function() { };
                            _cdiv.onmouseover = function()
                            {
                                this.th.Selected.SetColor(this.color.toUpperCase());
                            } .bind({ color: color, th: this });
                        }
                    }
                    _wrap.AddControl(new A2.UI.Control(_rdiv));
                }
                this.AddControl(_wrap);
                var _gstripe = $G.Tag("div", "Stripe floatLeft");
                for (var g = 0; g < this.AlternateColors.length; g++)
                {
                    var color = this.AlternateColors[g];
                    var _cdiv = $G.Append(_gstripe, $G.Tag("div", "Color floatLeft"));
                    _cdiv.style.background = color;
                    _cdiv.onclick = this.OnChange != null
                        ? function()
                        {
                            this.th.OnChange(this.color.toUpperCase());
                        } .bind({ color: color, th: this })
                        : function() { };
                    _cdiv.onmouseover = function()
                    {
                        this.th.Selected.SetColor(this.color.toUpperCase());
                    } .bind({ color: color, th: this });
                }
                this.AddControl(new A2.UI.Control(_gstripe));
                this.Selected = this.AddControl(new A2.UI.Control($G.Tag("div", "Selected floatRight")));
                this.Selected.SetColor = function(color)
                {
                    this.Holder.style.background = color;
                    this.Holder.innerHTML = color;
                }
                this.Selected.SetColor("#FFFFFF");
            }
        },
        Calendar: function(onChange, date)
        {
            this.NextButton = { src: A2.UI.Url + "resource/images/calendarNext.gif", width: "16", height: "16" };
            this.PreviousButton = { src: A2.UI.Url + "resource/images/calendarPrev.gif", width: "16", height: "16" };
            this.Holder = this.Content = $G.Tag("div", "UICalendar");
            this.Controls = new Array();
            this.CurrentDate = (date || new Date());
            this.OnChange = onChange;

            this.SelectDate = function(date, accept)
            {
                if ((this.Days.Controls.length == 49) && (date.getMonth() != this.CurrentDate.getMonth()))
                    this.RenderDate(date);
                else if ((this.Days.Controls.length == 12) && ($G.Date.Decade(date) != $G.Date.Decade(this.CurrentDate)))
                    this.RenderYear(date);
                else
                {
                    var _c = this.GetByDate(this.CurrentDate);
                    _c.Holder.className = _c.Holder.className.replace(" Selected", "");
                    _c = this.GetByDate(date);
                    _c.Holder.className += " Selected";
                }
                this.CurrentDate = date;
                this._focusFixer.focus();
                if (accept)
                    this.Accept();
            }
            this.GetByDate = function(date)
            {
                for (var i = 0; i < this.Days.Controls.length; i++)
                {
                    var _day = this.Days.Controls[i];
                    if (_day.Holder.className.indexOf("NotThis") == -1)
                        if (this.Days.Controls.length == 49)
                    {
                        if (_day.GetText() == date.getDate().toString())
                            return _day;
                    }
                    else if (this.Days.Controls.length == 12)
                    {
                        if (_day.GetText() == date.getFullYear().toString())
                            return _day;
                    }
                }
            }
            this.SelectNext = function()
            {
                var date = this.CurrentDate;
                var _wd = $G.Date.Clone(date);
                if (this.Days.Controls.length == 49)
                    _wd.setDate(_wd.getDate() + 1);
                else if (this.Days.Controls.length == 12)
                    _wd.setFullYear(_wd.getFullYear() + 1);
                this.SelectDate(_wd);
                _wd = date = null;
            }
            this.SelectPrevious = function()
            {
                var date = this.CurrentDate;
                var _wd = $G.Date.Clone(date);
                if (this.Days.Controls.length == 49)
                    _wd.setDate(_wd.getDate() - 1);
                else if (this.Days.Controls.length == 12)
                    _wd.setFullYear(_wd.getFullYear() - 1);
                this.SelectDate(_wd);
                _wd = date = null;
            }
            this.NextWeek = function()
            {
                var date = this.CurrentDate;
                var _wd = $G.Date.Clone(date);
                if (this.Days.Controls.length == 49)
                    _wd.setDate(_wd.getDate() + 7);
                else if (this.Days.Controls.length == 12)
                    _wd.setFullYear(_wd.getFullYear() + 4);
                this.SelectDate(_wd);
                _wd = date = null;
            }
            this.PreviousWeek = function()
            {
                var date = this.CurrentDate;
                var _wd = $G.Date.Clone(date);
                if (this.Days.Controls.length == 49)
                    _wd.setDate(_wd.getDate() - 7);
                else if (this.Days.Controls.length == 12)
                    _wd.setFullYear(_wd.getFullYear() - 4);
                this.SelectDate(_wd);
                _wd = date = null;
            }
            this.NextMonth = function()
            {
                var date = this.CurrentDate;
                var _wd = $G.Date.Clone(date);
                if (this.Days.Controls.length == 49)
                {
                    _wd.setMonth(_wd.getMonth() + 1);
                    if (_wd.getMonth() - date.getMonth() == 2)
                    {
                        _wd.setMonth(1);
                        _wd.setDate(28);
                    }
                }
                else if (this.Days.Controls.length == 12)
                    _wd.setFullYear(_wd.getFullYear() + 10);
                this.SelectDate(_wd);
                _wd = date = null;
            }
            this.PreviousMonth = function()
            {
                var date = this.CurrentDate;
                var _wd = $G.Date.Clone(date);
                if (this.Days.Controls.length == 49)
                {
                    _wd.setMonth(_wd.getMonth() - 1);
                    if (date.getMonth() - _wd.getMonth() == 2)
                    {
                        _wd.setMonth(1);
                        _wd.setDate(28);
                    }
                }
                else if (this.Days.Controls.length == 12)
                    _wd.setFullYear(_wd.getFullYear() - 10);
                this.SelectDate(_wd);
                _wd = date = null;
            }
            this.Accept = function()
            {
                if (this.OnChange)
                    this.OnChange(this.CurrentDate);
            }
            this.Rendered = false;
            this.RenderDate = function(date)
            {
                this.Rendered = false;
                this.Days.ClearControls();
                var _dow = $G.Date.DaysOfWeekShort;
                for (var i = 1; i < _dow.length; i++) // Понедельник - суббота
                    this.Days.AddControl(new A2.UI.Label(_dow[i], "Day Label floatLeft"));
                this.Days.AddControl(new A2.UI.Label(_dow[0], "Day Label floatLeft")); // Воскресенье
                this.Month.SetText($G.Date.MonthEntity[date.getMonth() + 1] + ", " + date.getFullYear());
                this.Month.Holder.onclick = function()
                {
                    this.th.RenderYear(this.date);
                } .bind({ th: this, date: date });
                var _wd = $G.Date.Clone(date);
                _wd.setDate(1);
                for (var i = 0; i < 42; i++)
                {
                    var _td = $G.Date.Clone(_wd);
                    _td.setDate(i - (_wd.getDay() || 7) + 2);
                    var _day = this.Days.AddControl(new A2.UI.Label(_td.getDate(),
		                 "Day floatLeft" + ($G.Date.Compare(date, _td) ? " Selected" : "")
		                       + ($G.Date.Compare(_td, (new Date())) ? " Current" : "")
		                       + (_td.getMonth() != date.getMonth() ? " NotThis" : "")
		                    ));
                    $G.Event.Add(_day, "click", function()
                    {
                        this.th.SelectDate(this.date, true);
                    } .bind({ th: this, date: _td }));
                }
                this.Rendered = true;
            }
            this.RenderYear = function(date)
            {
                this.Rendered = false;
                this.Days.ClearControls();
                var _tyear = $G.Date.Decade(date);
                this.Month.SetText($G.Number.Norm(_tyear, 4) + " - " + $G.Number.Norm(_tyear + 9, 4));
                this.Month.Holder.onclick = function() { };
                for (var i = -1; i < 11; i++)
                {
                    var _ld = new Date();
                    _ld.setFullYear(_tyear + i);
                    var _year = this.Days.AddControl(new A2.UI.Label(_ld.getFullYear(), "Day Year floatLeft" +
		                  (_ld.getFullYear() == date.getFullYear() ? " Selected" : "")
		                + (_ld.getFullYear() == (new Date()).getFullYear() ? " Current" : "")
		                + ($G.Date.Decade(_ld) != $G.Date.Decade(date) ? " NotThis" : "")
		                ));
                    $G.Event.Add(_year, "click", function()
                    {
                        this.th.SelectDate(this.date, false);
                        this.th.RenderDate(this.date);
                        document.body.onclick = function()
                        {
                            document.body.onclick = $E.BodyClick.bind(this);
                        } .bind(this.th);
                    } .bind({ th: this, date: _ld }));
                }
                this.Rendered = true;
            }
            var _header = this.AddControl(new A2.UI.Control($G.Tag("div", "Header")));
            var _prev = _header.AddControl(new A2.UI.Image(this.PreviousButton, "Button floatLeft"));
            $G.Event.Add(_prev, "click", function()
            {
                this.PreviousMonth();
            } .bind(this));
            this.Month = _header.AddControl(new A2.UI.Label("Январь", "Month floatLeft"));
            var _next = _header.AddControl(new A2.UI.Image(this.NextButton, "Button floatLeft"));
            $G.Event.Add(_next, "click", function()
            {
                this.NextMonth();
            } .bind(this));
            this.Days = this.AddControl(new A2.UI.Control($G.Tag("div", "DaysContainer floatLeft")));
            this.OnLoad = function()
            {
                this.RenderDate(this.CurrentDate);
                $UI.Hotkey.Register([$UI.Hotkey.Keys.ArrowLeft], function()
                {
                    this.SelectPrevious();
                } .bind(this), "CalendarLeft");
                $UI.Hotkey.Register([$UI.Hotkey.Keys.ArrowRight], function()
                {
                    this.SelectNext();
                } .bind(this), "CalendarRight");
                $UI.Hotkey.Register([$UI.Hotkey.Keys.ArrowDown], function()
                {
                    this.NextWeek();
                } .bind(this), "CalendarDown");
                $UI.Hotkey.Register([$UI.Hotkey.Keys.ArrowUp], function()
                {
                    this.PreviousWeek();
                } .bind(this), "CalendarUp");
                $UI.Hotkey.Register([$UI.Hotkey.Keys.Enter], function()
                {
                    if (this.Days.Controls.length == 49 && this.Accept)
                        this.Accept();
                    else
                        this.RenderDate(this.CurrentDate);
                } .bind(this), "CalendarEnter");
                this.OnParentDeleted = function()
                {
                    this.OnUnload();
                }
            }
            this.OnUnload = function()
            {
                $UI.Hotkey.UnRegister([], "CalendarLeft");
                $UI.Hotkey.UnRegister([], "CalendarRight");
                $UI.Hotkey.UnRegister([], "CalendarUp");
                $UI.Hotkey.UnRegister([], "CalendarDown");
                $UI.Hotkey.UnRegister([], "CalendarEnter");
            }
            this._focusFixer = $G.Append(this.Holder, $G.Tag("input", "almostHidden", { type: "text" }));
        },
        ProgressBar: function(width, progress, color)
        {
            this.Controls = new Array();
            this.Holder = this.Content = $G.Tag("div", "ProgressBar");
            this.Bar = this.AddControl(new A2.UI.Control($G.Tag("div", "Bar")));
            this.Progress = progress ? progress : 0;
            this.Width = width ? width : 100;
            this.Color = color ? color : 0;
            this.SetColor = function(color)
            {
                this.Bar.Holder.style.backgroundColor = color;
            }
            this.SetWidth = function(width)
            {
                this.Holder.style.width = width + "px";
                this.ReportProgress(this.Progress);
            }
            this.ReportProgress = function(progress)
            {
                this.Progress = progress;
                this.Bar.Holder.style.width = this.Progress + "%";
            }
            this.OnLoad = function()
            {
                this.SetWidth(this.Width);
                this.SetColor(this.Color);
                this.ReportProgress(this.Progress);
            }
            this.Animate = function()
            {
            }
        },
        Image: function(obj, css)
        {
            this.Holder = this.Content = $G.Tag("img");
            this.SetImage = function(_obj)
            {
                if ($G.isString(_obj))
                    this.SetSrc(_obj);
                else
                {
                    $G.Extend(this.Holder, _obj, "");
                    this.SetSrc(_obj.src);
                    if ($G.Browser.Detect.ie)
                    {
                        this.Holder.width = _obj.width;
                        this.Holder.height = _obj.height;
                    }
                }
            }
            this.SetSrc = function(src)
            {
                if ((src.toLocaleLowerCase().indexOf(".png") != -1) && ($G.Browser.Detect.ie && !$G.Browser.Detect.ie7))
                {
                    this.Holder.style.background = "";
                    this.Holder.style.filter = "";
                    this.Holder.src = "images/px.gif";
                    this.Holder.style.background = "url(images/px.gif) repeat left top";
                    this.Holder.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', SizingMethod='scale')";
                }
                else
                    this.Holder.src = src;
            }
            if (obj)
                this.SetImage(obj);
            this.SetClass(css || "");
        },
        Label: function(text, css)
        {
            this.Holder = this.Content = $G.Tag("span");
            this.SetText = function(text)
            {
                this.Content.innerHTML = text;
                return this;
            }
            this.GetText = function()
            {
                return this.Content.innerHTML;
            }
            if (text)
                this.SetText(text);
            if (css)
                this.SetClass(css);
        },
        SystemControl: UISystemControl,
        IconButton: UIIconButton,
        LinkButton: UILinkButton,
        Control: UIControl
    },
    Init: function()
    {
        A2.UI.ColorChooser.prototype = new A2.UI.Control();
        A2.UI.Calendar.prototype = new A2.UI.Control();
        A2.UI.ProgressBar.prototype = new A2.UI.Control();
        A2.UI.Image.prototype = new A2.UI.Control();
        A2.UI.Label.prototype = new A2.UI.Control();
    }
}
function _UISize(w, h)
{
    this.Width = w ? w : 0;
    this.Height = h ? h : 0;
}
A2.Init();