﻿///<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))
            if($E[i] && $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(); };
