'use strict';

Ox.ObjectArrayInput = function(options, self) {

    self = self || {};
    var that = Ox.Element({}, self)
        .defaults({
            buttonTitles: {add: 'Add', remove: 'Remove'},
            inputs: [],
            labelWidth: 128,
            max: 0,
            value: [],
            width: 256
        })
        .options(options || {})
        .addClass('OxObjectArrayInput');

    if (self.options.value.length == 0) {
        self.options.value = [{}];
        self.options.inputs.forEach(function(input) {
            self.options.value[0][input.options.id] = '';
        });
    }

    self.$element = [];
    self.$input = [];
    self.$removeButton = [];
    self.$addButton = [];
    self.buttonWidth = self.options.width / 2 - 4;

    self.options.value.forEach(function(value, i) {
        addInput(i, value);
    });

    function addInput(index, value) {
        self.$element.splice(index, 0, Ox.Element()
            .css({
                width: self.options.width + 'px',
                height: (self.options.inputs.length + 1) * 24 - 8 + 'px'
            })
        );
        if (index == 0) {
            self.$element[index].appendTo(that);
        } else {
            self.$element[index].insertAfter(self.$element[index - 1]);
        }
        self.$input.splice(index, 0, Ox.ObjectInput({
                elements: self.options.inputs.map(function(input) {
                    return Ox[input.element](input.options || {})
                        .bindEvent(input.events || {});
                }),
                labelWidth: self.options.labelWidth,
                width: self.options.width
            })
            .bindEvent({
                change: function(data) {
                    // ...
                }
            })
            .appendTo(self.$element[index])
        );
        self.$removeButton.splice(index, 0, Ox.Button({
                disabled: self.$input.length == 1,
                title: self.options.buttonTitles.remove,
                width: self.buttonWidth
            })
            .css({float: 'left', margin: '8px 4px 0 0'})
            .bind({
                click: function() {
                    var index = $(this).parent().data('index');
                    if (self.$input.length > 1) {
                        removeInput(index);
                    }
                }
            })
            .appendTo(self.$element[index])
        );
        self.$addButton.splice(index, 0, Ox.Button({
                disabled: index == self.options.max - 1,
                title: self.options.buttonTitles.add,
                width: self.buttonWidth
            })
            .css({float: 'left', margin: '8px 0 0 4px'})
            .bind({
                click: function() {
                    var index = $(this).parent().data('index');
                    addInput(index + 1);
                }
            })
            .appendTo(self.$element[index])
        );
        updateInputs();
    }

    function removeInput(index) {
        [
            'input', 'removeButton', 'addButton', 'element'
        ].forEach(function(element) {
            var key = '$' + element;
            self[key][index].remove();
            self[key].splice(index, 1);
        });
        updateInputs();
    }

    function updateInputs() {
        var length = self.$element.length;
        self.$element.forEach(function($element, i) {
            $element
                [i == 0 ? 'addClass' : 'removeClass']('OxFirst')
                [i == length - 1 ? 'addClass' : 'removeClass']('OxLast')
                .data({index: i});
            self.$removeButton[i].options({
                disabled: length == 1,
            });
            self.$addButton[i].options({
                disabled: length == self.options.max
            });
        });
    }

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

    // FIXME: remove
    that.value = function() {
        return self.$input.map(function($input) {
            return $input.value();
        });
    };

    return that;

};