/**
 * Custom category attribute configuration popup
 */
window.AttributeConfigurationPopup = Class.create({
    initialize: function ($el, options) {
        var that = this, i;

        this.$root = $el;
        this.$fieldType = this.$root.down('[name="field_type"]');
        this.$fieldTitle = this.$root.down('[name="field_title"]');
        this.$fieldTitleMultiline = this.$root.down('[name="field_title_multiline"]');
        this.$fieldVisibility = this.$root.down('[name="field_visibility"]');
        // "Extra" fields.
        this.$fieldIdentifier = this.$root.down('[name="field_identifier"]');
        this.$fieldDialogDefault = this.$root.down('[name="field_dialog_default"]');
        this.$fieldRelation = this.$root.down('[name="field_relation"]');
        this.$fieldReport = this.$root.down('[name="field_report"]');
        this.$fieldDependency = this.$root.down('[name="field_dialog_dependency"]');
        this.$fieldLinkedTo = this.$root.down('[name="field_dialog_linked_to"]');
        this.$fieldShowInList = this.$root.down('[name="field_show_in_list"]');
        // Misc elements.
        this.$notice = this.$root.down('.notice');

        this.options = {
            dialogYesNoDefaults: [],
            calendarDefaults:    [],
            singleLineFields:    [],
            aceInstance:         null,
            badIdentifierWords:  []
        };

        Object.extend(this.options, options || {});

        this.setObserver();

        // Simulate a type change to prepare the necessary fields.
        this.$fieldType.simulate('change');

        return this;
    },

    setObserver: function () {
        const that = this;

        this.$fieldType.on('change', function () { that.changeFieldType(); });
        this.$fieldIdentifier.on('change', function () { that.changeIdentifier(); }); // @see ID-11427
        this.$fieldDependency.on('change', function () { that.changeDependency(); });
    },

    getConfiguration: function () {
        const fieldType = this.$fieldType.getValue();

        const fieldTitle = ['html', 'script'].include(fieldType)
            ? this.$fieldTitleMultiline.getValue()
            : this.$fieldTitle.getValue();

        const linkedTo = this.$fieldDependency.getValue() == -1
            ? null
            : this.$fieldLinkedTo.getValue();

        // Only get the 'relation' field as identifier, if we are handling relation object browsers.
        const fieldIdentifier = fieldType.indexOf('f_popup,browser_object,1') === 0
            ? this.$fieldRelation.getValue()
            : fieldType === 'f_popup,report_browser'
                ? this.$fieldReport.getValue()
                : this.$fieldIdentifier.getValue()

        return {
            fieldType:           fieldType,
            fieldTitle:          fieldTitle,
            fieldTitleMultiline: this.$fieldTitleMultiline.getValue(),
            fieldVisibility:     this.$fieldVisibility.getValue(),
            fieldIdentifier:     fieldIdentifier,
            fieldDialogDefault:  this.$fieldDialogDefault.getValue(),
            fieldDependency:     this.$fieldDependency.getValue(),
            fieldLinkedTo:       linkedTo,
            fieldShowInList:     this.$fieldShowInList ? this.$fieldShowInList.getValue() : null
        };
    },

    changeFieldType: function () {
        var temporaryValue;
        const fieldTypeValue = this.$fieldType.getValue();
        const fieldTypeValueParts = fieldTypeValue.split(',');
        const fieldTypeName = this.$fieldType.down(':selected').textContent;

        // Show or hide the "one element per row" notice.
        if (this.options.singleLineFields.include(fieldTypeValue)) {
            const notice = idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__ONE_ELEMENT_PER_ROW').replace('%s', fieldTypeName);

            idoit.Notify.info(notice);
            this.$notice.down('span').update(notice);
            this.$notice.removeClassName('hide');
        } else {
            this.$notice.down('span').update('');
            this.$notice.addClassName('hide');
        }

        // Enable or disable the visibility field, according to the field type.
        if (!['f_text', 'f_popup', 'f_password', 'f_link', 'f_time', 'f_textarea', 'f_dialog'].include(fieldTypeValueParts[0])) {
            this.$fieldVisibility
                .setValue('visible')
                .disable();
        } else {
            this.$fieldVisibility
                .enable();
        }

        // Hide and disable all "extra" fields by default.
        this.$fieldIdentifier.addClassName('hide').disable();
        this.$fieldDialogDefault.addClassName('hide').disable();
        this.$fieldRelation.addClassName('hide').disable();
        this.$fieldReport.addClassName('hide').disable();
        this.$fieldDependency.disable().up('tr').addClassName('hide');
        this.$fieldLinkedTo.disable().up('tr').addClassName('hide');

        // Select the temporary value of the field, that is currently not hidden.
        temporaryValue = this.$fieldTitle.hasClassName('hide')
            ? this.$fieldTitleMultiline.getValue()
            : this.$fieldTitle.getValue();

        // Switching textareas and input fields for HTML and SCRIPT elements.
        if (['html', 'script'].include(fieldTypeValue)) {
            // Show the 'multi-line' field (ace instance).
            this.$root.down('[data-type="single-line"]').addClassName('hide');
            this.$root.down('[data-type="multi-line"]').removeClassName('hide');

            this.$fieldTitle.disable()
            this.$fieldTitleMultiline.enable()

            if (this.options.aceInstance) {
                if (fieldTypeValue === 'html') {
                    this.options.aceInstance.session.setOption('mode', 'ace/mode/html');
                } else {
                    this.options.aceInstance.session.setOption('mode', 'ace/mode/javascript');
                }
            }

            this.$fieldTitleMultiline.setValue(temporaryValue);
        } else {
            // Show the 'single-line' field (basic input).
            this.$root.down('[data-type="single-line"]').removeClassName('hide');
            this.$root.down('[data-type="multi-line"]').addClassName('hide');

            this.$fieldTitle.enable()
            this.$fieldTitleMultiline.disable()

            this.$fieldTitle.setValue(temporaryValue);
        }

        if (fieldTypeValueParts[0] === 'f_dialog' && fieldTypeValueParts[1] === 'yes-no') {
            this.$fieldDialogDefault
                .removeClassName('hide')
                .enable();

            this.fillSelectValues(this.$fieldDialogDefault, this.$fieldDialogDefault.getValue(), this.options.dialogYesNoDefaults);

            return;
        }

        if (fieldTypeValueParts[0] === 'f_popup') {
            // Only show the dependency field for single-value dialog+ values, if there are possible linked fields.
            if (fieldTypeValueParts[1] === 'dialog_plus' && (!fieldTypeValueParts.hasOwnProperty(2) || !fieldTypeValueParts[2])) {
                this.$fieldDependency.up('tr').removeClassName('hide');
                this.$fieldLinkedTo.up('tr').removeClassName('hide');

                // Only allow dependencies, when the field has been saved previously (= is not changeable).
                if (this.$fieldLinkedTo.select('option').length > 1 && this.$fieldType.down('option').disabled) {
                    this.$fieldDependency.enable();
                    this.$fieldLinkedTo.enable();

                    // Simulate a change to trigger some logic.
                    this.$fieldDependency.simulate('change');
                }
            }

            if (fieldTypeValueParts[1] === 'report_browser') {
                this.$fieldReport.removeClassName('hide').enable();
                return;
            }

            if (fieldTypeValueParts[1] === 'dialog_plus' || fieldTypeValueParts[1] === 'checkboxes') {
                this.$fieldIdentifier.removeClassName('hide').enable();
                return;
            }

            if (fieldTypeValueParts[1] === 'file') {
                this.$fieldIdentifier.removeClassName('hide');
                return;
            }

            if (fieldTypeValueParts[1] === 'browser_object') {
                if (fieldTypeValueParts[2] == 1) {
                    this.$fieldRelation.removeClassName('hide').enable();
                    return;
                }

                this.$fieldIdentifier.removeClassName('hide');
                return;
            }

            this.$fieldDialogDefault
                .removeClassName('hide')
                .enable();

            this.fillSelectValues(this.$fieldDialogDefault, this.$fieldDialogDefault.getValue(), this.options.calendarDefaults);

            return;
        }

        // Display the disabled identifier.
        this.$fieldIdentifier.removeClassName('hide');
    },

    changeIdentifier: function () {
        const currentIdentifier = this.$fieldIdentifier.getValue();
        const replaceRegex = RegExp(this.options.badIdentifierWords.join('|'), 'gi');
        const cleanedIdentifier = currentIdentifier.replace(replaceRegex, '');

        if (currentIdentifier === cleanedIdentifier) {
            return;
        }

        idoit.Notify.info(
            idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__IDENTIFIER_CHANGED').replace('%s', this.options.badIdentifierWords.join(', ')),
            { sticky: true }
        );

        this.$fieldIdentifier.setValue(cleanedIdentifier);
    },

    changeDependency: function () {
        this.$fieldLinkedTo.disable();

        if (this.$fieldDependency.getValue() != -1) {
            this.$fieldLinkedTo.enable();
        }
    },

    fillSelectValues: function ($select, selectedValue, options) {
        var i;

        $select.update();

        for (i in options) {
            if (!options.hasOwnProperty(i)) {
                continue;
            }

            $select.insert(new Element('option', { value: i }).update(options[i]));
        }

        $select.setValue(selectedValue);
    }
});
