
sa.view = {};

sa.view.Base = Backbone.View.extend({

    getActionContexts: function() {
        return [this];
    }

    , hide: function() {
        $(this.el).addClass('hidden');
        this.hide2();
    }

    , hide2: function(){}

    , show: function(options) {
        $(this.el).removeClass('hidden');
        this.show2(options);
    }

    , show2: function(){}
});

sa.view.Action = sa.view.Base.extend({
    _:''
    , classClick: null
    , classFocus: null
    , classHover: null
    , events: {
        'click': 'click'
    }
    , html: null
    , label: null

    , click: function() {}
    , render: function() {
        if(this.label)
            $(this.el).text(this.label);
        else if(this.html)
            $(this.el).html(this.html);
        return this;
    }

});

sa.view.Button = sa.view.Action.extend({
    attributes: {
        role: 'button'
        , tabindex: '0'
    }
    , className: 'button'
});

sa.view.PopupButton = sa.view.Button.extend({
    click: function() {
        var popup = this.createPopup();
        if(!popup) return;

        var $el = $(this.el),
            pos = $el.position();
        $el.addClass('popup');
        popup.showAt(pos.left, pos.top + $el.height()).
        popup.bind('close', function() {
            $el.removeClass('popup');
        }, this);
    }

    , createPopup: function() {}
});

function tplScript(id) {
    return _.template(document.getElementById(id).innerHTML);    
}

sa.view.TemplateView = sa.view.Base.extend({
    tpl: null

    , getTplContext: function() {
        return this.model ? this.model.toJSON() : {};
    }

    , render: function() {
        if(this.tpl) {
            $(this.el).html(this.tpl(this.getTplContext()));
        }
        this.render2();
        return this;
    }

    , render2: function() {}
});


sa.view.List = sa.view.TemplateView.extend({

    className: 'ai-list-wrap'

    /*
     * CSS class for list item.
     */
    , itemClass: ''

    /*
     * List Items, could be any object.
     */
    , items: null

    /*
     * Deault template to render an item. By default, it assumes each item to be
     * a string.
     */
    , itemTpl: _.template('<%= item %>')

    /*
     * list template
     */
    , tpl: tplScript('template-list')

    , getTplContext: function() {
        return {
            itemClass: this.itemClass
            , items: this.items
            , itemTpl: this.itemTpl
        }
    }
});

/*
 * A window consists of a titlebar/header, actionbar and a footer.
 */
sa.view.Window = sa.view.TemplateView.extend({
    // TODO

    className: 'ai-window-wrap'

    , options: {
        title: ''
    }

    , title: ''
    , tplTitleBar: _.template('<span><%= title %><span>')

    , render2: function() {
        this.renderTitleBar();
        this.renderTopBar();
        this.renderBody();
        this.renderBottomBar();
    }

    , renderBody: function() {
    }

    , renderBottomBar: function() {
    }

    , renderTitleBar: function() {
        this.$('.ai-wtitlebar').html(this.tplTitleBar({
            title: this.options.title
        }));
    }

    , renderTopBar: function() {
    }
});

sa.view.Popup = sa.view.Window.extend({

    className: 'ai-window-wrap ai-popup-wrap ai-invisible'

    , hide: function() {
        $(this.el).addClass('ai-invisible');
        this.trigger('afterhide', this);
    }

    , show: function() {
        var rect = this.el.getBoundingClientRect();
        var view = document.documentElement;
        var left = view.scrollLeft + (view.clientWidth - rect.width)/2;
        var top = (view.scrollTop + (view.clientHeight - rect.height)/2 
                   - view.clientHeight / 4);
        return this.showAt(left, Math.max(0, top));
    }

    , showAt: function(leftHint, topHint) {
        var root = document.documentElement;
        $(this.el).removeClass('ai-invisible');
        var left = leftHint,
            width = $(this.el).width();
        if(left + width > root.scrollWidth) {
            left = root.scrollWidth - width - 5;
        }
        var top = topHint,
            height = $(this.el).height();
        if(top + height > root.scrollHeight) {
            top = root.scrollHeight - height - 5;
        }
        $(this.el).css('top', top+'px').css('left', left+'px');
        this.trigger('aftershow', this);
        return this;
    }

    , showNearEvent: function(event) {
        // TODO show popup at co-ordinates relative to the event.
        throw new Error("Not Implemented showNearEvent()");
    }

});

