var Chars = new Class({
    initialize: function() {
        this._charList = [];
        this._currTheme = -1;
        this._preload_user = -1;

        new Request.JSON({
            url: 'chars-xhr.php',
            data: {r:0},
            onSuccess: this.__onThemes.bind(this)
        }).post();
        new Request.JSON({
            url: 'chars-xhr.php',
            data: {r:3},
            onSuccess: this.__onUsers.bind(this)
        }).post();

        this.aj_char = new Request.JSON({
            url: 'chars-xhr.php',
            onSuccess: this.__onChar.bind(this)
        });
        this.aj_theme = new Request.JSON({
            url: 'chars-xhr.php',
            onSuccess: this.__onCharList.bind(this)
        });
    },

    filterUser: function(e, id) {
        if (e) new Event(e).stop();
        this.showCharList( this._charList.filter(function(i){return i.u==id;}), false );
    },

    loadChar: function(e, id, name, user, theme) {
        new Event(e).stop();
        this.aj_char.post({r:2, i:id, n:name, u:user, t:theme});
    },

    loadTheme: function(e, id) {
        if (e) new Event(e).stop();
        if (id != this._currTheme)
            this.aj_theme.post({r:1, i:id});
        else this.showCharList( this._charList, true );
    },

    loadUser: function(e) {
        new Event(e).stop();
        var id = $('users-select').get('value');
        this._loadUser(id);
    },
    _loadUser: function(id) {
        // bootstrap for the win
        this.aj_theme.post({r:4, i:id});
    },

    parseUrl: function() {
        var hash = window.location.hash.substr(2);
        if (hash.length == 0)
            return;

        var items = hash.split('/');
        if (items[0] == 'users') {
            var user_id = items[1];
            this._loadUser(user_id);
        } else if (items[0] == 'themes') {
            if (items.length == 3) 
                this._preload_user = items[2];

            var theme_id = items[1];
            this.loadTheme(null, theme_id);
        }
    },

    showCharList: function(list, showUser) {
        $('chars-list').empty();
        if (list.length > 0) {
            list.each(function(item) {
                $('chars-list').grab(
                    new Element('div').addClass('char-link')
                        .adopt(
                        new Element('a', {href:'#'})
                            .set('html', item.n)
                            .addEvent('click', this.loadChar.bindWithEvent(this, 
                                [item.i, item.n, item.k, item.t])),
                        ((showUser) ? ([
                        document.newTextNode(' ('),
                        new Element('a', {href:'#'})
                            .addClass('user-link')
                            .set('html', item.k)
                            .addEvent('click', this.filterUser.bindWithEvent(this, item.u)),
                        document.newTextNode(')')
                        ]) : [])
                    )
                );
            }, this);
            $('chars-list').grab( new Element('div').addClass('clear') );
        } else $('chars-list').set('html', 'No characters found');
    },

    __onChar: function(json) {
        if (!(json && json.s)) return;

        $('char-header').empty().grab(
            new Element('h3')
                .addClass('header-link')
                .set('html', json.n)
        );
        if (json.h) {
            $('char-header').grab(
                document.newTextNode('on ' + this.__themes[json.h])
            );
        }
        if (json.u) {
            $('char-header').grab(
                document.newTextNode('(by: ' + json.u + ')')
            );
        }
        $('char-header').grab(
            new Element('a', {href:'./read.php?r='+json.i})
                .addClass('header-link')
                .set('text', "View discussion thread")
        );
        if (json.p) {
            $('char-header').grab(
                new Element('a', {href:'./post.php?p='+json.p+'&mode=edit'})
                    .addClass('header-link')
                    .set('text', "Edit character")
            );
        }
        $('char-pane').set('html', json.t);
    },

    __onCharList: function(json, t) {
        if (!(json && json.s)) return;

        this._charList.empty().extend( json.t );
        if (!json.u) {
            if (this._currTheme != -1)
                $('users-at-'+this._currTheme).empty();
            this._currTheme = json.i;
            if (this._preload_user > -1) {
                this.filterUser.delay(50, this, [null, this._preload_user]);
                this._preload_user = -1;
            }

           // build user list
            var users = [], users_hash = {}; 
            if (this._charList.length > 0) {
                this._charList.each(function(item) {
                    if (users_hash[ item.u ] == item.k)
                        return;
                    this.push({n:item.k, i:item.u});
                    users_hash[ item.u ] = item.k;
                }, users);
                
                // sort and show
                users.sort( this.___userCmp );
                users.each(function(item) {
                    var el = $('users-at-'+json.i);
                    if (el) el.grab(
                        new Element('a', {href:'#'})
                            .addClass('user-link')
                            .set('text', item.n)
                            .addEvent('click', this.filterUser.bindWithEvent(this, item.i))
                    );
                }, this);
            }
        }

        var showUser = !json.u;

        this.showCharList( this._charList, showUser );
    },


    __onThemes: function(json) {
        if (!(json && json.s)) return;

        this.__themes = {};
        json.t.each(function(item) {
            var repr = item.n + ' (' + item.d + ')';
            this.__themes[item.i] = repr;
            $('servers-list').grab(
                new Element('div').adopt(
                    new Element('a', {href:'#'})
                        .set('text', repr)
                        .addEvent('click', this.loadTheme.bindWithEvent(this, item.i)),
                    new Element('div', {id:'users-at-'+item.i})
                        .addClass('users-list')
                )
            );
        }, this);
        $('chars-list').empty()
            .set('html', 'Step 1: Select a theme from the left, or a user from the drop-down');
        $('char-pane').empty()
            .set('html', 'Step 2: Select a character from up top, or click on a user name to only list characters that user has posted.');

        this.parseUrl.delay(50, this);
    },

    __onUsers: function(json, t) {
        if (!(json && json.s)) return;

        json.u.each(function(item) {
            $('users-select').grab(
                new Element('option', {value: item.u})
                    .set('text', item.k)
            );
        }, this);

        $('users-select').addEvent('change', this.loadUser.bindWithEvent(this))
    },

    /**
     * Comparator for two "user" hashes
     */
    ___userCmp: function(a, b) {
        if (a.n == b.n)
            return 0;
        else if (a.n > b.n)
            return 1;
        else return -1;
    }
});
window.addEvent('domready', function(){ new Chars(); });
