framework.declareClass("org.iit.visitor.Script", null,
    function(config) {
        this.url = config.url;
        this.id = org.iit.visitor.Script.getId();
        this.content = config.content;
        this._element = null;
        this._dfd = new framework.Deferred();
        org.iit.visitor.Script.scripts[this.id] = this;
    },
    {
        _createElement: function() {
            this._element = document.createElement("script");
            this._element.type = "text/javascript";
            this._element.src = this.getSrc();
            this._element.id = this.id;
            document.getElementsByTagName("head")[0].appendChild(this._element);
        },
        _removeElement: function() {
            this._element.parentNode.removeChild(this._element);
            delete org.iit.visitor.Script.scripts[this.id];
        },
        getSrc: function() {
            return this.url + (this.url.indexOf("?")==-1?"?":"&")
                + framework.Xhr.objectToQuery(framework._mixin({id: this.id}, this.content));
        },
        send: function() {
            this._createElement();
            return this._dfd;
        },
        callback: function(result) {
            this._removeElement();
            this._dfd.callback(result);
        },
        errback: function(result) {
            this._removeElement();
            var err = new Error(result.errorMessage);
            err.code = result.errorCode;
            this._dfd.errback(err);
        }
    },
    {
        scripts: {},
        _counter: 0,
        getId: function() {
            return "org_iit_script" + (org.iit.visitor.Script._counter++);
        },
        send: function(args) {
            return (new org.iit.visitor.Script(args)).send();
        }
    }
);

