///<reference path="global.js" />
///<reference path="effects.js" />
$E = {
    _oldLoad: function(){},
    Init:function()
    { 
        for(var i in $E)
            if(!Function.prototype.isPrototypeOf($E[i]) && $E[i].Init && Function.prototype.isPrototypeOf($E[i].Init))
                $E[i].Init();
    },
    CssFix:
    {
        //Взято с хабра
        GetBrowser:function()
        {
            return document.getElementsByTagName('html')[0].className;
        },
        Init:function()
        {
            var u = navigator.userAgent.toLowerCase();
            var is = function(t){return (u.indexOf(t)!=-1);};
            var info = [
                (!(/opera|webtv/i.test(u))&&/msie (\d)/.test(u)) 
                    ?('ie ie'+RegExp.$1)
                    :is('firefox/2')
                        ?'gecko ff2'
                        :is('firefox/3')
                            ?'gecko ff3'
                            :is('gecko/')
                                ?'gecko'
                                :is('opera/9')
                                    ?'opera opera9'
                                    :/opera (\d)/.test(u)
                                        ?'opera opera'+RegExp.$1
                                        :is('konqueror')
                                            ?'konqueror'
                                            :is('applewebkit/')
                                                ?'webkit safari'   
                                                :is('mozilla/')
                                                    ?'gecko'
                                                    :'',
                (is('x11')||is('linux'))
                    ?' linux'
                    :is('mac')
                        ?' mac'
                        :is('win')
                        ?' win'
                        :''
            ]
            $E.Environment.Family = info[0].split(" ")[0];
            $E.Environment.Version = info[0].split(" ")[1];
            $E.Environment.OS = info[1];
            $E.CssFix.AddClass(document.getElementsByTagName('html')[0], info.join(" "));
        },
        AddClass:function(el, val)
        {
            if(!el.className)
                el.className = val;
            else
            {
                var newCl = el.className;
                newCl+=(" "+val);  
                el.className = newCl;
            }
        }
    },
    Environment:
    {
        Family:"",
        Version:"",
        OS:"",
        Init:function(){}
    },
    Wheel:
    {
        _handlers:{},
        Register:function(obj, formal, func, prevent)
        {
            $E.Wheel._handlers[formal] = {obj:obj, func:func, prevent:prevent};
        },
        UnRegister:function(formal)
        {
            $E.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 $E.Wheel._handlers)
	            {
	                if($E.Wheel._handlers[i] != null)
	                {
	                    if($G.IsChildOf($E.Wheel._handlers[i].obj, obj, 5) || $E.Wheel._handlers[i].obj == obj)
	                    {
	                        $E.Wheel._handlers[i].func(delta);
	                        prevent = prevent || $E.Wheel._handlers[i].prevent;
	                    }
	                }
	            }
	        }
	        if(prevent)
	        {
                if (event.preventDefault)
                    event.preventDefault();
                event.returnValue = false;
            }
        },
        Invoke:function()
        {
        },
        Init:function()
        {
            if (window.addEventListener)
                window.addEventListener('DOMMouseScroll', $E.Wheel.Process, false);
            window.onmousewheel = document.onmousewheel = $E.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()
		{
			this._old = $E.CssFix.GetBrowser().indexOf("gecko") != -1 ? window.onkeydown : document.body.onkeydown;
			if($E.CssFix.GetBrowser().indexOf("gecko") != -1)
				window.onkeydown = $E.Hotkey.Process.bind(this);
			else
				document.body.onkeydown = $E.Hotkey.Process.bind(this);
		    var _oldU = $E.CssFix.GetBrowser().indexOf("gecko") != -1 ? window.onkeyup : document.body.onkeyup;
			this._oldU = _oldU;
			if($E.CssFix.GetBrowser().indexOf("gecko") != -1)
				window.onkeyup = $E.Hotkey.Clear.bind(this);
			else
				document.body.onkeyup = $E.Hotkey.Clear.bind(this);
		},
		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)
		{
			var res = true;
			for(var i=0;i<val1.length;i++)
				res = res && (val1[i] == val2[i]);
			return res;
		},
		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]();
		},
		Process:function(e)
		{
			if(this._old)
				this._old(e);
			var _code = $G.GetKeyCode(e); 
			this.Pressed.push(_code);
			this.Invoke(this.GetFuncs(this.Pressed));
		}
	},
    CloseWindow:function(win, onClose)
    {
        if(onClose)
            onClose();
        $FX.Time(1000).Page.FadeOut("#fff", $FX.Page.CleanUp, true);
        var bg = $G.GET(win, "div:0");
        var content = $G.GET(win, "div:1");
        var scroll  = $G.GET(content, "div:0");
        $G.Display.Hide(scroll);
        $FX.Time(1000).AnimateStyle(win, "width", -1*$G.GetStyle(win, "width", true), 42, null, function(x)
        {
            this.win.style.left = (Math.round(this.wx/2)+this.x-Math.round(x/2))+"px";
            this.bg.style.width = (x-2)+"px";
            this.content.style.width = (x-8)+"px";
        }.bind({win:win, bg:bg, content:content, wx:$G.Window.Width(), x:$G.Window.Scroll.Left()}), "windowWidth");
        $FX.Time(1000).AnimateStyle(win, "height", -1*$G.GetStyle(win, "height", true), 42, function()
        {
            document.body.removeChild(this); 
            $E.Wheel.UnRegister("WindowScroll"); 
        }.bind(win), function(x)
        {
            this.win.style.top = (Math.round(this.hx/2)+this.y-Math.round(x/2))+"px";
            this.bg.style.height = (x-2)+"px";
            this.content.style.height = (x-8)+"px";
        }.bind({win:win, bg:bg, content:content, hx:$G.Window.Height(), y:$G.Window.Scroll.Top()}), "windowHeight");
    },
    ShowWindow:function(width, height, title, obj, onClose, noscroll)
    {
        var win = $G.Tag("div", "window", null);
        win.style.width = 6+"px";
        win.style.height = 6+"px";
        var bg = $G.Append(win, $G.Tag("div", "bg"));
        bg.style.width = 6+"px";
        bg.style.height = 6+"px";
        $G.Opacity.Set(bg, 0.15);
        var content = $G.Append(win,  $G.Tag("div", "w-content"));
        content.style.width = 0+"px";
        content.style.height = 0+"px";
        var scroll = $G.Append(content, $G.Tag("div", "scroll"));
        $G.Append(document.body, win);
        win.style.top = (Math.round($G.Window.Height()/2)+$G.Window.Scroll.Top()-3)+"px";
        win.style.left = (Math.round($G.Window.Width()/2)+$G.Window.Scroll.Left()-3)+"px";
        $G.Append($G.Event.Add($G.Append(scroll, $G.Tag("a", "close", {href:"javascript:void(0)"})), "click", function()
        {
            $E.CloseWindow(this.win, this.close);
        }.bind({win:win, close:onClose})), $G.Tag("img", {src:"resource/px.gif", width:"16", height:"16"}));
        $G.Append(scroll, $G.Tag("h3", null, null, (title || "")));
        $FX.Time(1000).Page.FadeIn("#fff", 80, null, true);
        setTimeout(function()
        {
            $FX.Time(1000).AnimateStyle(win, "width", width, width, function()
            {
                var x = $G.GetStyle(this.win, "width", true);
                this.win.style.left = (Math.round(this.deltax/2)+this.x-Math.round(x/2))+"px";
                this.bg.style.width = (x-2)+"px";
                this.content.style.width = (x-8)+"px";
                $E._wstop = true;
                if($E._hstop)
                    $E._appendFunc.bind(this)();
            }.bind(this), function(x)
            {
                this.win.style.left = (Math.round(this.deltax/2)+this.x-Math.round(x/2))+"px";
                this.bg.style.width = (x-2)+"px";
                this.content.style.width = (x-8)+"px";
            }.bind(this), "windowWidth");
            $FX.Time(1000).AnimateStyle(win, "height", height, height, function()
            {
                var x = $G.GetStyle(this.win, "height", true);
                this.win.style.top = (Math.round(this.deltay/2)+this.y-Math.round(x/2))+"px";
                this.bg.style.height = (x-2)+"px";
                this.content.style.height = (x-8)+"px";
                $E._hstop = true;
                if($E._wstop)
                    $E._appendFunc.bind(this)();
            }.bind(this), function(x)
            {
                this.win.style.top = (Math.round(this.deltay/2)+this.y-Math.round(x/2))+"px";
                this.bg.style.height = (x-2)+"px";
                this.content.style.height = (x-8)+"px";
            }.bind(this), "windowHeight");
        }.bind({noscroll:noscroll, win:win, bg:bg, scroll:scroll, content:content, obj:obj, x:$G.Window.Scroll.Left(), y:$G.Window.Scroll.Top(), deltax:$G.Window.Width(), deltay:$G.Window.Height()})
        , 10);
        return win;
    },
    _wstop:false,
    _hstop:false,
    WindowScroll:function(delta)
    {
          var border = delta > 0 ? 0 : ($G.GetStyle(this.content, "height", true) - this.scroll.offsetHeight-15);
          $FX.Time(200).AnimateStyle(this.scroll, "margin-top", (-delta*10), border, null, null, "WindowScroll");
    },
    _appendFunc:function()
    {
        if(this.obj)
            $G.Append(this.scroll, this.obj);
        if(!this.noscroll)
            $E.Wheel.Register(this.content, "WindowScroll", $E.WindowScroll.bind(this), true);
        $E._wstop = false;
        $E._hstop = false;
    },
    Screen:
    {
        Init:function(){},
        Over:function(obj)
        {
            if(obj)
            {
                if(obj.src.toLowerCase().indexOf(".png") != -1)
                    obj.src = obj.src.toLowerCase().replace(".png", "-selected.png");
                else if(obj.style.filter != null)
                    obj.style.filter = obj.style.filter.toLowerCase().replace(".png", "-selected.png");
            }
        },
        Out:function(obj)
        {
            if(obj)
            {
                if(obj.src.toLowerCase().indexOf(".png") != -1)
                    obj.src = obj.src.toLowerCase().replace("-selected.png", ".png");
                else if(obj.style.filter != null)
                    obj.style.filter = obj.style.filter.toLowerCase().replace("-selected.png", ".png");
            }
        }
    }
}
$E._oldLoad = window.onload;
window.onload = function(){ if($E._oldLoad){$E._oldLoad();}; $E.Init();};
