<div id="custom_fields_configuration">
    [{if isset($g_list)}]
    [{$g_list}]

    <script type="text/javascript">
        var urlParts = document.location.href.parseQuery(),
            $body = $('body'),
            $id;

        if ($body) {
            $id = $body.down('[name="id"]');

            if ($id) {
                $id.setValue(null);
            }
        }

        delete urlParts['[{$smarty.const.C__GET__ID}]'];

        window.history.replaceState(null, document.title, '?' + Object.toQueryString(urlParts));
    </script>
    [{else}]
    <div class="fl">
        <table class="contentTable">
            <tr>
                <td class="key">[{isys type="f_label" name="category_title" ident="LC__UNIVERSAL__CATEGORY_TITLE"}]</td>
                <td class="value">[{isys type="f_text" id="category_title" name="category_title" p_bNoTranslation=true}]</td>
            </tr>
            <tr>
                <td class="key">[{isys type="f_label" name="object_types" ident="LC_UNIVERSAL__OBJECT_TYPES"}]</td>
                <td class="value">[{isys type="f_dialog_list" name="object_types" p_bSort=false}]</td>
            </tr>
            <tr>
                <td class="key">
                    [{isys type="f_label" name="object_types" ident="LC__CMDB__CUSTOM_CATEGORIES__CONSTANT"}]
                    <img title="[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__CONSTANT_INFO"}]" src="[{$dir_images}]axialis/basic/button-info.svg" data-tooltip="1" class="vam">
                </td>
                <td class="value">
                    <div class="input-group input-size-medium ml20">
                        <div class="input-group-addon input-group-addon-unstyled"><code>C__CATG__CUSTOM_FIELDS_</code></div>
                        [{isys type="f_text" name="category_constant" disableInputGroup=true p_bInfoIconSpacer=0}]
                    </div>
                </td>
        </table>
    </div>
    <div class="fl ml20">
        <table class="contentTable">
            <tr>
                <td class="key" style="width: 230px">
                    [{isys type="f_label" name="multivalued" ident="LC__CMDB__CUSTOM_CATEGORIES__LIST_CATEGORY"}]
                    <img title="[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__MULTIVALUE_INFO"}]" src="[{$dir_images}]axialis/basic/button-info.svg" data-tooltip="1" class="vam" />
                </td>
                <td class="value">[{isys type="f_dialog" name="multivalued"}]</td>
            </tr>
            <tr>
                <td class="key">
                    [{isys type="f_label" name="label_position" ident="LC__CMDB__CUSTOM_CATEGORIES__LABEL_POSITION"}]
                    <img title="[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__LABEL_POSITION_INFO"}]" src="[{$dir_images}]axialis/basic/button-info.svg" data-tooltip="1" class="vam">
                </td>
                <td class="value">[{isys type="f_dialog" name="label_position"}]</td>
            </tr>
            <tr>
                <td class="key"></td>
                <td class="value">
                    <button type="button" id="show-api-info" class="btn ml20">
                        <img src="[{$dir_images}]axialis/development/processes.svg" alt="" /><span>[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__SHOW_TECHNICAL_INFO"}]</span>
                    </button>
                </td>
        </table>
    </div>
    <br class="cb" />

    <div class="p10">
        <p class="mb10">
            <img src="[{$dir_images}]axialis/basic/button-info.svg" class="vam mr5" />
            <span class="vam">[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__DESCRIPTION"}]</span>
        </p>

        <button type="button" class="btn fl" id="add_custom_multiple_fields_button">
            <img src="[{$dir_images}]axialis/basic/symbol-add.svg" alt="" /><span>[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__ADD_MULTIPLE_FIELDS"}]</span>
        </button>

        [{isys type="f_count" name="count_of_custom_fields"}]
    </div>

    <div class="p10 cb" id="area">
        <p class="m5 p5">
            <img src="[{$dir_images}]ajax-loading.gif" class="vam mr5" />
            <span class="vam">[{isys type="lang" ident="LC__UNIVERSAL__LOADING"}]</span>
        </p>
    </div>

    <div class="p10">
        [{if is_array($category_config) && count($category_config) && $valueCount > 0}]
        <p class="box-yellow p10 mt10 mb10">
            <img src="[{$dir_images}]axialis/construction/warning-sign.svg" class="vam mr5" /><span class="vam">[{isys type="lang" ident="LC__CMDB__CUSTOM_CATEGORIES__CHANGE_NOTE"}]</span>
        </p>
        [{/if}]

        [{if $entryCount}]
        <div class="box-blue p10 mt10 mb10">
            <h3 class="mb10"><img src="[{$dir_images}]axialis/basic/button-info.svg" class="vam mr5" /><span class="vam">[{isys type="lang" ident="LC__LICENCE_OVERVIEW__STATISTIC"}]</span></h3>
            <p>[{isys type="lang" ident="LC__CMDB__CUSTOM_CATEGORIES__ENTRY_COUNT"}]: <strong>[{$entryCount}]</strong></p>
            <p>[{isys type="lang" ident="LC__CMDB__CUSTOM_CATEGORIES__VALUE_COUNT"}]: <strong>[{$valueCount}]</strong></p>
        </div>
        [{/if}]

        [{if $apiExample}]
        <div id="api-info" class="hide mt20">
            <div class="display-flex">
                <div>
                    <h3 class="mt10">Configuration:</h3>
                    <pre class="box-neutral-200">[{json_encode($apiExampleConfig, JSON_PRETTY_PRINT)}]</pre>
                </div>

                <div class="ml10">
                    <h3 class="mt10">Structure Info:</h3>
                    <pre class="box-neutral-200">{
    "Field Key / Identifier": {
        "type": "Field Type",
        "popup": "Popup Type",
        "title": "Title",
        "identifier": "Group ID",
        "show_in_list": 0/1
    }
}</pre>
                </div>
            </div>

            <h2 class="mt10">API-Examples:</h2>
            <div class="display-flex mt10">
                <div>
                    <h3>Read</h3>
                    <pre class="box-neutral-200">[{json_encode($apiExample.read, JSON_PRETTY_PRINT)}]</pre>
                </div>
                <div class="ml10">
                    <h3>Write</h3>
                    <pre class="box-neutral-200">[{json_encode($apiExample.create, JSON_PRETTY_PRINT)}]</pre>
                </div>
            </div>
        </div>
        [{/if}]
    </div>
</div>

<script type="application/javascript">
    var url = document.location.href.parseQuery(),
        id = parseInt('[{$id}]'),
        $id_field = $N('id')[0],
        $categoryTitle = $('category_title'),
        $categoryConstant = $('category_constant');

    var changeCatConstant = true;
    if ($categoryConstant.value) {
        changeCatConstant = false;
    }

    if ($id_field) {
        $id_field.setValue(id || null);
    }

    url['[{$smarty.const.C__GET__ID}]'] = '[{$id}]';
    url['[{$smarty.const.C__GET__SETTINGS_PAGE}]'] = '[{$smarty.const.C__CUSTOM_FIELDS__CONFIG}]';
    url['[{$smarty.const.C__CMDB__GET__EDITMODE}]'] = 1;

    window.pushState({ }, '', '?' + Object.toQueryString(url));

    (function () {
        var fieldConfiguration    = [],
            field_options         = JSON.parse('[{$propertyTypes|json_encode|escape:"javascript"}]'),
            onelineFields         = field_options
                .filter(function (prop) { return !prop.allowInline; })
                .map(function (prop) { return getType(prop).configValue; })
                .uniq();

        // @see ID-8734 Allow certain types to have no title
        const typesWithoutNames = ['hr', 'f_popup,report_browser'];

        const maxElementsInColl = 4;
        const $area = $('area');
        const $saveButton = $('navbar_item_C__NAVMODE__SAVE');
        const $customFieldCounter = $('count_of_custom_fields');

        const $categoryTitle = $('category_title');
        const $categoryConstant = $('category_constant');

        Position.includeScrollOffsets = true;

        idoit.Translate.set('LC_UNIVERSAL__ACCEPT', '[{isys type="lang" ident="LC_UNIVERSAL__ACCEPT" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__UNIVERSAL__BUTTON_CANCEL', '[{isys type="lang" ident="LC__UNIVERSAL__BUTTON_CANCEL" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_REMOVE', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_REMOVE" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__ONE_ELEMENT_PER_ROW', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__ONE_ELEMENT_PER_ROW" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TITLE', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TITLE" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_ADDITIONAL', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_ADDITIONAL" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__STANDARD', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__STANDARD" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__API_ONLY', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__API_ONLY" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__HIDDEN', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__HIDDEN" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__SHOW_IN_LIST', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__SHOW_IN_LIST" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__CALENDAR_WITH_TIME', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__CALENDAR_WITH_TIME" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__CALENDAR_WITHOUT_TIME', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__CALENDAR_WITHOUT_TIME" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_NONE', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_NONE" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_YES', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_YES" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_NO', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_NO" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_IDENTIFIER', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_IDENTIFIER" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__EMPTY_TITLE_MESSAGE', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__EMPTY_TITLE_MESSAGE" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__TO_MUCH_ELEMENTS', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__TO_MUCH_ELEMENTS" p_bHtmlEncode=false}]');
        idoit.Translate.set('LC__SYSTEM__CUSTOM_CATEGORIES__NEW_FIELD', '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__NEW_FIELD" p_bHtmlEncode=false}]');

        if ($categoryTitle && $categoryConstant) {
            $categoryTitle.on('change', function() {
                if ($categoryConstant.getValue().blank()) {
                    $categoryConstant.setValue($categoryTitle.getValue()).simulate('change');
                }
            });

            $categoryConstant.on('change', function() {
                $categoryConstant.setValue($categoryConstant.getValue().toUpperCase().replace(/(\s|-)+/g, '_').replace(/_{2,}/g, '_').replace(/[^a-z0-9_]/gi, ''));
            });
        }

        function render() {
            const cleanedData = cleanupData();
            var row, col;

            // Clear the "area" with the first row.
            $area.update(new Element('div', { 'data-role': 'row', className:'droppable-row hide' }));

            for (row in cleanedData) {
                if (!cleanedData.hasOwnProperty(row) || cleanedData[row].length == 0) {
                    continue;
                }

                const $row = new Element('div', { 'data-role': 'row' });

                $row.insert(new Element('div', { className:'droppable-col hide', 'data-pos': row + ',0', style:'top:4px; left:-10px; position:absolute;' }));

                for (col in cleanedData[row]) {
                    if (!cleanedData[row].hasOwnProperty(col)) {
                        continue;
                    }

                    const config = cleanedData[row][col];
                    const cssClass = config.title.blank() && typesWithoutNames.indexOf(config.configValue) < 0 ? 'box-red' : '';
                    const type = getType(config);

                    $row
                        .insert(new Element('div', { 'data-role': 'field', 'data-key': config.key, 'data-property-configuration': JSON.stringify(config), 'data-position': row + ',' + col, className: cssClass })
                            .update(new Element('div', { className: 'handle' }))
                            .insert(new Element('div', { className: 'type-and-title' })
                                .update(new Element('p', { className:'text-neutral-400' }).update(type ? type.title : '-'))
                                .insert(new Element('p').update('')))
                            .insert(new Element('button', { type: 'button', className: 'btn btn-secondary popup_options_caller', 'data-tooltip': 1, title: '[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__PROPERTY_EDIT"}]' })
                                .update(new Element('img', { src: window.dir_images + 'axialis/basic/tool-pencil.svg', className:'mouse-pointer' }))))
                        .insert(new Element('div', { className:'droppable-col hide', 'data-pos': row + ',' + (1+parseInt(col)), style:'top:3px; left:' + (((1+parseInt(col))*258) - 18) + 'px; position:absolute;' }));

                    $row.down('.type-and-title p:last').textContent = config.title.substr(0, 75);
                }

                $area
                    .insert($row)
                    .insert(new Element('div', { 'data-role': 'row', className:'droppable-row hide' }));
            }

            // Reset droppables.
            Droppables.drops = [];

            $$('.droppable-row,.droppable-col').each(function ($el) {
                Droppables.add($el, {
                    hoverclass: 'hover',
                    onDrop:     function ($drag, $droppable) {
                        fieldConfiguration = [];

                        $droppable.insert($drag);
                        $$('[data-role="row"]').each(function ($row) {
                            $row.select('[data-role="field"]').each(function ($col, index) {
                                const temp = JSON.parse($col.readAttribute('data-property-configuration'));

                                if (index > 0 && index < maxElementsInColl && !onelineFields.includes(temp.configValue)) {
                                    temp.show_inline = true;
                                } else {
                                    if (index >= maxElementsInColl) {
                                        idoit.Notify.error(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__TO_MUCH_ELEMENTS'), { sticky:true });
                                    }

                                    if (onelineFields.includes(temp.configValue) && index != 0) {
                                        idoit.Notify.error('[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__THIS_ONE_ELEMENT_PER_ROW"}]');
                                    }

                                    temp.show_inline = false;
                                }

                                fieldConfiguration.push(temp);
                            });
                        });

                        render();
                    }
                });
            });

            $$('[data-role="field"]').each(function ($el) {
                new Draggable($el, {
                    revert:  true,
                    zindex: null,
                    onStart: function () {
                        $$('.droppable-col,.droppable-row').invoke('removeClassName', 'hide');
                    },
                    onEnd:   function () {
                        $$('.droppable-col,.droppable-row').invoke('addClassName', 'hide');
                    },
                    handle:  'handle'
                });
            });

            [{if !empty($attributeVisibilityConfigCustom)}]
            idoit.Require.require('attributeVisibility', function () {
                const visibilityOptions = {
                    parentElementType: 'div',
                    selectedAttributeFromConfig: 'id',
                    searchPattern: 'div[data-key="%s"]',
                    itemNamePattern: '%s'
                };
                (new AttributeVisibility(JSON.parse('[{$attributeVisibilityConfigCustom|json_encode|escape:"javascript"}]'), visibilityOptions)).hideAttributes();
            });
            [{/if}]

            // Re-initialize the tooltips.
            $('body').fire('update:tooltips');
        }

        $('show-api-info').on('click', function () {
            $('api-info').toggleClassName('hide');
        });

        $area.on('click', '.popup_options_caller', function (ev) {
            $fieldElement = ev.findElement().up('[data-role="field"]');

            get_popup(
                'custom_fields_attribute_configuration',
                '',
                650,
                400,
                {
                    otherProperties: JSON.stringify(fieldConfiguration.filter((prop) => prop.key != $fieldElement.readAttribute('data-key'))),
                    configuration: $fieldElement.readAttribute('data-property-configuration')
                }
            );
        });

        $area.on('field:remove', function (ev) {
            // Handle possible dependencies
            const configuration = fieldConfiguration.find(function(configuration) {
                return configuration.key == ev.memo.key;
            });

            updateDependency({ }, configuration);

            // And now remove the configuration
            fieldConfiguration = fieldConfiguration.filter(function(configuration) {
                return configuration.key != ev.memo.key;
            });

            render();
        });

        $area.on('field:update', function (ev) {
            const $element = $area.down('[data-key="' + ev.memo.key + '"]');
            const oldData = JSON.parse($element.readAttribute('data-property-configuration'))
            const position = $element.readAttribute('data-position').split(',');
            var [type, popup, relation, multivalue] = ev.memo.fieldType.split(',');
            const multiselection = (type === 'f_popup' && popup === 'checkboxes' && relation === '1')
                || (type === 'f_popup' && popup === 'dialog_plus' && relation === '1')
                || (type === 'f_popup' && popup === 'browser_object' && multivalue === '1');
            var extra = '';

            if (type === 'f_popup' && popup === 'date-datetime') {
                extra = 'date-datetime';

                // Fix calendar type
                popup = 'calendar';
            } else if (type === 'f_dialog' && popup === 'yes-no') {
                extra = 'yes-no'

                // Fix calendar type
                popup = '';
            }

            const newData = {
                key: ev.memo.key,
                newKey: ev.memo.newKey,
                title: ev.memo.fieldTitle,
                type: type,
                configValue: ev.memo.fieldType,
                popup: popup || '',
                identifier: ev.memo.fieldIdentifier,
                show_in_list: !!ev.memo.fieldShowInList,
                disable: !!oldData.disable,
                multiselection: multiselection,
                default: ev.memo.fieldDialogDefault,
                visibility: ev.memo.fieldVisibility,
                show_inline: !!oldData.show_inline,
                extra: extra
            };

            if (ev.memo.fieldDependency != -1) {
                newData.dialogDependency = ev.memo.fieldDependency;
                newData.dialogLinkedTo = ev.memo.fieldLinkedTo;
            }

            // In case the dependency has changed, we might also need to change the linked field.
            if (newData.dialogDependency != oldData.dialogDependency || newData.dialogLinkedTo != oldData.dialogLinkedTo) {
                updateDependency(newData, oldData);
            }

            if (onelineFields.includes(newData.configValue)) {
                newData.show_inline = false;
            }

            fieldConfiguration = fieldConfiguration.map(function(configuration) {
                if (configuration.key == ev.memo.key) {
                    return newData;
                }

                return configuration;
            });

            render();
        });

        function updateDependency(newData, oldData) {
            const oldLink = fieldConfiguration.find(function(configuration) { return configuration.key == oldData.dialogLinkedTo; });
            const newLink = fieldConfiguration.find(function(configuration) { return configuration.key == newData.dialogLinkedTo; });

            // There is no old link, simply connect the new one.
            if (!oldLink) {
                // Go sure to handle possible previous links.
                if (newLink) {
                    if (newLink.dialogDependency !== undefined && newLink.dialogLinkedTo !== undefined) {
                        idoit.Notify.info('[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__DEPENDENCY_NOTICE"}]'.replace('%s', newLink.title.escapeHTML()), { life: 10 });
                        updateDependency({ }, newLink);
                    }

                    newLink.dialogDependency = newData.dialogDependency === 'primary' ? 'secondary' : 'primary';
                    newLink.dialogLinkedTo = newData.key;
                }

                return;
            }

            // There is no new link, simply disconnect the old one.
            if (!newLink) {
                delete oldLink.dialogDependency;
                delete oldLink.dialogLinkedTo;
                return;
            }

            // The dependency type has changed, simply update it accordingly.
            if (newData.dialogLinkedTo == oldData.dialogLinkedTo) {
                newLink.dialogDependency = newData.dialogDependency === 'primary' ? 'secondary' : 'primary';
                return;
            }

            /*
             * The dependency link (and probably it's type) has changed - this case is a bit more complex,
             * because the new link might already have a connection that has to be removed now!
             */

            // First we disconnect the old link.
            delete oldLink.dialogDependency;
            delete oldLink.dialogLinkedTo;

            // Go sure to handle possible previous links.
            idoit.Notify.info('[{isys type="lang" ident="LC__SYSTEM__CUSTOM_CATEGORIES__DEPENDENCY_NOTICE"}]'.replace('%s', oldLink.title.escapeHTML()), { life: 10 });
            updateDependency({ }, newLink);

            // And finally we connect them.
            newLink.dialogDependency = newData.dialogDependency === 'primary' ? 'secondary' : 'primary';
            newLink.dialogLinkedTo = newData.key;
            return;
        }

        $('add_custom_multiple_fields_button').on('click', function () {
            const countOfFields = $F('count_of_custom_fields');

            for (var i = 0; i < countOfFields; i++) {
                // @see ID-9588 We save the number values as string, so that they get appended instead of added.
                const currentTimestamp = '' + (new Date()).getTime();
                const randomNumber = '' + Math.floor(999 * Math.random());

                fieldConfiguration.push({
                    key: "c_" + (currentTimestamp + randomNumber + i),
                    title: idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__NEW_FIELD') + ' #' + (fieldConfiguration.length + 1),
                    type: 'f_text',
                    configValue: 'f_text',
                    popup: '',
                    identifier: '',
                    show_in_list: true,
                    disable: false,
                    multiselection: false,
                    default: '',
                    visibility: 'visible',
                    show_inline: false,
                    extra: null
                });
            }

            render();
        })

        /*
         * This function will clean the provided data, like:
         * - put "single line" elements in their single line.
         * - take care of proper dependency handling
         */
        function cleanupData(data) {
            const preparedData = [];
            var row = [];
            var moveToNextRow = false;
            var index;

            for (index in fieldConfiguration) {
                if (!fieldConfiguration.hasOwnProperty(index)) {
                    continue;
                }

                if (moveToNextRow) {
                    // Move the field to the next line, when the previous one was a "one line field".
                    fieldConfiguration[index].show_inline = false;
                }

                moveToNextRow = onelineFields.includes(fieldConfiguration[index].configValue);

                if (fieldConfiguration[index].hasOwnProperty('dialogDependency') && fieldConfiguration[index].hasOwnProperty('dialogLinkedTo')) {
                    // @todo  We found a dependency field! We might want to validate it...
                } else {
                    delete fieldConfiguration[index].dialogDependency;
                    delete fieldConfiguration[index].dialogLinkedTo;
                }
            }

            // After the cleanup we'll bring the data in the expected structure.
            for (index in fieldConfiguration) {
                if (!fieldConfiguration.hasOwnProperty(index)) {
                    continue;
                }

                if (index == 0) {
                    row.push(fieldConfiguration[index]);
                    continue;
                }

                if (fieldConfiguration[index].show_inline && row.length < maxElementsInColl && !onelineFields.includes(fieldConfiguration[index].configValue)) {
                    row.push(fieldConfiguration[index]);
                    continue;
                }

                if (row.length > maxElementsInColl) {
                    idoit.Notify.error(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__TO_MUCH_ELEMENTS'), { sticky:true });
                }

                preparedData.push(row);
                row = [];

                fieldConfiguration[index].show_inline = false;
                row.push(fieldConfiguration[index]);
            }

            preparedData.push(row);

            return preparedData;
        }

        $customFieldCounter.on('change', function () {
            const currentCount = parseInt($customFieldCounter.getValue());

            if (currentCount > 100) {
                $customFieldCounter.setValue(100);
            }
        });

        function getType(prop) {
            var relation = '';

            if (prop.type === 'f_popup' && prop.popup === 'browser_object') {
                relation = (prop.identifier > 0) ? '1' : '0'
            }

            const addition = [prop.type, prop.value, prop.extra, prop.popup, relation, +prop.multiselection]
                .filter(function(value) {return !!value;})
                .join(',');

            const value = field_options.find(function(field) {
                return field && (addition === field.configValue || prop.type === field.configValue);
            });

            if (value) {
                return value;
            }

            return null;
        }

        $saveButton
            .writeAttribute('onclick', null)
            .on('click', function () {
                // Check if there are any fields with validation issues.
                if ($area.down('.box-red')) {
                    idoit.Notify.error(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__EMPTY_TITLE_MESSAGE'), {sticky:true});
                } else {
                    new Ajax.Request(window.www_dir + 'custom_fields/ajax/save', {
                        parameters: {
                            id: '[{$id}]',
                            properties: JSON.stringify(fieldConfiguration),
                            categoryTitle: $F('category_title'),
                            multivalued: $F('multivalued'),
                            categoryConstant: $F('category_constant'),
                            labelPosition: $F('label_position'),
                            assignedObjectTypes: $F('object_types__selected_values'),
                        },
                        onComplete: function (xhr) {
                            if (!is_json_response(xhr, true)) {
                                return;
                            }

                            var json = xhr.responseJSON;

                            if (!json.success) {
                                idoit.Notify.error(json.message, { sticky: true });
                                return;
                            }

                            // Reload the page for everything to "refresh".
                            if (json.data && json.data.hasOwnProperty('redirectUrl')) {
                                location.href = json.data.redirectUrl;
                            }
                        }
                    });
                }
            });

        // Load the properties for this configuration.
        new Ajax.Request(window.www_dir + 'custom_fields/ajax/load', {
            parameters: {
                id: '[{$id}]'
            },
            onComplete: function (xhr) {
                if (!is_json_response(xhr, true)) {
                    return;
                }

                var json = xhr.responseJSON;

                fieldConfiguration = json.data;
                render();
            }
        });


    })();
</script>

<style type="text/css">
    [data-role="row"] {
        width: 100%;
        height: 60px;
        padding: 3px;
        position: relative;
    }

    [data-role="field"] {
        border: 1px solid #aaa;
        min-width: 250px;
        height: 50px;
        float: left;
        background: #fff;
        margin-right: 8px;
        border: 1px solid #aaa;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }

    [data-role="field"] .popup_options_caller {
        margin-right: 4px;
    }

    .handle {
        background: url("[{$dir_images}]/icons/hatch.gif");
        width: 10px;
        height: calc(100% - 4px);
        margin: 2px;
        cursor: move;
        z-index: 50;
    }

    .type-and-title {
        flex-grow: 1;
    }

    .type-and-title p {
        padding: 5px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 190px;
    }

    .droppable-row,
    .droppable-col {
        background: transparent;
        border-radius: 2px;
        opacity: 0.5;
        z-index: 100;
    }

    .droppable-col {
        position: absolute;
        width: 30px;
        height: 50px;
    }

    .droppable-row {
        position: relative;
        width: 100%;
        height: 10px;
        margin: -5px 0;
        padding: 0;
        top: -2px;
    }

    .droppable-row.hover,
    .droppable-col.hover,
    .droppable-row.hide2,
    .droppable-col.hide2 {
        background: #aaa;
        box-shadow: 0 0 8px #aaa;
    }

    #custom_fields_configuration pre {
        font-size: 13px;
        line-height: 16px;
    }

    #api-info .display-flex > div {
        min-width: 25%;
        max-width: 50%;
        overflow: hidden;
    }

    #api-info .display-flex > div > pre {
        width: 100%;
        overflow: auto;
        padding: 10px;
        margin-top: 10px;
    }
</style>
[{/if}]