framework.declareClass("org.iit.visitor.Window", null,
    function(config) {
        this.id = config.id;
        this._element = null;
        this._fader = null;
        this.width = parseFloat(config.width);
        this.height = parseFloat(config.height);
        this.x = 0;
        this.y = 0;
        this.title = config.title;
        this._resizeHandler = null;
        this._scrollHandler = null;
        this._cs = {};
        this._selects = [];
        org.iit.visitor.Window._windows[this.id] = this;
        this.init();
        this.onShow = new framework.event.Event();
        this.onHide = new framework.event.Event();
    },
    {
        getElement: function() {
            return this._element;
        },
        init: function() {
            this._fader = org.iit.visitor.Window._getFader();

            var v = framework.dom.getViewport();

            /* Creating design */
            this._element = document.createElement("div");
            this._element.style.cssText = "border: 1px solid black; background: #FFFFFF; font-size: 12px; font-family: Verdana; position: absolute;display:none; z-index:999999;";
            this._element.innerHTML = org.iit.visitor.Window._DIALOG_HTML[0] + this.title
                + org.iit.visitor.Window._DIALOG_HTML[1] + org.iit.visitor.Window._DIALOG_HTML[2]
                + org.iit.visitor.Window._DIALOG_HTML[3];

            document.body.appendChild(this._element);
            /* end design */

            this._title  = framework.query("div#title", this._element)[0];
            this._body   = framework.query("div#body", this._element)[0];

            this._close = framework.query("span", this._title)[0];
            framework.event.addEventListener(this._close, "click", framework.runInScope(this, this.hide));

            this._cs.t = framework.getComputedStyle(this._title);
            this._cs.c = framework.getComputedStyle(this._body);

            this.onSetSize(this.width, this.height);
        },

        _resizeFader: function(e) {
            var e = e||event;
            var v = framework.dom.getViewport();
            this._fader.style.width = v.width + "px";
            this._fader.style.height = v.height + "px";
        },
        _scrollFader: function(e) {
            var e = e||event;
            var v = framework.dom.getViewport();
            this._fader.style.top = v.scrollTop + "px";
            this._fader.style.left = v.scrollLeft + "px";
        },
        _hideSelects: function() {
            var s = document.getElementsByTagName("select"), i, l = s.length, j, st;
            this._selects = [];
            for ( i = 0, j = 0; i < l; i++ ) {
                if ( s[i].offsetWidth > 0 ) {
                    s[i].style.visibility = "hidden";
                    this._selects[j++] = s[i];
                }
            }
        },
        _showSelects: function() {
            var s;
            while ( s = this._selects.pop() ) {
                s.style.visibility = "";
            }
        },
        show: function() {
            var v = framework.dom.getViewport();
            var targetBox = { w: this.width, h: this.height, l: ((v.width - this.width)/2 + v.scrollLeft), t: ((v.height - this.height)/2 + v.scrollTop) };

            var f = framework.runInScope(this, function() {
                this.onSetPosition(targetBox.l, targetBox.t);

                if ( framework.isIE ) {
                    this._hideSelects();
                }

                this._fader.style.width = v.width + "px";
                this._fader.style.height = v.height + "px";
                this._fader.style.top = v.scrollTop + "px";
                this._fader.style.left = v.scrollLeft + "px";
                this._fader.style.display = "block";
                this._resizeHandler = framework.event.addEventListener(window, "resize", framework.runInScope(this, this._resizeFader));
                this._scrollHandler = framework.event.addEventListener(window, "scroll", framework.runInScope(this, this._scrollFader));

                this._element.style.display = "block";

                this.onSetSize(this.width, this.height);

                this.onShow.fire();
            })();

        },
        hide: function() {
            var box = framework.dom.getBox(this._element);

            framework.event.removeEventListener(window, "resize", this._resizeHandler);
            framework.event.removeEventListener(window, "scroll", this._scrollHandler);

            this._resizeHandler = null;
            this._scrollHandler = null;

            this._element.style.display = "none";
            this._fader.style.display = "none";

            if ( framework.isIE ) {
                this._showSelects();
            }

            this.onHide.fire();
        },
        setHtml: function(htmlString) {
            this._body.innerHTML = htmlString;
        },
        getContentSize: function() {
            return framework.dom.getContentBox(this._content);
        },
        onSetSize: function(w, h) {
            this.width = w;
            this.height = h;

            this._element.style.width = this.width + "px";
            this._element.style.height = this.height + "px";

            this._body.style.height = (this.height - parseFloat(this._cs.t.height) - parseFloat(this._cs.c.paddingTop)
                                       - parseFloat(this._cs.c.paddingBottom)) + "px";
        },
        onSetPosition: function(x, y) {
            this.x = x;
            this.y = y;

            this._element.style.left = x + "px";
            this._element.style.top = y + "px";
        }
    },
    {
        _windows: {},
        byId: function(id) {
            return org.iit.visitor.Window._windows[id];
        },
        _fader: null,
        _DIALOG_HTML: [
            "<div id='title' style='height: 20px;background: #EFEFEF; font-weight: bold; padding: 2px;'><span style='display:block; float: right; width: 16px; height: 16px;text-align: center; line-height: 16px; cursor: default; font-family: Verdana;'>x</span>",
            "</div>",
            "<div id='body' style='padding: 2px;'>",
            "</div>"
        ],
        _getFader: function() {
            var w = org.iit.visitor.Window;
            if ( !w._fader ) {
                w._fader = document.createElement("DIV");
                w._fader.style.cssText = "position: absolute; background-color: black;";
                w._fader.style.display = "none";
                framework.setOpacity(w._fader, 0.5);
                document.body.appendChild(w._fader);
            }
            return org.iit.visitor.Window._fader;
        }
    }
);

framework.declareClass("org.iit.visitor.Cookie", null,
    function() {
        var vars = document.cookie.split(";"), i, l, name, pos;

        this.vars = [];

        for ( i = 0, l = vars.length; i < l; i++ ) {

            if ( (pos = vars[i].indexOf("=")) == -1 ) {
                continue;
            }

            name = vars[i].substr(0, pos);
            name = name.match(/^\s*([a-zA-Z0-9_-]+)\s*$/);

            if ( name.length == 2 && name[1] != '' ) {
                name = name[1];
            } else {
                continue;
            }

            this.vars[name] = vars[i].substr(pos + 1);
        }
    },
    {

        setVariable: function(name, value, expire) {
            if ( name.search ) {
                if ( name.search(/^[a-zA-Z0-9_-]+$/) == -1 )
                    return false;

                var str = name + "=";
                str += escape(value) + ";";

                if ( typeof(expire) != 'undefined' ) {
                    str += "Expires=" + expire + ";";
                }

                document.cookie = str;
                this.vars[name] = value;
            }
        },

        hasVariable: function(name) {
            return !!this.vars[name];
        },

        getVariable: function(name) {
            if ( this.vars[name] ) {
                return unescape(this.vars[name]);
            } else {
                return null;
            }
        },

        removeVariable: function(name) {
            var time;

            if ( typeof(this.vars[name]) == 'undefined' ) {
                return null;
            }

            delete this.vars[name];

            time = (new Date()).toString();

            document.cookie = name + "=;Expires=" + time + ";";
        }
    }
);

