<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}]icons/silk/information.png">
                </td>
                <td class="value">
                    <div class="input-group input-size-small 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">
                    [{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}]icons/silk/information.png" 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}]icons/silk/information.png" 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 class="mr5" src="[{$dir_images}]icons/silk/brick.png" />
                        <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}]icons/silk/information.png" 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 class="mr5" src="[{$dir_images}]icons/plus-green.gif" />
            <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">

    </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}]icons/silk/error.png" class="vam mr5" />[{isys type="lang" ident="LC__CMDB__CUSTOM_CATEGORIES__CHANGE_NOTE"}]
        </p>
        [{/if}]

        [{if $entryCount}]
        <div class="box-blue p10 mt10 mb10">
            <h3 class="mb10"><img src="[{$dir_images}]icons/silk/information.png" class="vam mr5" />[{isys type="lang" ident="LC__LICENCE_OVERVIEW__STATISTIC"}]</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>
                <div class="fl">
                    <h3 class="mt10">Configuration:</h3>
                    <pre class="box-lightgrey mt10 p10">[{json_encode($apiExampleConfig, JSON_PRETTY_PRINT)}]</pre>
                </div>

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

            <br class="cb"/>

            <h3 class="mt10">API-Examples:</h3>
            <pre class="box-lightgrey mt10 p10">[{json_encode($apiExample.read, JSON_PRETTY_PRINT)}]</pre>
            <pre class="box-lightgrey mt10 p10">[{json_encode($apiExample.create, JSON_PRETTY_PRINT)}]</pre>
        </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 field_options         = JSON.parse('[{$propertyTypes|json_encode|escape:"javascript"}]'),
            relationTypes         = JSON.parse('[{$relation_types|json_encode|escape:"javascript"}]'),
            unhandledData         = [],
            onelineFields         = field_options
                .filter(function (prop) { return !prop.allowInline; })
                .map(function (prop) { return getType(prop).configValue; })
                .uniq();

        const maxElementsInColl = 4;
        const $area = $('area');
        const $scroller = $('scroller');
        const $saveButton = $('navbar_item_C__NAVMODE__SAVE');
        const $customFieldCounter = $('count_of_custom_fields');
        const $relationTypeTemplate = new Element('select', {className: 'ml15 input hide'});

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

        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, ''));
            });
        }

        for (var relationTypeId in relationTypes) {
            if (!relationTypes.hasOwnProperty(relationTypeId)) {
                continue;
            }

            $relationTypeTemplate
                .insert(new Element('option', {value: relationTypes[relationTypeId].id})
                    .update(relationTypes[relationTypeId].title));
        }

        var propertyTypes = field_options.clone();

        propertyTypes.sort(function(a, b) {
            return a.title.localeCompare(b.title);
        });

        [{foreach $category_config as $key => $config}]
        unhandledData.push(prepareElement(
            '[{$key}]',
            '[{$config.title|escape:"javascript"}]',
            '[{$config.type|default:'f_text'}]',
            '[{$config.popup|default:''}]',
            '[{$config.identifier|default:''}]',
            '[{$config.show_in_list|default:1}]',
            true,
            '[{$config.multiselection}]',
            '[{$config.default|default:-1}]',
            '[{$config.visibility|default:'visible'}]',
            '[{$config.show_inline|default:0}]',
            '[{$config.extra}]'
        ));
        [{/foreach}]

        var data = prepareData(unhandledData)

        if (!Array.isArray(data) || !data.length) {
            data = [];
        }

        function render() {
            var i, j;

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

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

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

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

                for (j in data[i]) {
                    if (!data[i].hasOwnProperty(j)) {
                        continue;
                    }

                    const cleanTitle = data[i][j].title.replace(/\r?\n|\r/g, '');
                    const unvalidated = data[i][j].title.blank() ? 'unvalidated' : '';
                    const type = getType(data[i][j]);

                    $row
                        .insert(new Element('div', {'data-role': 'field', 'data-elem': JSON.stringify(data[i][j]), 'data-position': i + ',' + j, className: unvalidated})
                            .update(new Element('img', {src: window.dir_images + 'icons/silk/pencil.png', className:'mouse-pointer popup_options_caller'}))
                            .insert(new Element('div', {className:'handle'}))
                            .insert(new Element('div', {className:'type text-grey'}).update(type ? type.title : '-'))
                            .insert(new Element('div', {className:'title'}).update('title'))
                            .insert(new Element('div', {className:'popup custom-fields-popup hide'})
                                .insert(new Element('div',{class: 'popup-dialog-plus'})
                                    .insert(new Element('h3',{className: 'popup-header'})
                                        .insert(new Element('img', {src: window.dir_images + 'icons/close-circle.png', className: 'fr mouse-pointer popup-closer', alt: 'x'}))
                                        .insert(new Element('span').update('title field parameters')))
                                    .insert(new Element('div', {className: 'popup-content'})
                                        .insert(new Element('table', {className: 'w100'})
                                            .insert(new Element('tr')
                                                .insert(new Element('td',{className: 'label-key'})
                                                    .update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE'))
                                                )
                                                .insert(new Element('td')
                                                    .insert(getPropertyTypesSelector(data[i][j]))
                                                )
                                            )
                                            .insert(new Element('tr')
                                                .insert(new Element('td',{className: 'label-key'})
                                                    .update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TITLE'))
                                                )
                                                .insert(new Element('td')
                                                    .insert(new Element('input', {type: 'text',id:'field_title['+data[i][j].key+']', name: 'field_title['+data[i][j].key+']', value: data[i][j].title, className: 'input'}))
                                                )
                                            )
                                            .insert(new Element('tr')
                                                .insert(new Element('td',{className: 'label-key'})
                                                    .update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_ADDITIONAL'))
                                                )
                                                .insert(new Element('td')
                                                    .insert(new Element('input', {id:'field_dialog_identifier['+data[i][j].key+']', type: 'text', name: 'field_dialog_identifier['+data[i][j].key+']', value: data[i][j].identifier, className: 'input', diasbled: data[i][j].disable}))
                                                    .insert(generateExtraField(data[i][j]))
                                                    .insert(generateRelationElement(data[i][j]))
                                                )
                                            )
                                            .insert(new Element('tr')
                                                .insert(new Element('td',{className: 'label-key'})
                                                    .update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING'))
                                                )
                                                .insert(new Element('td')
                                                    .insert(generateVisibilitySelector(data[i][j]))
                                                )
                                            )
                                            .insert(new Element('tr', {className: 'show-in-list hide'})
                                                .insert(new Element('td',{className: 'label-key'})
                                                    .update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__SHOW_IN_LIST')))
                                                .insert(new Element('td')
                                                    .insert(new Element('input', {type: 'checkbox', name: 'field_show_in_list['+data[i][j].key+']', value: 1, checked: data[i][j].show_in_list}))
                                                )
                                            )
                                            .insert(new Element('tr', {className: 'hide'})
                                                .insert(new Element('td',{className: 'label-key'}))
                                                .insert(new Element('td')
                                                    .insert(new Element('input', {type: 'checkbox', name: 'field_show_inline['+data[i][j].key+']', value: 1, checked: data[i][j].displayInline}))
                                                )
                                            )
                                        )
                                    )
                                    .insert(new Element('div', {className: 'popup-footer'})
                                        .insert(new Element('button',{type:'button', className: 'btn mr5 custom_field_options_save'})
                                            .insert(new Element('img',{src: window.dir_images + 'icons/silk/tick.png', className:'mr5'}))
                                            .insert(new Element('span').update(idoit.Translate.get('LC_UNIVERSAL__ACCEPT')))
                                        )
                                        .insert(new Element('button',{type:'button', className: 'btn popup-closer'})
                                            .insert(new Element('img',{src: window.dir_images + 'icons/silk/cross.png', className:'mr5'}))
                                            .insert(new Element('span').update(idoit.Translate.get('LC__UNIVERSAL__BUTTON_CANCEL')))
                                        )
                                        .insert(new Element('button',{type:'button', className: 'btn fr custom_field_options_remover'})
                                            .insert(new Element('img',{src: window.dir_images + 'icons/silk/bin_empty.png', className:'mr5'}))
                                            .insert(new Element('span').update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_REMOVE')))
                                        )
                                    )
                                )
                            ))
                        .insert(new Element('div', {className:'droppable-col hide', 'data-pos': i + ',' + (1+parseInt(j)), style:'top:4px; left:' + (((1+parseInt(j))*255) - 15) + 'px; position:absolute;'}));

                    $row.down('.title').textContent = cleanTitle;
                    $row.down('.popup-header span').textContent = cleanTitle;
                }

                $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) {
                        var newData = [];
                        var tempData;
                        $droppable.insert($drag);
                        $$('[data-role="row"]').each(function ($row) {
                            var cols = [];

                            $row.select('[data-role="field"]').each(function ($col, index) {
                                const temp = JSON.parse($col.dataset.elem);

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

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

                                    temp.displayInline = false;
                                }

                                newData.push(temp);
                            });
                        });

                        data = prepareData(newData);

                        render();
                    }
                });
            });

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

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

        $area.on('click', '.popup_options_caller', function (ev) {
            const $popup = ev.findElement().next('.custom-fields-popup');

            show_overlay();

            if ($categoryMultivalued.getValue() === '1') {
                $popup.down('.show-in-list').removeClassName('hide');
            } else {
                $popup.down('.show-in-list').addClassName('hide');
            }

            $popup.down('.fieldType').simulate('change');

            $popup.removeClassName('hide');
        });

        $area.on('click', '.custom_field_options_remover', function (ev) {
            hide_overlay();

            var position = ev.findElement().up('[data-role="field"]').readAttribute('data-position').split(',');

            data[position[0]].splice(position[1], 1);
            render();
        });

        $area.on('click', '.popup-closer', function (ev) {
            hide_overlay();

            ev.findElement().up('.custom-fields-popup').addClassName('hide');
        });

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

            const oldData = JSON.parse($row_element.readAttribute('data-elem'))
            const position = $row_element.readAttribute('data-position').split(',');

            const newData = prepareElement(
                oldData.key,
                $F('field_title[' + oldData.key + ']'),
                $F('field_type' + oldData.key),
                oldData.popup,
                $F('field_dialog_identifier[' + oldData.key + ']'),
                oldData.show_in_list,
                oldData.disable,
                oldData.multiselection,
                $F('default_' + oldData.key),
                $F('field_visibility_id_' + oldData.key),
                oldData.displayInline,
                oldData.extra
            );

            hide_overlay();

            if (onelineFields.includes(newData.type) && position[1] != 0) {
                newData.displayInline = false;
                idoit.Notify.error(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__TO_MUCH_ELEMENTS'), {sticky:true});
                data[position[0]].splice(position[1], 1);
            } else {
                data[position[0]][position[1]] = newData;
            }

            render();
        });

        $area.on('change', '.fieldType', function(ev){
            const $fieldType = ev.findElement();
            const $fieldTitle = $fieldType.up('table').down('[name^="field_title"]');
            const fieldTypeName = $fieldType.down(':selected').textContent;
            const notice = idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__ONE_ELEMENT_PER_ROW').replace('%s', fieldTypeName);
            const $notice = $('notice');
            var textarea = false;

            if (onelineFields.include($fieldType.getValue())) {
                idoit.Notify.info(notice);

                if (!$notice) {
                    $fieldType.insert({
                        after: new Element('div', {id: 'notice', className:'box-blue p5 mt5'})
                            .insert(new Element('img', {src: window.dir_images + 'icons/silk/information.png', className: 'vam mr5'}))
                            .insert(new Element('span',{className: 'van'}).update(notice))
                    });
                }
            } else if ($notice) {
                $notice.remove();
            }

            change_fields_by_type($fieldType);

            // Switching textareas and input fields for HTML and SCRIPT elements.
            if (['html', 'script'].include($fieldType.getValue())) {
                $fieldTitle.insert({
                    after: new Element('textarea', {
                        rows:        10,
                        name:        $fieldTitle.readAttribute('name'),
                        id:          $fieldTitle.readAttribute('id'),
                        className:   'input input-small ml15 mr15',
                        placeholder: fieldTypeName + '..'
                    }).update($fieldTitle.getValue())
                }).remove();
            } else {
                $fieldTitle.insert({
                    after: new Element('input', {
                        type:      'text',
                        name:      $fieldTitle.readAttribute('name'),
                        id:        $fieldTitle.readAttribute('id'),
                        className: 'input input-small ml15 mr15'
                    }).setValue($fieldTitle.getValue())
                }).remove();
            }
        });

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

            // Find out how many fields already exist:
            const fieldCount = data
                .flatten()
                .filter(function(config) { return typeof config === 'object'; })
                .length;

            for (var i = 0; i < countOfFields; i++) {
                const code = (new Date()).getTime() + Math.floor((10 - 3) * Math.random()) + 5 + i * 5;
                const fieldName = idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__NEW_FIELD') + ' #' + (fieldCount + 1);

                data.push([prepareElement(code, fieldName, 'f_text', '', '', 1, false, 0, -1, 'visible', 0, null)]);
            }

            render();
        })

        render();

        function prepareData(unhandledData) {
            var preparedData = [],
                temp = [],
                i;

            for (i = 0; i < unhandledData.length; i++) {
                if (i == 0) {
                    temp.push(unhandledData[i]);
                    continue;
                }
                if (unhandledData[i].displayInline && temp.length < maxElementsInColl && !onelineFields.includes(unhandledData[i].type)) {
                    temp.push(unhandledData[i]);
                } else {
                    if (temp.length > maxElementsInColl) {
                        idoit.Notify.error(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__TO_MUCH_ELEMENTS'), {sticky:true});
                    }
                    preparedData.push(temp);
                    temp = [];
                    unhandledData[i].displayInline = false;
                    temp.push(unhandledData[i]);
                }
            }
            preparedData.push(temp);
            return preparedData
        }

        function prepareElement(key, title, type, popup, identifier, show_in_list, disable, multiselection, defaultValue, visibility, displayInline, extra) {
            if (type === 'f_popup' && popup === 'browser_object') {
                multiselection = multiselection ? '1' : '';
            }

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

            return {
                key: key,
                title: title,
                type: type,
                popup: popup,
                identifier: identifier,
                show_in_list: show_in_list,
                disable: disable,
                multiselection: multiselection,
                defaultValue: defaultValue,
                visibility: visibility,
                displayInline: displayInline == '1',
                extra: extra
            }
        }

        function getPropertyTypesSelector(data) {
            const disabled = data.disable ? 'disabled' : '';
            const selectedType = getType(data);
            const element = new Element('select', {id:'field_type' + data.key, name: 'field_type['+data.key+']', className: 'input fieldType ' + (data.disable ? 'disabled' : '')});
            var option;
            var i;

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

                option = new Element('option', {value: propertyTypes[i].configValue}).update(propertyTypes[i].title);

                if (data.disable) {
                    option.writeAttribute('disabled', 'disabled');
                }

                element.insert(option);
            }

            if (selectedType) {
                element.setValue(selectedType.configValue)
            }

            return element;
        }

        function generateRelationElement(data) {
            var i;

            const custom_optional_relation_ele = $relationTypeTemplate.clone(true)
                .writeAttribute('name', 'field_relation[' + data.key + ']')
                .writeAttribute('id', 'field_relation_id_' + data.key);

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

                if (data.popup === 'browser_object'
                    && data.identifier != ''
                    && propertyTypes[i].relation == 1
                    && data.type === propertyTypes[i].value
                    && (propertyTypes[i].popup == undefined || propertyTypes[i].popup == data.popup)) {

                    custom_optional_relation_ele.setValue(data.identifier);
                }
            }

            return custom_optional_relation_ele;
        }

        function generateExtraField(data) {
            var $extraField = new Element('select', {
                id: 'default_' + data.key,
                name: 'field_dialog_default[' + data.key + ']',
                class: 'input ml15 hide',
                readonly: 'readonly'
            })

            buildPropertyTypeExtra($extraField, data.popup);

            $extraField.setValue(data.defaultValue);

            return $extraField;
        }

        function generateVisibilitySelector(data) {
            const $select = new Element('select', {className:'ml15 input', id:'field_visibility_id_' + data.key, name:'field_visibility[' + data.key + ']'})
                .insert(new Element('option', {value: 'visible'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__STANDARD')))
                .insert(new Element('option', {value: 'readonly'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__API_ONLY')))
                .insert(new Element('option', {value: 'hidden'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_HANDLING__HIDDEN')))

            $select.setValue(data.visibility ? data.visibility : 'visible');

            return $select;
        }

        function buildPropertyTypeExtra($select, type) {
            if (type === 'calendar') {
                $select
                    .update(new Element('option', {value:  '1'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__CALENDAR_WITH_TIME')))
                    .insert(new Element('option', {value: '-1'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__CALENDAR_WITHOUT_TIME')));
            } else {
                $select
                    .update(new Element('option', {value: '-1'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_NONE')))
                    .insert(new Element('option', {value: '1'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_YES')))
                    .insert(new Element('option', {value: '0'}).update(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__DEFAULT_NO')));
            }
        }

        function change_fields_by_type($typeSelect) {
            var $identifierField = $typeSelect.up('table').down('[name^="field_dialog_identifier"]').removeClassName('hide').enable(),
                $defaultField    = $typeSelect.up('table').down('[name^="field_dialog_default"]').removeClassName('hide').enable(),
                $relationField   = $typeSelect.up('table').down('[name^="field_relation"]').removeClassName('hide').enable(),
                $visibilityField = $typeSelect.up('table').down('[name^="field_visibility"]'),
                typeValue        = $typeSelect.getValue().split(',');

            if (!['f_text', 'f_popup', 'f_password', 'f_link', 'f_time', 'f_textarea'].include(typeValue[0])) {
                $visibilityField
                    .setValue('visible')
                    .writeAttribute('readonly', 'readonly')
                    .writeAttribute('disabled', 'disabled');
            } else {
                $visibilityField
                    .writeAttribute('readonly', null)
                    .writeAttribute('disabled', null);
            }

            if (typeValue[0] === 'f_popup') {
                if (typeValue[1] === 'dialog_plus' || typeValue[1] === 'checkboxes') {
                    $identifierField
                        .writeAttribute('readonly', null)
                        .writeAttribute('placeholder', idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_IDENTIFIER'));
                    $defaultField
                        .disable()
                        .addClassName('hide');
                    $relationField
                        .disable()
                        .addClassName('hide');
                    return;
                } else if (typeValue[1] === 'browser_object') {
                    if ((typeValue.length === 3 || typeValue.length === 4) && typeValue[2] == 1) {
                        $identifierField
                            .addClassName('hide')
                            .writeAttribute('readonly', 'readonly')
                            .writeAttribute('placeholder', null);
                        $defaultField
                            .disable()
                            .addClassName('hide');
                        return;
                    }
                } else if (typeValue[1] === 'report_browser') {
                    $identifierField
                        .writeAttribute('readonly', null)
                        .writeAttribute('placeholder', idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_IDENTIFIER'));
                    $defaultField
                        .disable()
                        .addClassName('hide');
                    $relationField
                        .disable()
                        .addClassName('hide');
                    return;
                }

                var tempValue = $defaultField.getValue();

                if (typeValue[1] === 'date-datetime') {
                    buildPropertyTypeExtra($defaultField, 'calendar');
                    $defaultField.setValue(tempValue);

                    $identifierField
                        .disable()
                        .addClassName('hide');
                    $defaultField
                        .writeAttribute('readonly', null);
                    $relationField
                        .disable()
                        .addClassName('hide');

                    return;
                } else {
                    buildPropertyTypeExtra($defaultField, '');
                    $defaultField.setValue(tempValue);
                }
            } else if (typeValue[0] === 'f_dialog' && typeValue[1] === 'yes-no') {
                $identifierField
                    .disable()
                    .addClassName('hide');
                $defaultField
                    .writeAttribute('readonly', null);
                $relationField
                    .disable()
                    .addClassName('hide');
                return;
            }

            $identifierField
                .disable()
                .writeAttribute('readonly', 'readonly')
                .writeAttribute('placeholder', null);

            $defaultField
                .disable()
                .addClassName('hide');

            $relationField
                .disable()
                .addClassName('hide');
        };

        $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 unvalidated fields.
                if ($$('.unvalidated').length) {
                    idoit.Notify.error(idoit.Translate.get('LC__SYSTEM__CUSTOM_CATEGORIES__EMPTY_TITLE_MESSAGE'), {sticky:true});
                } else {
                    $('navMode').setValue('[{$smarty.const.C__NAVMODE__SAVE}]');
                    form_submit();
                }
            });
    })();
</script>

<style type="text/css">
    .popup * {
        box-sizing: border-box;
    }

    .popup-dialog-plus {
        height: 100%;
    }

    #notice {
        width: 350px;
    }

    .unvalidated {
        border-color: #ff4343 !important;
    }

    .custom-fields-popup {
        z-index: 1100;
        position: fixed;
        width: 550px;
        height: 350px;
        top: 15%;
        left: 50%;
        margin-left: -240px;
    }

    .custom-fields-popup textarea {
        resize: vertical;
    }

    [data-role="row"] {
        width: 100%;
        height: 40px;
        padding: 3px;
        position: relative;
    }

    [data-role="field"] {
        border: 1px solid #aaa;
        min-width: 250px;
        height: 40px;
        float: left;
        background: #fff;
        margin-right: 4px;
        border: 1px solid #aaa;
        position: relative;
    }

    [data-role="field"] img.popup_options_caller {
        position: absolute;
        top: 12px;
        right: 7px;
        opacity: 0;
        transition: opacity 150ms;
    }

    [data-role="field"]:hover img.popup_options_caller {
        opacity: 1;
    }

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

    .type,
    .title {
        position: absolute;
        top: 5px;
        left: 20px;
        width: 200px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .title {
        top: 22px;
    }

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

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

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

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

    .popup-header span {
        width: 440px;
        overflow: hidden;
        text-overflow: ellipsis;
        display: block;
        white-space: nowrap;
    }

    .popup-content table tr {
        height: 30px;
    }

    .popup-content table td:first-child {
        width: 120px;
        text-align: right;
        padding: 8px;
        vertical-align: top;
    }

    .popup-content table td:last-child {
        padding: 3px 8px;
        vertical-align: top;
    }

    .popup-content input,
    .popup-content .input {
        width: 100%;
        margin-left: 0 !important;
    }

    .popup-content input[type="checkbox"] {
        width: auto;
        margin-top: 6px;
    }

    #custom_fields_configuration pre {
        font-size: 13px;
        line-height: 16px;
    }
</style>
[{/if}]
