// vim: et:ts=4:sw=4:sts=4:ft=javascript
/*@
Ox.Button <f:Ox.Element> Button Object
    () ->              <f> Button Object
    (options) ->       <f> Button Object
    (options, self) -> <f> Button Object
    options <o> Options object
        disabled   <b|false> disabled
        group      <b|false> is part of group
        id:        <s|''> button id
        overlap    <s|none> overlap
        selectable <b|false> is selecatable
        selected   <b|false> is selected
        size       <s|medium> button size
        style      <s|default> // can be default, checkbox, symbol, or tab
        title      <s|a|''> title, can be array of titles
        tooltip    <s|a|''> tooltip if multiple must be same number as titles
        type <s|text>   button type, text or image, (for image, title must be symbolTitle.svg must be availabe)
        width <s|auto>  button width
    self <o>    Shared private variable
    click    <!> non-selectable button was clicked
    deselect <!> selectable button was deselected
    select   <!> selectable button was selected
@*/

Ox.Button = function(options, self) {

    self = self || {};
    var that = Ox.Element('<input>', self)
            .defaults({
                disabled: false,
                group: false,
                id: '',
                overlap: 'none',
                selectable: false,
                selected: false,
                size: 'medium',
                // fixme: 'default' or ''?
                style: 'default', // can be default, checkbox, symbol, or tab
                title: '',
                tooltip: '',
                type: 'text',
                width: 'auto'
            })
            .options(options || {})
            .attr({
                disabled: self.options.disabled ? 'disabled' : '',
                type: self.options.type == 'text' ? 'button' : 'image'
            })
            .addClass('OxButton Ox' + Ox.toTitleCase(self.options.size) +
                (self.options.disabled ? ' OxDisabled': '') +
                (self.options.selected ? ' OxSelected': '') +
                (self.options.style != 'default' ? ' Ox' + Ox.toTitleCase(self.options.style) : '') +
                (self.options.overlap != 'none' ? ' OxOverlap' + Ox.toTitleCase(self.options.overlap) : ''))
            .css(self.options.width == 'auto' ? {} : {
                width: (self.options.width - 14) + 'px'
            })
            .mousedown(mousedown)
            .click(click);

    $.extend(self, Ox.isArray(self.options.title) ? {
        selectedTitle: Ox.setPropertyOnce(self.options.title, 'selected'),
        titles: self.options.title
    } : {
        selectedTitle: 0,
        titles: [{
            id: '',
            title: self.options.title
        }]
    });

    setTitle(self.titles[self.selectedTitle].title);

    if (self.options.tooltip) {
        self.tooltips = Ox.isArray(self.options.tooltip) ? self.options.tooltip : [self.options.tooltip];
        self.$tooltip = Ox.Tooltip({
                title: self.tooltips[self.selectedTitle]
            });
        that.mouseenter(mouseenter)
            .mouseleave(mouseleave);
    }

    function click() {
        if (!self.options.disabled) {
            var data = self.titles[self.selectedTitle];
            if (!self.options.selectable) {
                that.triggerEvent('click', data);
            } else {
                //self.options.selected = !self.options.selected;
                //that.toggleClass('OxSelected');
                if (self.options.group) {
                    that.triggerEvent('select', data);
                } else {
                    that.toggleSelected();
                    //that.triggerEvent('change', {selected: self.options.selected});
                }
            }
            if (self.titles.length == 2) {
                that.toggleTitle();
            }
        }
    }

    function mousedown(e) {
        if (self.options.type == 'image' && $.browser.safari) {
            // keep image from being draggable
            e.preventDefault();
        }
    }

    function mouseenter(e) {
        self.$tooltip.show(e.clientX, e.clientY);
    }

    function mouseleave() {
        self.$tooltip.hide();
    }

    function setTitle(title) {
        self.title = title;
        if (self.options.type == 'image') {
            that.attr({
                src: Ox.UI.getImagePath(
                    'symbol' + title[0].toUpperCase() + title.substr(1) + '.svg'
                )
            });
        } else {
            that.val(title);
        }
    }

    self.setOption = function(key, value) {
        if (key == 'disabled') {
            that.attr({
                    disabled: value ? 'disabled' : ''
                })
                .toggleClass('OxDisabled');
        } else if (key == 'selected') {
            if (value != that.hasClass('OxSelected')) { // fixme: neccessary?
                that.toggleClass('OxSelected');
            }
            that.triggerEvent('change');
        } else if (key == 'title') {
            setTitle(value);
        } else if (key == 'width') {
            that.$element.css({
                width: (value - 14) + 'px'
            });
        }
    }

    /*@
    toggleDisabled <f>
        () -> <u> toggle disabled state
    @*/
    that.toggleDisabled = function() {
        that.options({
            disabled: !self.options.disabled
        });
        return that;
        //self.options.disabled = !self.options.disabled;
    }

    /*@
    toggleSelected <f>
        () -> <u> toggle selected state
    @*/
    that.toggleSelected = function() {
        that.options({
            selected: !self.options.selected
        });
        return that;
        //self.options.selected = !self.options.selected;
    }

    /*@
    toggleTitle <f>
        () -> <u> toggle through titles
    @*/
    that.toggleTitle = function() {
        self.selectedTitle = 1 - self.selectedTitle;
        setTitle(self.titles[self.selectedTitle].title);
        self.$tooltip && self.$tooltip.options({
            title: self.tooltips[self.selectedTitle]
        });
        return that;
    }

    return that;

};