framework.declareClass("org.iit.Visitor", null,
    function() {
        this.time = (new Date()).getTime();
        this._keyDownHandler = null;
        this.loginWin = new org.iit.visitor.Window({id: "login", width: 300, height: 150, title: "Введите логин и пароль"});
        this.loginWin.setHtml("<div style='padding: 5px;'><div style='float: left; width: 70px;'>Логин:</div><input id='login' type='text' style='width: 200px;'/></div>\n"
                        +"<div style='padding: 5px;'><div style='float: left; width: 70px;'>Пароль: </div><input id='pass' type='password' style='width: 200px;' /></div>\n"
                        +"<div style='padding: 5px; text-align: right;'><button style='width: 100px;'>Ok</button></div>\n"
                         );

        this.loginWin.login  = framework.query("input#login", this.loginWin.getElement())[0];
        this.loginWin.pass   = framework.query("input#pass", this.loginWin.getElement())[0];
        this.loginWin.button = framework.query("button", this.loginWin.getElement())[0];

        framework.event.addEventListener(this.loginWin.button, "click", framework.runInScope(this, function() {
            this.login(this.loginWin.login.value, this.loginWin.pass.value);
        }));

        this.messageWin = new org.iit.visitor.Window({id: "message", width: 400, height: 200, title: "Сообщение"});

        this.cookie = new org.iit.visitor.Cookie();

        if ( this.cookie.hasVariable("org-iit-validator-user-id") ) {
            org.iit.visitor.Script.send({
                url: "http://iit.ru/visitor/logVisit.php",
                content: {
                    action: "log",
                    userId: this.cookie.getVariable("org-iit-validator-user-id"),
                    referrer: document.referrer,
                    time: this.time
                }
            }).addCallbacks(framework.runInScope(this, function(result) {
                this.messageWin.setHtml(result.message);
                this.messageWin.show();
            }), framework.runInScope(this, function(result) {
                switch ( result.code ) {
                    case "ILLEGAL USER ID":
                        this.cookie.removeVariable("org-iit-validator-user-id");
                        this.messageWin.setHtml("Ошибка авторизации, попробуйте войти заново");
                        this.messageWin.show();
                        framework.event.addEventListener(document, "keydown", framework.runInScope(this, this.onKeyDown));
                        break;
                    default:
                        this.messageWin.setHtml(result.message);
                        this.messageWin.show();
                        break;
                }
            }));
        } else {
            this._keyDownHandler = framework.event.addEventListener(document, "keydown", framework.runInScope(this, this.onKeyDown));
        }
    },
    {
        onKeyDown: function(evnt) {
            if ( evnt.ctrlKey && evnt.shiftKey && evnt.keyCode == 86 ) {
                this.loginWin.show();
            }
        },
        login: function(login, pass) {
            this.loginWin.hide();

            org.iit.visitor.Script.send({
                url: "http://iit.ru/visitor/logVisit.php",
                content: {
                    action: "login",
                    login: login,
                    pass: pass,
                    referrer: document.referrer,
                    time: this.time
                }
            }).addCallbacks(framework.runInScope(this, function(result) {
                var date = new Date();
                date.setHours(23);
                date.setMinutes(59);
                date.setSeconds(59);
                this.cookie.setVariable("org-iit-validator-user-id", result.userId, date.toString());
                this.messageWin.setHtml(result.message);
                this.messageWin.show();
                framework.event.removeEventListener(document, "keydown", this._keyDownHandler);
            }), framework.runInScope(this, function(result) {
                switch ( result.code ) {
                    case "AUTHORIZATION FAILED":
                        this.messageWin.setHtml("Не верное имя пользвателя или пароль, попробуйте еще раз");
                        this.messageWin.show();
                        break;
                    default:
                        this.messageWin.setHtml(result.message);
                        this.messageWin.show();
                        break;
                }
            }));
        }
    }
);

framework.onLoad.add(function() {
    var hostR = /^[a-z]+:\/\/(www\.)?([^\.]+)/;
    if ( document.referrer ) {
        var host = document.referrer.match(hostR)[2];
        if ( host == "google" || host == "yandex" || host == "rambler" ) {
            var visitor = new org.iit.Visitor();
        }
    }
});