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

/*@
Ox.Select <f:Ox.Element> Select Object
    () ->              <f> Select Object
    (options) ->       <f> Select Object
    (options, self) -> <f> Select Object
    options <o> Options object
        id <s> element id
        items <a|[]> items
        max <n|1> minimum number of selected items
        min <n|1> maximum number of selected items
        overlap <s|'none'> can be none, left or right
        selectable <b|true> is selectable
        size <s|'medium'> size, can be small, medium, large
        title <s|''> select title
        type <s|'text'> can be 'text' or 'image'
        width <s|n|'auto'> can be auto or width in pixels
    self    <o> shared private variable
    click <!> on click event
    change <!> on change event
@*/

Ox.Select = function(options, self) {

    // fixme: selected item needs attribute "checked", not "selected" ... that's strange
    var self = self || {},
        that = new Ox.Element({
                tooltip: options.tooltip || ''
            }, self)
            .defaults({
                id: '',
                items: [],
                max: 1,
                min: 1,
                overlap: 'none', // can be none, left or right
                selectable: true,
                size: 'medium',
                title: '',
                type: 'text', // can be 'text' or 'image'
                width: 'auto',
                value: [],
            })
            // fixme: make default selection restorable
            // or allow for extra action items below options
            .options(options)
            .addClass(
                'OxSelect Ox' + Ox.toTitleCase(self.options.size) +
                (self.options.overlap == 'none' ? '' : ' OxOverlap' +
                Ox.toTitleCase(self.options.overlap))
            )
            .css(self.options.width == 'auto' ? {} : {
                width: self.options.width + 'px'
            })
            .bindEvent({
                key_escape: loseFocus,
                key_down: showMenu
            });

    Ox.print('Ox.Select', self.options)

    $.extend(self, {
        buttonId: self.options.id + 'Button',
        groupId: self.options.id + 'Group',
        menuId: self.options.id + 'Menu'
    });

    if (self.options.selectable) {
        self.optionGroup = new Ox.OptionGroup(
            self.options.items,
            self.options.min,
            self.options.max
        );
        self.options.items = self.optionGroup.init();
        self.checked = self.optionGroup.checked();
    }

    if (self.options.label) {
        self.$label = Ox.Label({
            overlap: 'right',
            textAlign: 'right',
            title: self.options.label,
            width: self.options.labelWidth
        })
        .click(function() {
            // fixme: ???
            // that.focus();
        })
        .appendTo(that);
    };

    if (self.options.type == 'text') {
        self.$title = $('<div>')
            .addClass('OxTitle')
            .css({
                width: (self.options.width - 22 - (
                    self.options.label ? self.options.labelWidth : 0
                )) + 'px'
            })
            .html(
                self.options.title ? self.options.title :
                self.options.items[self.checked[0]].title
            )
            .click(showMenu)
            .appendTo(that.$element);
    }

    self.$button = new Ox.Button({
            id: self.buttonId,
            style: 'symbol',
            title: 'select',
            type: 'image'
        })
        .bindEvent('click', showMenu)
        .appendTo(that);

    self.$menu = new Ox.Menu({
            element: self.$title || self.$button,
            id: self.menuId,
            items: [self.options.selectable ? {
                group: self.groupId,
                items: self.options.items,
                max: self.options.max,
                min: self.options.min
            } : self.options.items],
            side: 'bottom',
            size: self.options.size
        })
        .bindEvent({
            change: changeMenu,
            click: clickMenu,
            hide: hideMenu
        });

    self.options.type == 'image' && self.$menu.addClass('OxRight');

    function clickMenu(event, data) {
        that.triggerEvent('click', data);
    }

    function changeMenu(event, data) {
        //Ox.print('clickMenu: ', self.options.id, data)
        self.checked = self.optionGroup.checked();
        self.$title && self.$title.html(
            self.options.title ? self.options.title :
                    data.checked[0].title
        );
        that.triggerEvent('change', {
            selected: data.checked
        });
    }

    function hideMenu() {
        //Ox.print('%% hideMenu that', that, 'self', self)
        that.removeClass('OxSelected');
        // self.$button.removeClass('OxSelected');
        //Ox.print('%% hideMenu end')
    }

    function loseFocus() {
        that.loseFocus();
    }

    function showMenu() {
        that.gainFocus();
        that.addClass('OxSelected');
        self.options.tooltip && that.$tooltip.hide();
        self.$menu.showMenu();
    }

    self.setOption = function(key, value) {
        if (key == 'value') {
            that.selectItem(value);
        }
    };

    /*@
    selectItem <f> select item in group
        () -> <o> returns object of selected items with id, title
    @*/
    that.selected = function() {
        return $.map(/*self.checked*/self.optionGroup.checked(), function(v) {
            return {
                id: self.options.items[v].id,
                title: self.options.items[v].title
            };
        });
    };

    /*@
    selectItem <f> select item in group
        (id) -> <u> select item by id
        id <s> item id
    @*/
    that.selectItem = function(id) {
        Ox.print('selectItem', id, Ox.getObjectById(self.options.items, id).title)
        self.options.type == 'text' && self.$title.html(
            Ox.getObjectById(self.options.items, id).title[0] // fixme: title should not have become an array
        );
        self.$menu.checkItem(id);
        self.checked = self.optionGroup.checked();
    };

    /*
    that.width = function(val) {
        // fixme: silly hack, and won't work for css() ... remove!
        that.$element.width(val + 16);
        that.$button.width(val);
        //that.$symbol.width(val);
        return that;
    };
    */

    that.value = function() {
        if (arguments.length == 0) {
            Ox.print('selected::', that.selected())
            return that.selected()[0].id;
        } else {
            /*
            Ox.print('ELSE');
            that.selectItem(arguments[0]);
            return that;
            */
        }
    };

    return that;

};