WEB_SOCKET_SWF_LOCATION = '/static/js/socketio/WebSocketMainInsecure.swf';

var Talk = Class.create({
    initialize: function (host) {
        this.host = host;
        Utils.fetch('/api/block/talk', function (json) {
            this.auth = json.auth;
            if ('block' in json) {
                this.block = json.block;
                this.connect();
            }
        }.bind(this));
    },
    connect: function () {
        var socket = this.socket = io.connect('http://'+window.location.host+':10980');
        socket.on('connect', function () {
            if ('widget_exists' in this) {
                if ($('talk_place').hasClassName('ondemand')) {
                    $('talker').appear();
                } else {
                    $('talk_place').appear();
                }
            } else {
                this.create_widget(this.block);
            }
            this.stream.update();
            this.users.select('div').invoke('remove');
            $('say').enable();
            this.socket.emit('init', window.location.href, this.process_cb.bindAsEventListener(this));
        }.bind(this));
        socket.on('disconnect', function () {
            $('say').disable().blur();
            $('talk_place').fade();
            $('talker').fade();
        }.bind(this));
        socket.on('alert', function (d) { Utils.growl(d) } );
        ['bundle','text','status','users','auth'].each(function (n) {
            this.socket.on(n, function (n, data) {
                this['on_'+n](data);
                /* this.socket.emit('ping', 'ping'); */
            }.bind(this, n));
        }.bind(this));
    },
    process_cb: function (data) {
        this['on_'+data[0]](data[1]);
    },
    on_bundle: function (data) {
        data.each(this.process_cb.bind(this));
    },
    on_text: function (data) {
        data.reverse().each(function (n) {
            this.stream.insert({ top: new Element('div', { 'data-date':n.date || '', 'data-av':n.user.av, 'data-name':n.user.name || '' }).update('<a class="user" href="/user/'+n.user.url+'" target="_blank">'+n.user.nick+'</a>' + ': ' + linkify(n.text.escapeHTML())) }).firstChild.hide().appear().select('a').invoke('writeAttribute', 'target', '_blank');
        }.bind(this));
        if (data.size() == 1 && $('talker').visible()) { Effect.Pulsate('talker') }
    },
    on_status: function (data) {
        var user_clients = this.users.select('a.user_' + data.url.replace('.', ''));
        if (data.status == 'online') {
            this.add_user(data);
            if ($('talk_place').visible() && user_clients.size() == 0) {
                Utils.growl(data.nick + ' ' + I18N[data.status]);
            }
        } else { // offline
            if (user_clients.size() > 1) { /* just one client of many */
                user_clients.select(function (s) { return !s.visible() }).first().remove();
            } else {
                user_clients.invoke('remove');
                if ($('talk_place').visible()) {
                    Utils.growl(data.nick + ' ' + I18N[data.status]);
                }
            }
        }
        this.update_users_count(); /* may just de-/increment */
    },
    on_users: function (data) {
        data.reverse().each(this.add_user.bind(this));
        this.socket.emit('auth', this.auth, this.process_cb.bindAsEventListener(this));
        this.update_users_count();
    },
    on_auth: function (data) {
        this.can_send = true;
        this.add_user(data);
        this.update_users_count();
        $('say').focus();
    },
    add_user: function (n) {
        this.users.insert(new Element('a', {
            className:'user_'+n.url.replace('.', ''),
            title:n.name || n.nick,
            href:'/user/'+n.url,
            target:'_blank'
        }).setStyle({
            backgroundImage: 'url(/static/'+ n.av +')',
            display:'none'
        }).update(n.nick)).lastChild[this.users.select('a.user_'+n.url.replace('.','')).size() > 1?'hide':'appear']();
        this.users.insert(' ');
    },
    update_users_count: function () { (function () {
        var btn = $('talk_menu').down('a.users');
        btn.update(btn.firstChild.nodeValue.replace(/\d+/, this.users.select('a').select(function (s) { return s.visible() }).size()));
    }).bind(this).delay(0.1); },
    create_widget: function (html) {
        if (!$('talk_place')) {
            $('footer').insert(new Element('div', { id: 'talk_place' }).hide().addClassName('ondemand'));
            $('talker').observe('click', function (e) {
                $('talk_place').down().addClassName('floating');
                $('talk_place').clonePosition($('talker'), { setWidth:false, setHeight: false }).setStyle({ position:'fixed', zIndex:11 }).addClassName('shadow3').appear();
                new Effect.Tween(null, -($('talk_place').getWidth() + 2), -2, {
                    duration: 1.0,
                    transition: Effect.Transitions.spring
                }, function (p) { this.setStyle({ left: p + 'px' }) }.bind($('talk_place')));
                $('talker').fade();
            }.bind(this)).appear();
            new Effect.Tween(null, -$('talker').getWidth() - 2, -2, {
                duration: 2.0,
                transition: Effect.Transitions.linear,
                afterFinish: function () {
                    $('talker').setStyle({ left: null });
                }
            }, function (p) { this.setStyle({ left: p + 'px' }) }.bind($('talker')));
        }
        $('talk_place').insert(html);
        if ($('talk_place').hasClassName('ondemand')) {
            $('talk_place').down('table.head').observe('click', function () {
                $('talk_place').fade();
                new Effect.Tween(null, -2, -($('talk_place').getWidth() + 2), {
                    duration: 1.0,
                    transition: Effect.Transitions.sinoidal
                }, function (p) { this.setStyle({ left: p + 'px' }) }.bind($('talk_place')));
                $('talker').appear();
            });
        }

        this.stream = $('talk_stream');
        this.users = $('talk_users');
        $('say').observe('keypress', function (e) {
            if (e.keyCode == Event.KEY_RETURN) {
                var el = e.findElement();
                if (!el.getValue()) { return e.stop(); }
                if ('socket' in this) {
                    if ('can_send' in this) {
                        this.socket.emit('text', el.getValue() );
                        el.value = '';
                    } else {
                        Utils.growl(I18N.no_guest_rate);
                    }
                } else {
                    Utils.growl(I18N.error);
                }
            }
            return true;
        }.bindAsEventListener(this)).disable();
        $('talk_menu').observe('click', function (e) {
            var el = e.findElement();
            if (el.tagName == 'A') {
                $('talk_' + el.up().down('a.select').removeClassName('select').className).hide();
                $('talk_' + el.className).show();
                el.addClassName('select');
                e.stop();
            }
        }.bindAsEventListener(this));
        this.tiptop = new TipTop();
        this.stream.observe('mouseover', function (e) {
            var el = e.findElement();
            if (el.hasClassName('user') && el.identify() !== this.current_tiptop) {
                this.current_tiptop = el.id;
                el = el.up();
                this.tiptop.show(e, 5, 5).update(
                    el.readAttribute('data-name') + (function (s) { 
                        if (!s) { return '' }
                        var d = new Date(s*1000);
                        return ' (' + d.getDate().toPaddedString(2) 
                            + '.' + (d.getMonth() + 1).toPaddedString(2) 
                            + '.' + (d.getYear() - 100) 
                            + ' ' + d.getHours().toPaddedString(2) 
                            + ':' + d.getMinutes().toPaddedString(2)+')';
                    })(el.readAttribute('data-date')) 
                    + '<br /><img src="/static/' + el.readAttribute('data-av') + '" />'
                );
            } else if (this.tiptop.visible()) {
                this.tiptop.hide();
            }
        }.bindAsEventListener(this)).observe('mouseleave', function (e) {
            this.tiptop.hide();
        }.bindAsEventListener(this));
        this.widget_exists = true;
    }
});

var TipTop = Class.create({
    visible: false,
    initialize: function () {
        this.el = new Element('div', { className: 'b-tiptop' });
        document.body.appendChild(this.el);
        this.el.hide().identify();
    },
    show: function(e, o_x, o_y) {
        if (!('wnd' in this)) {
            this.wnd = new Control.Window(this.el.show(), { position:'mouse', offsetTop: o_x, offsetY: o_y, fade: true, fadeDuration: 0.15 });
        }
        this.wnd.open(e);
        this.wnd.position(e);
        this.visible = true;
        return this;
    },
    hide: function() {
        if ('wnd' in this) {
            this.wnd.close();
        }
        this.visible = false;
        return this;
    },
    update: function (content) {
        this.el.update(content);
        return this;
    }
});

