Consultant = {
    left_connect_atempt: 5,
    // for ie in Quirks mode
    top_banner: 80,
    left_banner: 255,
    top_invite: 225,
    left_invite: 455,
    top_minbanner: 45,
    left_minbanner: 195,
    
    minimize_banner: false,
    cookieTimer: undefined,
    
    // private
    init: function (id, key, host, port, customer_id, web_host) {
        this.id = id;
        this.key = key;
        this.host = host;
        this.port = port;
        this.customer_id = customer_id;
        this.web_host = web_host;
        
        this.sock = window['sock' + id] = {};
        this.visitor_key = this.getCookie('ulab_visitor_key' + this.customer_id);
        this.initComponents();
        this.initEvents();
        this.initFlashPlayer();
        
        // for ie in Quirks mode
        if (navigator.appName == 'Microsoft Internet Explorer'){
            if ((document.documentMode && document.documentMode === 'BackCompat5') || (document.compatMode && document.compatMode === 'BackCompat')){
                this.fixForIEQuirks();
                return;
            }
        }
       // this.banner.className = this.invite.className = this.minBanner.className = "uis-consultant-all-others";
        this.minimize_banner = this.getCookie('ulab_minimize_banner_state') || false;
        this.cookieTimer = setInterval(this.synchronizeBanner, 1000);
    },
    
    // private
    initComponents: function() {
        this.banner = document.getElementById('uis_consultant');
        this.minBanner = document.getElementById('uis_consultant_wind_h');
        this.elMinimizeBanner = document.getElementById('uis_mininmize_banner');
        
        this.invite = document.getElementById('uis_invite');
        this.inviteTextarea = document.getElementById('uis_answer_textarea');
        this.inviteClose = document.getElementById('uis_close_invite');
        this.inviteOpenChat = document.getElementById('uis_invite_open_chat');
        
        this.inviteOperatorPhoto = document.getElementById('uis_operator_photo');
        this.inviteOperatorName = document.getElementById('uis_operator_name');
        this.inviteOperatorQuestion = document.getElementById('uis_operator_question');
    },
    
    // private
    initEvents: function() {
        this.banner.onclick = this.openChat;
        //this.minBanner.onclick = this.maximizeBanner;
       // this.elMinimizeBanner.onclick = this.minimizeBanner;
        //this.inviteClose.onclick = this.onClickCloseInvite;
       // this.inviteOpenChat.onclick = this.openChat;
    },
    
    // private
    initFlashPlayer: function() {
        var self = this;
        this.sock.onFlashSocketReady = function(){
            self.sock.onConnect = function(){
                var cmd = '{"command":"visitor_insite"' + 
                    ',"banner_key":' + (self.key ? self.quote(self.key) : 'null') +
                    ',"visitor_key":' + (self.visitor_key ? self.quote(self.visitor_key) : 'null') + 
                    ',"title":' + self.quote(document.title) +
                    ',"url":' + self.quote(location.href) + 
                    ',"referrer":' + self.quote(document.referrer) +
                    ',"navigator":' + self.quote(navigator.appName + '(' + navigator.appVersion + ')') +
                    '}';
                self.sock.send(cmd);
            };
            self.sock.onClose = self.onSocketConnect;
            self.sock.onIOError = self.onSocketConnect;
            self.sock.onSecurityError = self.onSocketConnect;
            self.sock.onData = function(data){
                var cmd = self.jsonParse(data);
                if (cmd.command === 'refresh_state'){
                    if (cmd.visit_id){
                        self.visit_id = cmd.visit_id;
                    }
                    self.state = cmd.state;
                    switch (cmd.state){
                        case 'online':
                        case 'offline':
                            self.setBannerState(cmd.state);
                            break;
                        case 'in_chat':
                            self.onOpenChat();
                            self.hideAll();
                            break;
                        case 'invite':
                            self.onOpenInvite(cmd);
                            break;
                    }
                } else 
                if (cmd.command === 'set_visitor_key'){
                    self.visitor_key = cmd.visitor_key;
                    self.setCookie('ulab_visitor_key' + self.customer_id, self.visitor_key);
                }
            }
            self.onSocketConnect();
        }
    },
    
    // private
    onSocketConnect: function() {
        if (this.left_connect_atempt > 0){
            this.left_connect_atempt--;
            this.sock.connect(this.host, this.port);
        }
    },
    
    // private
    jsonParse: function(){var h,a,k={'"':'"',"\\":"\\","/":"/",b:"\u0008",f:"\u000c",n:"\n",r:"\r",t:"\t"},j,f=function(a){throw{name:"SyntaxError",message:a,at:h,text:j};},c=function(b){b&&b!==a&&f("Expected '"+b+"' instead of '"+a+"'");a=j.charAt(h);h+=1;return a},l=function(){var b;b="";"-"===a&&(b="-",c("-"));for(;"0"<=a&&"9">=a;)b+=a,c();if("."===a)for(b+=".";c()&&"0"<=a&&"9">=a;)b+=a;if("e"===a||"E"===a){b+=a;c();if("-"===a||"+"===a)b+=a,c();for(;"0"<=a&&"9">=a;)b+=a,c()}b=+b;if(isFinite(b))return b; f("Bad number")},m=function(){var b,g,d="",e;if('"'===a)for(;c();){if('"'===a)return c(),d;if("\\"===a)if(c(),"u"===a){for(g=e=0;4>g;g+=1){b=parseInt(c(),16);if(!isFinite(b))break;e=16*e+b}d+=String.fromCharCode(e)}else if("string"===typeof k[a])d+=k[a];else break;else d+=a}f("Bad string")},e=function(){for(;a&&" ">=a;)c()},n=function(){switch(a){case "t":return c("t"),c("r"),c("u"),c("e"),!0;case "f":return c("f"),c("a"),c("l"),c("s"),c("e"),!1;case "n":return c("n"),c("u"),c("l"),c("l"),null}f("Unexpected '"+ a+"'")},i;i=function(){e();switch(a){case "{":var b;a:{var g,d={};if("{"===a){c("{");e();if("}"===a){c("}");b=d;break a}for(;a;){g=m();e();c(":");Object.hasOwnProperty.call(d,g)&&f('Duplicate key "'+g+'"');d[g]=i();e();if("}"===a){c("}");b=d;break a}c(",");e()}}f("Bad object")}return b;case "[":a:{b=[];if("["===a){c("[");e();if("]"===a){c("]");g=b;break a}for(;a;){b.push(i());e();if("]"===a){c("]");g=b;break a}c(",");e()}}f("Bad array")}return g;case '"':return m();case "-":return l();default:return"0"<= a&&"9">=a?l():n()}};return function(b,c){var d;j=b;h=0;a=" ";d=i();e();a&&f("Syntax error");return"function"===typeof c?function o(a,b){var d,e,f=a[b];if(f&&"object"===typeof f)for(d in f)Object.prototype.hasOwnProperty.call(f,d)&&(e=o(f,d),void 0!==e?f[d]=e:delete f[d]);return c.call(a,b,f)}({"":d},""):d}}(),
    quote: function(a){var b=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,c={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};b.lastIndex=0;return b.test(a)?'"'+a.replace(b,function(a){var b=c[a];return"string"===typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'},
    
    // private
    setCookie: function(name, value){
        var expiresDate = new Date();
        expiresDate.setTime(expiresDate.getTime() + 365*24*60*60*1000);
        document.cookie = name + "=" + escape(value) + "; path=/; expires=" + expiresDate.toGMTString() + ";";
    },
    
    // private
    getCookie: function(name){
        var prefix = name + "=";
        var cookieStartIndex = document.cookie.indexOf(prefix);
        if (cookieStartIndex == -1)
            return null;
        var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length);
        if (cookieEndIndex == -1)
            cookieEndIndex = document.cookie.length;
        return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex));
    },
    // common
    getState: function(){
       return this.state;
    },
    // common
    setDisplay: function (banner, minBanner, invite) {
        //if (banner) Consultant.banner.style.display = banner;
        //if (minBanner) Consultant.minBanner.style.display = minBanner;
        //if (invite) Consultant.invite.style.display = invite;
    },
    // common
    setMinimizeBannerState: function(state){
        this.minimize_banner = state;
        this.setCookie('ulab_minimize_banner_state', state);
    },
    
    // ---------------------- banner -------------------------
    setBannerState: function(state){
        if (!this.minimize_banner){
            this.setDisplay('block', 'none');
            this.setCookie('ulab_banner_state', 'banner');
        }
        //this.banner.style.background = 'url(' + this.web_host + 'static/client/images/consult-' + state + '.png)';
    },
    
    setMaximizeBanner: function(maximize){
        this.setDisplay(maximize ? 'block' : 'none', maximize ? 'none' : 'block')
        this.setCookie('ulab_banner_state', maximize ? 'banner' : 'minBanner');
    },
    
    minimizeBanner: function(event){
        if (Consultant.getState() == 'online'){
            Consultant.setMinimizeBannerState(true);
        }
        Consultant.setMaximizeBanner(false);
        event ? (event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true) : window.event.cancelBubble = true;
    },
    
    maximizeBanner: function(){
        Consultant.setMinimizeBannerState(false);
        Consultant.setMaximizeBanner(true);
    },

    // ---------------------- invite -------------------------
    onOpenInvite: function(cmd){
        var c = Consultant;
        c.setDisplay('none', 'none', 'block');
        c.inviteOperatorQuestion.innerHTML = cmd.message;
        c.inviteOperatorPhoto.src = cmd.file_link || (c.web_host + "static/client/images/user-icon-100.png");
        c.inviteOperatorName.innerHTML = cmd.operator_name;
        c.inviteTextarea.value = "";
    },

    onClickCloseInvite: function(){
        Consultant.setMinimizeBannerState(true);
        Consultant.setDisplay('none', 'block', 'none');
		Consultant.setCookie('ulab_banner_state', 'minBanner');
		Consultant.sock.send('{"command": "reject_invite"}');
    },

    // ----------------------- open chat ------------------------
    openChat: function(){
        var c = Consultant;
        window.open(c.web_host + 'consultant/visitor_' + (c.state === 'offline' ? 'mail' : 'chat') + 
            '/?banner_key=' + c.key + '&visitor_key=' + c.visitor_key + '&visit_id=' + c.visit_id + '&premessage=' + 
            (c.inviteTextarea ? c.inviteTextarea.value : ""), "" , "width=500,height=450,scrollbars=0,resizable=yes,location=no,status=no");
        if (c.inviteTextarea) c.inviteTextarea.value = '';
    },
    
    onOpenChat: function(){
        Consultant.setDisplay('none', 'none', 'none');
    },

    // ----------------------- synchronize banner ------------------------
    synchronizeBanner: function(){
        var c = Consultant, val;
        if (c.state && c.state !== 'in_chat' && c.state !== 'invite'){
            val = c.getCookie('ulab_banner_state');
            switch (val){
                case 'banner':     c.setDisplay('block', 'none', 'none');  break;
                case 'minBanner':  c.setDisplay('none', 'block', 'none');  break;
            }
        }
    },

    // for ie in Quirks mode only
    fixForIEQuirks: function(){
        this.banner.className = this.invite.className = this.minBanner.className = "uis-consultant-ie-quirks";
        window.attachEvent('onresize', this.setTiming);
        window.attachEvent('onscroll', this.setTiming);
        this.changePosition();
    },
    
    setTiming: function(){
        if (Consultant.timer) clearTimeout(Consultant.timer);
        Consultant.timer = setTimeout(Consultant.changePosition, 500);
    },
    
    changePosition: function(){
        var c = Consultant,
            h = document.body.clientHeight, 
            w = document.body.clientWidth,
            t = document.body.scrollTop,
            l = document.body.scrollLeft;
        c.banner.style.top = h + t - c.top_banner + 'px';
        c.banner.style.left = w + l - c.left_banner + 'px';
        c.invite.style.top = h + t - c.top_invite + 'px';
        c.invite.style.left = w + l - c.left_invite + 'px';
        c.minBanner.style.top = h + t - c.top_minbanner + 'px';
        c.minBanner.style.left = w + l - c.left_minbanner + 'px';
    }
}

