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

/*@
Ox.InputGroup <f:Ox.Element> InputGroup Object
    () ->              <f> InputGroup Object
    (options) ->       <f> InputGroup Object
    (options, self) -> <f> InputGroup Object
    options <o> Options object
        id     <s|''> id
        inputs <a|[]> inputs
        separators <a|[]> seperators
        width <n|0> width
    self    <o> shared private variable
@*/

Ox.InputGroup = function(options, self) {
    var self = self || {},
        that = new Ox.Element({}, self)
            .defaults({
                id: '',
                inputs: [],
                separators: [],
                width: 0
            })
            .options(options || {})
            .addClass('OxInputGroup')
            .click(click);

    if (self.options.width) {
        setWidths();
    } else {
        self.options.width = getWidth();
    }
    that.css({
        width: self.options.width + 'px'
    });

    $.extend(self, {
        //$input: [],
        $separator: []
    });

    self.options.separators.forEach(function(v, i) {
        self.options.id == 'debug' && Ox.print('separator #' + i + ' ' + self.options.inputs[i].options('id') + ' ' + self.options.inputs[i].options('width'))
        self.$separator[i] = new Ox.Label({
            textAlign: 'center',
            title: v.title,
            width: v.width + 32
        })
        .addClass('OxSeparator')
        .css({
            marginLeft: (self.options.inputs[i].options('width') - (i == 0 ? 16 : 32)) + 'px'
        })
        .appendTo(that);
    });

    self.options.inputs.forEach(function($input, i) {
        $input.options({
                id: self.options.id + Ox.toTitleCase($input.options('id')),
                parent: that
            })
            .css({
                marginLeft: -Ox.sum($.map(self.options.inputs, function(v_, i_) {
                    return i_ > i ? self.options.inputs[i_ - 1].options('width') +
                        self.options.separators[i_ - 1].width : (i_ == i ? 16 : 0);
                })) + 'px'
            })
            .bindEvent({
                change: change,
                submit: change,
                validate: validate
            })
            .appendTo(that);
    });

    function change(event, data) {
        //Ox.print('InputGroup change')
        // fixme: would be good to pass a value here
        that.triggerEvent('change');
    }

    function click(event) {
        if ($(event.target).hasClass('OxSeparator')) {
            self.options.inputs[0].focusInput();
        }
    }

    function getWidth() {
        return Ox.sum($.map(self.options.inputs, function(v, i) {
            return v.options('width');
        })) + Ox.sum($.map(self.options.separators, function(v, i) {
            return v.width;
        })) + 2; // fixme: why + 2?
    }

    function setWidths() {
        var length = self.options.inputs.length,
            inputWidths = Ox.divideInt(
                self.options.width - Ox.sum($.map(self.options.separators, function(v, i) {
                    return v.width;
                })), length
            );
        self.options.inputs.forEach(function(v) {
            v.options({
                width: inputWidths[1]
            });
        });
    }

    function validate(event, data) {
        //Ox.print('INPUTGROUP TRIGGER VALIDATE')
        that.triggerEvent('validate', data);
    }

    // fixme: is this used?
    that.getInputById = function(id) {
        var input = null;
        Ox.forEach(self.options.inputs, function(v, i) {
            //Ox.print(v, v.options('id'), id)
            if (v.options('id') == self.options.id + Ox.toTitleCase(id)) {
                input = v;
                return false;
            }
        });
        return input;
    };

    that.value = function() {
        return $.map(self.options.inputs, function(input) {
            var ret = null;
            ['checked', 'selected', 'value'].forEach(function(v) {
                input[v] && (ret = input[v]());
            });
            return ret;
        });
    };

    return that;

};