import ngModule from '../../module';
import Component from '../../lib/component';

/**
 * Base component for form inputs.
 *
 * @property {String} label Label to display along the component
 * @property {any} field The value with which the element is linked
 * @property {Boolean} disabled Put component in disabled mode
 */
export default class FormInput extends Component {
    $onInit() {
        // XXX: Compatibility with old inputs
        let attrs = this.$element[0].attributes;
        if (!this.name && attrs['ng-model']) {
            let split = attrs['ng-model'].nodeValue.split('.');
            this.name = split[split.length - 1];
        }

        if (!this.ngModel) return;
        this.ngModel.$render = () => {
            this.field = this.ngModel.$viewValue;
        };
    }

    set field(value) {
        this._field = value;

        if (this.ngModel)
            this.ngModel.$setViewValue(value);
    }

    get field() {
        return this._field;
    }

    set name(value) {
        this.element.setAttribute('name', value);
    }

    get name() {
        return this.element.getAttribute('name');
    }

    set disabled(value) {
        this._disabled = boolTag(value);
        this.classList.toggle('disabled', this._disabled);
        if (this.input)
            this.input.disabled = this._disabled;
        this.refreshTabIndex();
    }

    get disabled() {
        return this._disabled;
    }

    set readonly(value) {
        this._readonly = boolTag(value);
        this.classList.toggle('readonly', this._readonly);
        if (this.input)
            this.input.readOnly = this._readonly;
    }

    get readonly() {
        return this._readonly;
    }

    set tabIndex(value) {
        this._tabIndex = value;
        this.refreshTabIndex();
    }

    get tabIndex() {
        return this._tabIndex;
    }

    get inputEl() {
        return this.input || this.element;
    }

    get editable() {
        return !(this.readonly || this.disabled);
    }

    select() {
        if (this.inputEl.select)
            this.inputEl.select();
    }

    focus() {
        this.inputEl.focus();
    }

    initTabIndex() {
        if (!this.element.hasAttribute('tabindex'))
            this.element.tabIndex = 0;
    }

    refreshTabIndex() {
        this.inputEl.tabIndex = this.disabled ? -1 : this.tabIndex;
    }

    change(value) {
        this.field = value;
        this.element.dispatchEvent(new Event('change'));
        this.emit('change', {value: this.field});
    }
}

ngModule.vnComponent('vnFormInput', {
    controller: FormInput,
    bindings: {
        label: '@?',
        field: '=?',
        name: '@?',
        disabled: '<?',
        readonly: '<?',
        tabIndex: '<?'
    },
    require: {
        ngModel: '?ngModel'
    }
});

function boolTag(value) {
    return Boolean(value || value === '');
}