// vim: et:ts=4:sw=4:sts=4:ft=javascript

'use strict';

/*@
Ox.CollapsePanel <f:Ox.Panel> CollapsePanel Object
    () ->              <f> CollapsePanel Object
    (options) ->       <f> CollapsePanel Object
    (options, self) -> <f> CollapsePanel Object
    options <o> Options object
        collapsed <b|false> collapsed state
        extras <a|[]> panel extras
        size <n|16> size
        title <s> title
    self    <o> shared private variable
@*/

Ox.CollapsePanel = function(options, self) {

    self = self || {};
    var that = Ox.Panel({}, self)
            .defaults({
                animate: true,
                collapsed: false,
                extras: [],
                size: 16,
                title: ''
            })
            .options(options)
            .addClass('OxCollapsePanel');

    self.$titlebar = Ox.Bar({
            orientation: 'horizontal',
            size: self.options.size,
        })
        .bindEvent({
            doubleclick: doubleclickTitlebar
        })
        .appendTo(that);

    self.$button = Ox.Button({
            style: 'symbol',
            type: 'image',
            value: self.options.collapsed ? 'expand' : 'collapse',
            values: [
                {id: 'expand', title: 'right'},
                {id: 'collapse', title: 'down'}
            ]
        })
        .bindEvent({
            click: toggleCollapsed
        })
        .appendTo(self.$titlebar);

    self.$title = Ox.Element()
        .addClass('OxTitle')
        .html(self.options.title)
        .appendTo(self.$titlebar);

    if (self.options.extras.length) {
        self.$extras = Ox.Element()
            .addClass('OxExtras')
            .css({width: self.options.extras.length * 16 + 1 + 'px'})
            .appendTo(self.$titlebar);
        self.options.extras.forEach(function($extra) {
            $extra.appendTo(self.$extras);
        });
    }

    that.$content = Ox.Element()
        .addClass('OxContent')
        .appendTo(that);
    // fixme: doesn't work, content still empty
    // need to hide it if collapsed
    if (self.options.collapsed) {
        that.$content.css({
            marginTop: -that.$content.height() + 'px'
        }).hide();
    }

    function doubleclickTitlebar(e) {
        if (!$(e.target).hasClass('OxButton')) {
            self.$button.trigger('click');
        }
    }

    function toggleCollapsed() {
        // show/hide is needed in case the collapsed content
        // grows vertically when shrinking the panel horizontally
        var marginTop;
        self.options.collapsed = !self.options.collapsed;
        marginTop = self.options.collapsed ? -that.$content.height() : 0;
        !self.options.collapsed && that.$content.css({
            marginTop: -that.$content.height() + 'px'
        }).show();
        if (self.options.animate) {
            that.$content.animate({
                marginTop: marginTop + 'px'
            }, 250, function() {
                self.options.collapsed && that.$content.hide();
            });
        } else {
            that.$content.css({
                marginTop: marginTop + 'px'
            });
            self.options.collapsed && that.$content.hide();
        }
        that.triggerEvent('toggle', {
            collapsed: self.options.collapsed
        });
    }

    /*@
    setOption <f> setOption
        (key, value) -> <u> set key to value
    @*/
    self.setOption = function(key, value) {
        if (key == 'collapsed') {
            // will be toggled again in toggleCollapsed
            self.options.collapsed = !self.options.collapsed;
            self.$button.toggle();
            toggleCollapsed();
        } else if (key == 'title') {
            self.$title.html(self.options.title);
        }
    };

    /*@
    update <f> update // fixme: used anywhere?
    @*/
    that.update = function() {
        self.options.collapsed && that.$content.css({
            marginTop: -that.$content.height()
        });
    };

    return that;

};