sa.view.ListPopup = sa.view.Popup.extend({

    listOptionsDefauls: {}

    , options: {
        listClass: sa.view.List
    }

    , renderBody: function() {
        // TODO render list inside popup
    }
});

sa.view.SearchableListPopup = sa.view.ListPopup.extend({

    options: {
        listClass: sa.view.SearchableList
    }

});

sa.view.Tab = sa.view.Base.extend({
    
    active: false

    , className: 'tab-wrap hidden'

    , view: null

    , lazy: false

    , rendered: false
    
    , activate: function() {
        this.rendered || this.render2();
        $(this.el).removeClass('hidden');
        $(this.handle).addClass('active');
        this.active = true;
    }

    , deactivate: function() {
        $(this.el).addClass('hidden');
        $(this.handle).removeClass('active');
        this.active = false;
    }

    , getTitle: function() {
        return sa.encodeSafeHTML(this.view.getTabTitle());
    }

    , initialize: function(options) {
        this.handle = options.handle;
        this.lazy = options.lazy || this.lazy;
        this.view = options.view;
        this.view.bind('change:title', this.renderTitle, this);
    }

    , render: function() {
        ((this.options.lazy && this.active) || this.active) || this.render2(); 
        this.renderTitle();
        return this;
    }

    , render2: function() {
        this.rendered = true;
        $(this.el).append(this.view.render().el);
    }

    , renderTitle: function() {
        this.setTitle(this.getTitle());
    }

    , setHandle: function(handle) {
        this.handle = handle;
    }

    , setTitleHTML: function(titleHTML) {
        $('a', this.handle).html(titleHTML);
    }

    , setTitle: function(title) {
        this.setTitleHTML(sa.encodeSafeHTML(title));
    }

});

sa.view.Tabset = sa.view.Base.extend({

    at: function(index) {
        return this.tabViews[index];
    }

    , initialize: function(options) {
        this.tabHandles = [];
        this.tabViews = [];
        this.tabCollection = options.tabCollection;
        this.TabContentView = options.TabContentView || this.TabContentView;
        this.TabView = options.TabView || this.TabView;
        this.selectedTabIndex = 0;

        $(this.el).delegate('.tabs a', {
            'click': _.bind(this._onTabHandleClick, this)
        });

    }

    , prevThis: null

    , _onTabHandleClick: function(event) {
        if(event.type == 'keypress' && event.keyCode != 13) return;

        Backbone.history.navigate($(event.target).attr('path'), true);
    }

    , render: function() {
        var $el = $(this.el);

        this.elHandles = this.make('ul', {
            'class': 'tabs'
        });
        $el.append(this.elHandles);

        this.elBody = this.make('div', {
            'class': 'tabs-body'
        });
        $el.append(this.elBody);

        _.each(this.options.tabs, this.addTab, this);

        this.selectTab(0);

        return this;
    }

    , addTab: function(tab, path) {
        var handle = this.make('li');
        $(handle).append(this.make('a', {
            href: '#'
            , onclick: 'return false;'
            , path: path        // TODO store path so that we show that when ready
        }));
        $(this.elHandles).append(handle);

        tab.setHandle(handle);

        $(this.elBody).append(tab.render().el);
        this.tabViews.push(tab);
    }

    , selectTab: function(index) {
        var oldTab = this.tabViews[this.selectedTabIndex];
        oldTab.deactivate();

        var newTab = this.tabViews[index];
        newTab.activate();

        this.selectedTabIndex = index;
    }

});

