{include file="./index_top.tpl"}

<script type="text/javascript">
    // значения для системной подсказки
    var help_section = 'Settings';
    var help_sub_section = 'Informers';

    const isShowAdditionalButton = !!({$additional|default:'false'});
    const additionalButtons = Object.values({$all_buttons});
    const selectedAdditionalButton = {$additional_id|default:0};

    cpkNewCol = "{$lang.cp_new_color}";
    cpkCurCol = "{$lang.cp_cur_color}";
</script>

<script language="JavaScript" type="text/javascript">
  {literal}
    /**
     Состояние, аналогичное React, для отслеживания и обновления значения.
      * 
      * @param any initialValue - Начальное значение состояния.
    * @returns Array Массив, содержащий:
    *  - Функция для получения текущего значения состояния.
    *  - Функция для обновления состояния.
    *  - Функция для подписки на изменение состояния.
    */
    const useState = (initialValue) => {
      let value = initialValue; // Храним текущее состояние
      const listeners = new Set(); // Множество слушателей изменений состояния

      // Функция для обновления состояния
      const setState = (newValue) => {
        // Если передано как функция, вызываем её с текущим значением
        if (typeof newValue === 'function') {
          value = newValue(value);
        } 
        // Если передан объект, создаем новый объект для предотвращения мутации
        else if (typeof newValue === 'object' && newValue !== null) {
          value = JSON.parse(JSON.stringify(newValue)); // Создаем новый объект (глубокое копирование)
        } else {
          // Для примитивных значений просто присваиваем
          value = newValue;
        }
        
        // Уведомляем всех подписчиков о новом значении
        listeners.forEach((listener) => listener(value));
      };

      // Функция для подписки на изменения состояния
      const onStateChange = (listener) => {
        listeners.add(listener);
        return () => listeners.delete(listener); // Возвращаем функцию для отмены подписки
      };
      // Возвращаем массив с функцией для получения значения, функцией для его обновления и функцией подписки
      return [() => value, setState, onStateChange]; 
    };
    /**
     * Динамический рендер элементов настройки ДД в информере
     * @todo Добавить комментарии к компонентам
    */
    $(document).ready(() => {
      const Additonal = ({
        childrens
      }) => {
        const wrapper = document.getElementById('additional');
        $(wrapper).append(childrens);
        return $(wrapper);
      }
      const AdditonalCheckBox = ({
        isChecked,
        setIsChecked,
        onIsCheckedChange,
        onChange
      }) => {
        const render = () => {
          const $label = $('<td>', {
            'align': 'right',
          });
          $label
            .append(
              $('<span>', { text: "Выводить ДД" })
              .append(
                $('<span>', { class: "help_bt", h_id: 'Informer_additional_show' })
              )
            )
            .append(
              $('<span>', { text: ":" })
            );
          const $checkbox = $('<td>');
          const $checkboxInput = $('<input>', { 
              'type': "checkbox",
              'name': "additional",
              'checked': isChecked,
            });

          const handlerChange = (e) => {
            const newIsChecked = e.target.checked
            setIsChecked(newIsChecked);
            if(onChange) onChange(newIsChecked)
          }

          const renderIsCheckedChange = (newIsChecked) => {
            $checkboxInput.prop('checked', newIsChecked)
          }
          onIsCheckedChange(renderIsCheckedChange)
          $checkboxInput.change(handlerChange);
          $checkbox.append($checkboxInput);

          const $row = $('<tr>');
          $row
            .append($label)
            .append($checkbox)

          return $row;
        }
        
        return render();
      }
      const AdditonalSelect = ({
        isShow,
        onIsShowChange,
        options,
        setOptions,
        onOptionChange,
        selected,
        setSelected,
        onSelectedChange,
      }) => {
        const render = () => {
          const $label = $('<td>', {
            'align': 'right',
          });
          $label
            .append(
              $('<span>', { text: "Выберите ДД" })
              .append(
                $('<span>', { class: "help_bt", h_id: 'Informer_additional' })
              )
            )
            .append(
              $('<span>', { text: ":" })
            );
          const $selectTd = $('<td>');
          const $select = $('<select>', { 
            'id': "additional__select",
            'name': "additional_id",
            'className': "form-control form-control-160",
          });
          const $selectSettings = $('<a>', { 
            'href': `edit_button.php?table=${tableId}`,
            'title': "Настройка ДД",
            'target': "_blank",
            'class': "no_print",
          })
            .append($('<img>', { 
              'src': "images/settings_a.gif", 
              'class': "settings_t", 
              'style': "margin: 0px 0px 0px 6px; border: 0px;" 
            }));
          
          options.forEach(({id, name}) => {
            $('<option>', { value: id, text: name }).appendTo($select);
          });
          $select.val(selected);
          $selectTd.append($select);
          $selectTd.append($selectSettings);
          const $row = $('<tr>');
          $row
            .append($label)
            .append($selectTd)

          return { $row, $select };
        };
        
        const { $row, $select } = render();

        const handlerChange = () => setSelected($select.val() || null);
        const renderSelectedChange = (newSelected) => {
          $select.val(newSelected);
        }
        onSelectedChange(renderSelectedChange);
        $select.change(handlerChange);

        const toggleShow = (isShow) => {
          if(isShow)
            return $row.show();
          return $row.hide();
        }
        onIsShowChange(toggleShow);
        toggleShow(isShow);

        return $row;
      }

      const [
        getIsShowAdditional, 
        setIsShowAdditional, 
        onIsShowAdditionalChange
      ] = useState(isShowAdditionalButton || false);
      const [
        getAdditionalButtons, 
        setAdditionalButtons, 
        onAdditionalButtonsChange
      ] = useState([
        { id: 0, name: '--- Выберите ДД ---' },
        ...(Array.isArray(additionalButtons) 
          ? additionalButtons.map(({ id, name }) => ({ id, name })) 
          : []
        )
      ]);
      const [
        getSelectedAdditionalButton, 
        setSelectedAdditionalButton, 
        onSelectedAdditionalButtonChange
      ] = useState(selectedAdditionalButton || null);

      Additonal({
        childrens: [
          AdditonalCheckBox({
            isChecked: getIsShowAdditional(),
            setIsChecked: setIsShowAdditional,
            onIsCheckedChange: onIsShowAdditionalChange,
          }),
          AdditonalSelect({
            isShow: getIsShowAdditional(),
            onIsShowChange: onIsShowAdditionalChange,
            options: getAdditionalButtons(),
            setOptions: setAdditionalButtons,
            onOptionChange: onAdditionalButtonsChange,
            selected: getSelectedAdditionalButton(),
            setSelected: setSelectedAdditionalButton,
            onSelectedChange: onSelectedAdditionalButtonChange,
          })
        ]
      });
      // Активируем ссылки на help.clientbase...
      bind_help_bt(); 
    })
  {/literal}
    var under_mouse_object = 0;
    var last_focus = 0;

    function insert_field(area) {
        message = document.getElementById(area);
        ins_field = document.getElementById('ins_field_' + area);
        if (document.selection) {
            message.focus();
            document.selection.createRange().text = ins_field.value;
        }
        else {
            message.value = message.value.substr(0, message.selectionStart) + ins_field.value + message.value.substr(message.selectionEnd);
        }

        // При добавлении шаблона в текст информера необходимо предпрудить пользователя, что текст будет автоматчиески обрезаться до 120 символов
        $('.status-max-length__error').css('display', '');
    }

    {literal}
    function strtotime(str, now) {
        var i, l, match, s, parse = '';

        str = (str + '').replace(/\s{2,}|^\s|\s$/g, ' ').replace(/[\t\r\n]/g, ''); // unecessary spaces and chars

        if (str === 'now') {
            return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0;
        } else if (!isNaN(parse = Date.parse(str))) {
            return parse / 1000 | 0;
        } else if (now) {
            now = new Date(now * 1000); // Accept PHP-style seconds
        } else {
            now = new Date();
        }

        str = str.toLowerCase();

        var __is = {
            day: {
                'sun': 0,
                'mon': 1,
                'tue': 2,
                'wed': 3,
                'thu': 4,
                'fri': 5,
                'sat': 6
            },
            mon: [
                'jan',
                'feb',
                'mar',
                'apr',
                'may',
                'jun',
                'jul',
                'aug',
                'sep',
                'oct',
                'nov',
                'dec'
            ]
        };

        var process = function (m) {
            var ago = (m[2] && m[2] === 'ago');
            var num = (num = m[0] === 'last' ? -1 : 1) * (ago ? -1 : 1);

            switch (m[0]) {
                case 'last':
                case 'next':
                    switch (m[1].substring(0, 3)) {
                        case 'yea':
                            now.setFullYear(now.getFullYear() + num);
                            break;
                        case 'wee':
                            now.setDate(now.getDate() + (num * 7));
                            break;
                        case 'day':
                            now.setDate(now.getDate() + num);
                            break;
                        case 'hou':
                            now.setHours(now.getHours() + num);
                            break;
                        case 'min':
                            now.setMinutes(now.getMinutes() + num);
                            break;
                        case 'sec':
                            now.setSeconds(now.getSeconds() + num);
                            break;
                        case 'mon':
                            if (m[1] === "month") {
                                now.setMonth(now.getMonth() + num);
                                break;
                            }
                            // fall through
                        default:
                            var day = __is.day[m[1].substring(0, 3)];
                            if (typeof day !== 'undefined') {
                                var diff = day - now.getDay();
                                if (diff === 0) {
                                    diff = 7 * num;
                                } else if (diff > 0) {
                                    if (m[0] === 'last') {
                                        diff -= 7;
                                    }
                                } else {
                                    if (m[0] === 'next') {
                                        diff += 7;
                                    }
                                }
                                now.setDate(now.getDate() + diff);
                                now.setHours(0, 0, 0, 0); // when jumping to a specific last/previous day of week, PHP sets the time to 00:00:00
                            }
                    }
                    break;

                default:
                    if (/\d+/.test(m[0])) {
                        num *= parseInt(m[0], 10);

                        switch (m[1].substring(0, 3)) {
                            case 'yea':
                                now.setFullYear(now.getFullYear() + num);
                                break;
                            case 'mon':
                                now.setMonth(now.getMonth() + num);
                                break;
                            case 'wee':
                                now.setDate(now.getDate() + (num * 7));
                                break;
                            case 'day':
                                now.setDate(now.getDate() + num);
                                break;
                            case 'hou':
                                now.setHours(now.getHours() + num);
                                break;
                            case 'min':
                                now.setMinutes(now.getMinutes() + num);
                                break;
                            case 'sec':
                                now.setSeconds(now.getSeconds() + num);
                                break;
                        }
                    } else {
                        return false;
                    }
                    break;
            }
            return true;
        };

        match = str.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
        if (match !== null) {
            if (!match[2]) {
                match[2] = '00:00:00';
            } else if (!match[3]) {
                match[2] += ':00';
            }

            s = match[1].split(/-/g);

            s[1] = __is.mon[s[1] - 1] || s[1];
            s[0] = +s[0];

            s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
            return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
        }

        var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';

        match = str.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
        if (match === null) {
            return false;
        }

        for (i = 0, l = match.length; i < l; i++) {
            if (!process(match[i].split(' '))) {
                return false;
            }
        }

        return now.getTime() / 1000 | 0;
    }
    /**
     * Добавляет указанный интервал времени к дате.
     *
     * @param {Date} date - Исходная дата, к которой необходимо добавить интервал.
     * @param {number} value - Количество единиц времени, которые нужно добавить (может быть отрицательным для вычитания).
     * @param {string} unit - Тип интервала (например, 'year', 'month', 'day', 'hour', 'minute').
     *                        Поддерживаемые значения: 'year', 'month', 'day', 'hour', 'minute'.
     * @returns {Date} - Новый объект Date с добавленным интервалом.
     */
     const addIntervalToDate = (date, value, unit) => {
      const newDate = new Date(date)
      if(unit.includes('year')) 
        newDate.setFullYear(newDate.getFullYear() + value);
      if(unit.includes('month')) 
        newDate.setMonth(newDate.getMonth() + value);
      if(unit.includes('day')) 
        newDate.setDate(newDate.getDate() + value);
      if(unit.includes('hour')) 
        newDate.setHours(newDate.getHours() + value);
      if(unit.includes('minute')) 
        newDate.setMinutes(newDate.getMinutes() + value);
      return newDate;
    }

    /**
     * Форматирует дату в строку формата "YYYY-MM-DD HH:mm:ss".
     *
     * @param {Date} date - Дата, которую нужно отформатировать.
     * @returns {string} - Строка, представляющая дату в формате "YYYY-MM-DD HH:mm:ss".
     */
    const formatDate = (date) => {
      const pad = (num) => (num < 10 ? '0' : '') + num;
      return (
        date.getFullYear() +
        '-' +
        pad(date.getMonth() + 1) +
        '-' +
        pad(date.getDate()) +
        ' ' +
        pad(date.getHours()) +
        ':' +
        pad(date.getMinutes()) +
        ':' +
        pad(date.getSeconds())
      );
    }
    /**
     * Функция высшего порядка для получения диапазона дат на основе типа даты.
     *
     * @param {Object} dateObject - Объект, содержащий ключевые даты начала и конца для различных типов.
     * @param {number} dateObject.endWeek - Конец недели в виде UNIX-метки времени (в секундах).
     * @param {number} dateObject.beginHalfMonth - Начало половины месяца в виде UNIX-метки времени (в секундах).
     * @param {number} dateObject.endHalfMonth - Конец половины месяца в виде UNIX-метки времени (в секундах).
     * @param {number} dateObject.beginMonth - Начало месяца в виде UNIX-метки времени (в секундах).
     * @param {number} dateObject.endMonth - Конец месяца в виде UNIX-метки времени (в секундах).
     * @param {number} dateObject.beginYear - Начало года в виде UNIX-метки времени (в секундах).
     * @param {number} dateObject.endYear - Конец года в виде UNIX-метки времени (в секундах).
     * @returns {Function} - Функция, принимающая параметр `selector`, который определяет, какая дата будет выбрана,
     *                       и возвращает массив из двух объектов `Date` (начало и конец интервала).
     */
    const getDateFromDateObject = (dateObject) => (selector) => {
      const dateType = $('#cond_value_' + selector).val();
      const {
        beginWeek,
        endWeek,
        beginHalfMonth,
        endHalfMonth,
        beginMonth,
        endMonth,
        beginYear,
        endYear,
      } = dateObject
      
      if (dateType === 'week()') 
        return [
          new Date(beginWeek * 1000),
          new Date(endWeek * 1000),
        ]
      if (dateType === 'half_month()') 
        return [
          new Date(beginHalfMonth * 1000),
          new Date(endHalfMonth * 1000),
        ]
      if (dateType === 'month()') 
        return [
          new Date(beginMonth * 1000),
          new Date(endMonth * 1000),
        ]
      if (dateType === 'year()') 
        return [
          new Date(beginYear * 1000),
          new Date(endYear * 1000),
        ]
      if (dateType === 'fix_date') 
        return [
          new Date(strtotime($('#cond_date_' + selector).val()) * 1000),
          new Date(strtotime($('#cond_date_' + selector).val()) * 1000),
        ]

      return [
        new Date(),
        new Date(),
      ]
    }
    {/literal}
    {literal}
    /**
     * Создаёт функцию для получения диапазона дат на основе типа даты.
     *
     * @const {Function} getDate - Функция, возвращающая диапазон дат на основе предоставленного типа даты.
     * @param {Object} dateObject - Объект с ключевыми временными интервалами.
     * @param {number} dateObject.beginWeek - UNIX-метка времени начала недели (в секундах).
     * @param {number} dateObject.endWeek - UNIX-метка времени конца недели (в секундах).
     * @param {number} dateObject.beginHalfMonth - UNIX-метка времени начала половины месяца (в секундах).
     * @param {number} dateObject.endHalfMonth - UNIX-метка времени конца половины месяца (в секундах).
     * @param {number} dateObject.beginMonth - UNIX-метка времени начала месяца (в секундах).
     * @param {number} dateObject.endMonth - UNIX-метка времени конца месяца (в секундах).
     * @param {number} dateObject.beginYear - UNIX-метка времени начала года (в секундах).
     * @param {number} dateObject.endYear - UNIX-метка времени конца года (в секундах).
     */
    {/literal}
    const getDate = getDateFromDateObject({
      beginWeek: {$begin_week},
      endWeek: {$end_week},
      beginHalfMonth: {$begin_half_month},
      endHalfMonth: {$end_half_month},
      beginMonth: {$begin_month},
      endMonth: {$end_month},
      beginYear: {$begin_year},
      endYear: {$end_year},
    })

    {literal}
    /**
     * Вычисляет новую дату на основе переданного интервала, периода и операции.
     *
     * @param {Object} params - Параметры для вычисления новой даты.
     * @param {Array<Date>} params.date - Массив с начальной и конечной датами ([begin, end]).
     * @param {number|string} params.interval - Значение интервала для добавления или вычитания.
     * @param {string} params.period - Тип интервала (например, 'year', 'month', 'day', 'hour', 'minute').
     * @param {string} params.operation - Операция, определяющая, добавить или вычесть интервал ('+ interval' или '- interval').
     * @returns {Array<Date>} - Новый массив дат ([newBegin, newEnd]) с учётом интервала и операции.
     */
    const getNewDate = ({
      date: [begin, end],
      interval,
      period,
      operation,
    }) => {
      if(!interval || !period)
        return [begin, end];
      if (operation.includes('+ interval'))
        return [
          addIntervalToDate(begin, +interval, period),
          addIntervalToDate(end, +interval, period),
        ];

      if (operation.includes('- interval')) 
        return [
          addIntervalToDate(begin, -interval, period),
          addIntervalToDate(end, -interval, period),
        ];

      return [begin, end];
    }
    /**
     * Формирует строку с новой датой на основе параметров интервала, периода и операции.
     *
     * @param {string} selector - строка условия для извлечения данных из DOM.
     * @returns {string} - Строка, представляющая новую дату или диапазон дат.
     *                     Формат зависит от типа даты:
     *                     - Для `curdate()`: возвращается только дата в формате "YYYY-MM-DD".
     *                     - Для других типов (`week()`, `half_month()`, `month()`, `year()`):
     *                       возвращается строка в формате "since_from {startDate} since_to {endDate}".
     *                     - По умолчанию возвращается строка в формате "YYYY-MM-DD HH:mm:ss".
     */
    const getNewDateStr = (selector) => {
      const interval = $('#cond_interval_' + selector).val();
      const period = $('#cond_period_' + selector).val();
      const operation = $('#cond_oper_' + selector).val();

      const [date0, date0_end] = getDate(selector);
      
      const [date1, date1_end] = getNewDate({
        date: [date0, date0_end],
        interval,
        period,
        operation,
      })
      const [date2, date2_end] = [formatDate(date1), formatDate(date1_end)]
      const dateType = $('#cond_value_' + selector).val();
      if (
        dateType !== 'week()' 
        && dateType !== 'half_month()'
        && dateType !== 'month()'
        && dateType !== 'year()'
      ) 
        return date2;
      if (dateType === 'curdate()') 
        return date2.split(' ')[0];
      
      return `${lang['since_from']} ${date2} ${lang['since_to']} ${date2_end}`
    }

    {/literal}
    {literal}
      /**
       * @deprecated
       * 
       * Используйте set_date_promt функцию ниже
      */
    {/literal}
    function set_date_promt1(num) {
        if ($('#cond_value_' + num).val() == 'curdate()' || $('#cond_value_' + num).val() == 'now()' || $('#cond_value_' + num).val() == 'week()' || $('#cond_value_' + num).val() == 'half_month()' || $('#cond_value_' + num).val() == 'month()' || $('#cond_value_' + num).val() == 'year()' || ($('#cond_value_' + num).val() == 'fix_date' && $('#cond_date_' + num).val())) {
            var date_type = $('#cond_value_' + num).val();
            switch (date_type) {
                case 'week()':
                    var date0 = {$begin_week};
                    var date0_end = {$end_week};
                    break
                case 'half_month()':
                    var date0 = {$begin_half_month};
                    var date0_end = {$end_half_month};
                    break
                case 'month()':
                    var date0 = {$begin_month};
                    var date0_end = {$end_month};
                    break
                case 'year()':
                    var date0 = {$begin_year};
                    var date0_end = {$end_year};
                    break
                case 'fix_date':
                    var date0 = strtotime($('#cond_date_' + num).val());
                    var date0_end = strtotime($('#cond_date_' + num).val());
                    break
                default:
                    var date0 = strtotime('now');
                    var date0_end = strtotime('now');
                    break
            }
            if ($('#cond_oper_' + num).val() == " + interval ") {
                if ($('#cond_interval_' + num).val() && $('#cond_period_' + num).val()) {
                    var inter0 = '+' + $('#cond_interval_' + num).val() + ' ' + $('#cond_period_' + num).val();
                    inter1 = strtotime(inter0, date0);
                    var date1 = new Date(inter1 * 1000);
                    inter_end = strtotime(inter0, date0_end);

                    if ((date_type == 'month()') && ($('#cond_period_' + num).val() == ' month'))
                        var date1_end = new Date(date1.getFullYear(), date1.getMonth(), new Date(date1.getFullYear(), date1.getMonth() + 1, 0).getDate(), 23, 59, 59);
                    else
                        var date1_end = new Date(inter_end * 1000);
                } else {
                    return false;
                }
            } else if ($('#cond_oper_' + num).val() == " - interval ") {
                if ($('#cond_interval_' + num).val() && $('#cond_period_' + num).val()) {
                    var inter0 = '-' + $('#cond_interval_' + num).val() + ' ' + $('#cond_period_' + num).val();
                    inter1 = strtotime(inter0, date0);
                    var date1 = new Date(inter1 * 1000);
                    inter_end = strtotime(inter0, date0_end);

                    if ((date_type == 'month()') && ($('#cond_period_' + num).val() == ' month'))
                        var date1_end = new Date(date1.getFullYear(), date1.getMonth(), new Date(date1.getFullYear(), date1.getMonth() + 1, 0).getDate(), 23, 59, 59);
                    else
                        var date1_end = new Date(inter_end * 1000);
                } else {
                    return false;
                }
            } else {
                var date1 = new Date(date0 * 1000);
                var date1_end = new Date(date0_end * 1000);
            }

            if ((date1.getDate()).toString().length == 2) {
                var toDay = (date1.getDate()).toString();
            } else {
                var toDay = '0' + (date1.getDate()).toString();
            }

            if ((date1.getMonth() + 1).toString().length == 2) {
                var month = (date1.getMonth() + 1).toString();
            } else {
                var month = '0' + (date1.getMonth() + 1).toString();
            }

            if ((date1.getHours()).toString().length == 2) {
                var Hours = (date1.getHours()).toString();
            } else {
                var Hours = '0' + (date1.getHours()).toString();
            }

            if ((date1.getMinutes()).toString().length == 2) {
                var Minutes = (date1.getMinutes()).toString();
            } else {
                var Minutes = '0' + (date1.getMinutes()).toString();
            }

            if ((date1.getSeconds()).toString().length == 2) {
                var Seconds = (date1.getSeconds()).toString();
            } else {
                var Seconds = '0' + (date1.getSeconds()).toString();
            }

            var date2 = date1.getFullYear().toString() + '-' + month + '-' + toDay + ' ' + Hours + ':' + Minutes + ':' + Seconds;

            if ((date1_end.getDate()).toString().length == 2) {
                var toDay = (date1_end.getDate()).toString();
            } else {
                var toDay = '0' + (date1_end.getDate()).toString();
            }

            if ((date1_end.getMonth() + 1).toString().length == 2) {
                var month = (date1_end.getMonth() + 1).toString();
            } else {
                var month = '0' + (date1_end.getMonth() + 1).toString();
            }

            if ((date1_end.getHours()).toString().length == 2) {
                var Hours = (date1_end.getHours()).toString();
            } else {
                var Hours = '0' + (date1_end.getHours()).toString();
            }

            if ((date1_end.getMinutes()).toString().length == 2) {
                var Minutes = (date1_end.getMinutes()).toString();
            } else {
                var Minutes = '0' + (date1_end.getMinutes()).toString();
            }

            if ((date1_end.getSeconds()).toString().length == 2) {
                var Seconds = (date1_end.getSeconds()).toString();
            } else {
                var Seconds = '0' + (date1_end.getSeconds()).toString();
            }

            var date2_end = date1_end.getFullYear().toString() + '-' + month + '-' + toDay + ' ' + Hours + ':' + Minutes + ':' + Seconds;

            switch (date_type) {
                case 'week()':
                case 'half_month()':
                case 'month()':
                case 'year()':
                    var date3 = lang['since_from'] + ' ' + date2 + ' ' + lang['since_to'] + ' ' + date2_end;
                    break
                default:
                    var date3 = date2;
                    break
            }

            if ($('#cond_value_' + num).val() == 'curdate()') {
                pos_time = date2.indexOf(' ');
                date3 = date2.substr(0, pos_time + 1);
            }
            var term = $('#cond_term_' + num).val();
            switch (term) {
                case '=':
                    var field_str = date3;
                    break
                case '!=':
                    var field_str = lang['none'] + ' ' + date3;
                    break
                case '>':
                    var field_str = lang['later_than'] + ' ' + date3;
                    break
                case '<':
                    var field_str = lang['earlier_than'] + ' ' + date3;
                    break
                case '>=':
                    var field_str = date3 + ' ' + lang['or_later'];
                    break
                case '<=':
                    var field_str = date3 + ' ' + lang['or_earlier'];
                    break
                case ' like ':
                    var field_str = lang['contains'] + ' ' + date3;
                    break
                case ' not like ':
                    var field_str = lang['does_not_contain'] + ' ' + date3;
                    break
            }
            $('#date_promt_' + num).html(field_str + " <span class='help_bt' style='height:16px' title='" + lang.now_tip + "'>");
        }
        else {
            $('#date_promt_' + num).html('');
        }

        if ($('#cond_value_' + num).val() == 'fix_date') {
            $('#date_value_' + num).css("display", "");
        } else {
            $('#date_value_' + num).css("display", "none");
        }

        $('.dtpicker').datetimepicker({
            showOn: 'button',
            dateFormat: 'yy-mm-dd',
            timeFormat: 'HH:mm:ss',
            showAlways: true,
            buttonImage: 'images/calbtn.png',
            buttonImageOnly: true,
            buttonText: 'Calendar',
            showAnim: (('\v' == 'v') ? '' : 'show'),  // в ie не включаем анимацию, тормозит
        }).css('width', '120px');

        const condFieldId = $('#cond_field_' + num).val();
        const condTermVal = $('#cond_term_' + num).val();
        const field = search_fields[condFieldId];
        const fieldType = parseInt(field.type_field);
        const fieldMultVal = parseInt(field.mult_value);
        const isTermFocused = $('#cond_term_' + num).is(':focus');

        if (condTermVal === '=' && isTermFocused) checkFieldForMultiValAndShowTooltip(fieldType, fieldMultVal, 1);
        if (condTermVal === '!=' && isTermFocused) checkFieldForMultiValAndShowTooltip(fieldType, fieldMultVal, 2);
        init_chosen();
    }
    function set_date_promt(num) {
        if ($('#cond_value_' + num).val() == 'curdate()' || $('#cond_value_' + num).val() == 'now()' || $('#cond_value_' + num).val() == 'week()' || $('#cond_value_' + num).val() == 'half_month()' || $('#cond_value_' + num).val() == 'month()' || $('#cond_value_' + num).val() == 'year()' || ($('#cond_value_' + num).val() == 'fix_date' && $('#cond_date_' + num).val())) {
            var date3 = getNewDateStr(num);
            var term = $('#cond_term_' + num).val();
            switch (term) {
                case '=':
                    var field_str = date3;
                    break
                case '!=':
                    var field_str = lang['none'] + ' ' + date3;
                    break
                case '>':
                    var field_str = lang['later_than'] + ' ' + date3;
                    break
                case '<':
                    var field_str = lang['earlier_than'] + ' ' + date3;
                    break
                case '>=':
                    var field_str = date3 + ' ' + lang['or_later'];
                    break
                case '<=':
                    var field_str = date3 + ' ' + lang['or_earlier'];
                    break
                case ' like ':
                    var field_str = lang['contains'] + ' ' + date3;
                    break
                case ' not like ':
                    var field_str = lang['does_not_contain'] + ' ' + date3;
                    break
            }
            $('#date_promt_' + num).html(field_str + " <span class='help_bt' style='height:16px' title='" + lang.now_tip + "'>");
        }
        else {
            $('#date_promt_' + num).html('');
        }

        if ($('#cond_value_' + num).val() == 'fix_date') {
            $('#date_value_' + num).css("display", "");
        } else {
            $('#date_value_' + num).css("display", "none");
        }

        $('.dtpicker').datetimepicker({
            showOn: 'button',
            dateFormat: 'yy-mm-dd',
            timeFormat: 'HH:mm:ss',
            showAlways: true,
            buttonImage: 'images/calbtn.png',
            buttonImageOnly: true,
            buttonText: 'Calendar',
            showAnim: (('\v' == 'v') ? '' : 'show'),  // в ie не включаем анимацию, тормозит
        }).css('width', '120px');

        const condFieldId = $('#cond_field_' + num).val();
        const condTermVal = $('#cond_term_' + num).val();
        const field = search_fields[condFieldId];
        const fieldType = parseInt(field.type_field);
        const fieldMultVal = parseInt(field.mult_value);
        const isTermFocused = $('#cond_term_' + num).is(':focus');

        if (condTermVal === '=' && isTermFocused) checkFieldForMultiValAndShowTooltip(fieldType, fieldMultVal, 1);
        if (condTermVal === '!=' && isTermFocused) checkFieldForMultiValAndShowTooltip(fieldType, fieldMultVal, 2);
        init_chosen();
    }
    // ============ МАСТЕР УСЛОВИЙ ============ //

    var fields_id = [ {foreach $search_fields as $one_field}{$one_field.id}, {/foreach} ]; // массив id полей для правильной сортировки search_fields при его проходе (см. get_fields_options)

    var search_fields = {
        {foreach $search_fields as $one_field}'{$one_field.id}': {
            'id': '{$one_field.id}',
            'table_id': '{$one_field.table_id}',
            'name_field': '{$one_field.name_field|replace:'\\':'\\\\'|replace:"'":"\'"}', 'type_field':'{$one_field.type_field}', 'type_value':'{$one_field.type_value_js}', 'default_value':'{$one_field.default_value_js}', 'main':'{$one_field.main}', 'unique':'{$one_field.unique}', 'mult_value':'{$one_field.mult_value}', 'pp':'{$one_field.pp}', 'int_name':'{$one_field.int_name}', 'view':'{$one_field.view}', 'view_tb':'{$one_field.view_tb}', 'view_edit':'{$one_field.view_edit}', 'view_add':'{$one_field.view_add}', 'read':'{$one_field.read}', 'write':'{$one_field.write}', 'child_link_field':'{$one_field.child_link_field}', 'parent_link_field':'{$one_field.parent_link_field}', 's_field_id':'{$one_field.s_field_id}', 's_table_id':'{$one_field.s_table_id}', 's_field_filter_id':'{$one_field.s_field_filter_id}', 'view_html':'{$one_field.view_html}', 'input_value':"{$one_field.input_value}" }, {/foreach} };

            function get_fields_options()
    {
        var fields_options = "";
        for (var key in fields_id) {
            fields_options += "<option value=" + fields_id[key] + ">" + search_fields[fields_id[key]].name_field + "</option>";
        }
        return fields_options;
    }

    function get_term_options(field) {
        var term_options = "";
        if (field.type_field == 1 || field.type_field == 2 || field.type_field == 8 || field.type_field == 10 || field.type_field == 12)
            term_options = "<option value='='>{$lang['=']}</option><option value='!='>{$lang['!=']}</option><option value='>'>{$lang['>']}</option><option value='<'>{$lang['<']}</option><option value='>='>{$lang['>=']}</option><option value='<='>{$lang['<=']}</option>";
        if (field.type_field == 3 || (field.type_field == 4 && field.mult_value == 1) || (field.type_field == 5 && field.mult_value == 1) || field.type_field == 6 || (field.type_field == 7 && field.mult_value == 1) || field.type_field == 9 || (field.type_field == 14 && field.mult_value == 1))
            term_options = "<option value='='>{$lang['=']}</option><option value='!='>{$lang['!=']}</option><option value=' like '>{$lang['LIKE']}</option><option value=' not like '>{$lang['NOT LIKE']}</option>";
        if ((field.type_field == 4 && field.mult_value == 0) || (field.type_field == 5 && field.mult_value == 0) || (field.type_field == 7 && field.mult_value == 0) || (field.type_field == 14 && field.mult_value == 0) || field.type_field == 11 || field.type_field == 13 || field.type_field == -2)
            term_options = "<option value='='>{$lang['=']}</option><option value='!='>{$lang['!=']}</option>";
        if (term_options) term_options += "<option value='{ldelim}changed{rdelim}'>{ldelim}{$lang.changed}{rdelim}</option>";
        return term_options;
    }

    function get_value_control(field, term, num) {
        var control = "";
        if (field.input_value.substring(0, 7) == "<option")
            control = "<select class='form-control form-control-160' name='cond_set[" + num + "][value]' id='cond_value_" + num + "' onChange='set_date_promt(" + num + "); set_expert();'>" + field.input_value + "</select>";
        else if (field.type_field == 5)
            control = "<select id='cond_value_" + num + "' class='combobox' name='cond_set[" + num + "][value_link]'></select>";
        else
            control = "<input class='form-control form-control-160' type=text name='cond_set[" + num + "][value]' id='cond_value_" + num + "' onChange='set_expert()'>";
        return control;
    }

    function get_union_options(num) {
        var union_options = "";
        union_options = ((num == last_num) ? "<option value=''></option>" : "") + "<option value=' and '>{$lang.and}</option><option value=' or '>{$lang.or}</option>";
        return union_options;
    }

    /**
     * Индексация для автокомплита
     * @type Number
     */
    var global_ac_index = 0;

    function set_search_controls(num, cond_field, cond_term, cond_value, cond_value_link, cond_date, cond_oper, cond_interval, cond_period, cond_union, open_bracket, close_bracket) {
        if (!cond_field) cond_field = +$('#cond_field_' + num).val();
        if (!cond_term && $('#cond_term_' + num).val()) cond_term = $('#cond_term_' + num).val();
        field = search_fields[cond_field];
        const fieldType = parseInt(field.type_field);
        const fieldMultVal = parseInt(field.mult_value);
        const termFocused =  $('#cond_term_' + num).is(':focus');
        const condFocused =  $('#cond_field_' + num).is(':focus');

        $('#cond_field_' + num).html(get_fields_options());
        $('#cond_field_' + num).val(cond_field);
        $('#cond_term_' + num).html(get_term_options(field));
        $('#cond_term_' + num).val(cond_term ? (termFocused ? cond_term : (fieldMultVal === 1 ? (condFocused ? ' like ' : cond_term) : cond_term)) : (fieldMultVal === 1 ? ' like ' : '='));
        $('#span_cond_value_' + num).html(get_value_control(field, cond_term, num));

        const condTermVal = $('#cond_term_' + num).val();
        if (condTermVal === '=') checkFieldForMultiValAndShowTooltip(fieldType, fieldMultVal, 1);
        if (condTermVal === '!=') checkFieldForMultiValAndShowTooltip(fieldType, fieldMultVal, 2);
        
        if (fieldType == 5) {
            create_ac_by_cond('#cond_value_' + num, global_ac_index, cond_value_link, cond_field, '{$table_id}', '{$filter_id}', set_expert);
            global_ac_index++;
        }
        if (fieldType == -1) {
            $('#cond_term_' + num).css("display", "none");
        } else {
            $('#cond_term_' + num).css("display", "");
        }
        if ($('#cond_term_' + num).val() == "{ldelim}changed{rdelim}" || fieldType == -1) {
            $('#span_cond_value_' + num).css("display", "none");
        } else {
            $('#span_cond_value_' + num).css("display", "");
        }
        if (fieldType == 2 || fieldType == 12) {
            $('#date_interval_' + num).css("display", "");
        } else {
            $('#date_interval_' + num).css("display", "none");
        }
        if ((fieldType == 2 || fieldType == 12) && cond_value == 'fix_date') {
            $('#date_value_' + num).css("display", "");
        } else {
            $('#date_value_' + num).css("display", "none");
        }
        if ((fieldType == 2 || fieldType == 12) && !cond_value) {
            $('#cond_value_' + num).val("0000-00-00 00:00:00");
        } else if (fieldType == 13 && !cond_value) {
            $('#cond_value_' + num).val(0);
        } else {
            $('#cond_value_' + num).val(cond_value);
        }
        $('#cond_oper_' + num).html("<option value=''></option><option value=' + interval '>+</option><option value=' - interval '>-</option>");
        $('#cond_period_' + num).html("<option value=''></option><option value=' day'>" + lang.days + "</option><option value=' month'>" + lang.months + "</option><option value=' year'>" + lang.years + "</option><option value=' hour'>" + lang.hours + "</option><option value=' minute'>" + lang.minutes + "</option>");
        $('#cond_date_' + num).val(cond_date);
        $('#cond_oper_' + num).val(cond_oper);
        $('#cond_interval_' + num).val(cond_interval);
        $('#cond_period_' + num).val(cond_period);
        $('#cond_union_' + num).html(get_union_options(num));
        $('#cond_union_' + num).val(cond_union);
        $('#cond_ob_' + num).val(+open_bracket ? 1 : 0);
        $('#cond_cb_' + num).val(+close_bracket ? 1 : 0);
        $('#span_ob_' + num).css('color', +open_bracket ? 'black' : '#ddd');
        $('#span_cb_' + num).css('color', +close_bracket ? 'black' : '#ddd');
        $('#span_ob_' + num).prop('title', +open_bracket ? lang.Disable_bracket: lang.Enable_bracket);
        $('#span_cb_' + num).prop('title', +open_bracket ? lang.Disable_bracket: lang.Enable_bracket);
        set_date_promt(num);
    }

    function add_cond(num, cond_field, cond_term, cond_value, cond_value_link, cond_date, cond_oper, cond_interval, cond_period, cond_union, open_bracket, close_bracket) {
        last_num = num;
        var new_cond = "<div id='cond_" + num + "' class='edit-tip__cond-row'><img alt='{$lang.delete}' title='{$lang.Delete_condition}' src='images/b_drop.png' border=0 style='cursor:pointer; vertical-align:middle; padding-bottom:3px' onclick='del_cond(" + num + ")'> <span id='span_ob_" + num + "' class='brackets' style='cursor:pointer' onclick='set_bracket(\"ob_" + num + "\"); set_expert();'><b>(</b></span> <input type='hidden' name='cond_set[" + num + "][open_bracket]' id='cond_ob_" + num + "'> <select class='form-control form-control-250' name='cond_set[" + num + "][field]' id='cond_field_" + num + "' onChange='set_search_controls(" + num + "); set_expert();'></select> <select class='form-control' name='cond_set[" + num + "][term]' id='cond_term_" + num + "' style='width:150px' onChange='set_search_controls(" + num + "); set_date_promt(" + num + "); set_expert()'></select> <span id='span_cond_value_" + num + "'><input class='form-control' type=text id='cond_value_" + num + "'></span> <span id='date_value_" + num + "'><input class='form-control dtpicker' type=text name='cond_set[" + num + "][date]' id='cond_date_" + num + "' onchange='set_date_promt(" + num + "); set_expert();'></span> <span id='date_interval_" + num + "'><select class='form-control' name='cond_set[" + num + "][oper]' id='cond_oper_" + num + "' style='width:36px' onChange='set_date_promt(" + num + "); set_expert();'></select> <input class='form-control' type=text name='cond_set[" + num + "][interval]' id='cond_interval_" + num + "' style='text-align:right; width:30px;' onChange='set_date_promt(" + num + "); set_expert();'> <select class='form-control' name='cond_set[" + num + "][period]' id='cond_period_" + num + "' style='width:80px' onChange='set_date_promt(" + num + "); set_expert();'></select></span> <span id='span_cb_" + num + "' class='brackets' style='cursor:pointer' onclick='set_bracket(\"cb_" + num + "\"); set_expert();'><b>)</b></span> <input type='hidden' name='cond_set[" + num + "][close_bracket]' id='cond_cb_" + num + "'> <select class='form-control' name='cond_set[" + num + "][union]' id='cond_union_" + num + "' style='width:53px' onChange='if (last_num==" + num + ") add_cond(" + (num + 1) + "); set_expert();'></select> &nbsp; <span id='date_promt_" + num + "' style='color:gray'></span></div>";
        if (num == 1) {
            $("#wizard_set").html(new_cond);
        }
        else {
            prev_cond_union = $('#cond_union_' + (num - 1)).val();
            $('#cond_union_' + (num - 1)).html(get_union_options((num - 1)));
            $('#cond_union_' + (num - 1)).val(prev_cond_union);
            $("#cond_" + (num - 1)).after(new_cond);
        }
        set_search_controls(num, cond_field, cond_term, cond_value, cond_value_link, cond_date, cond_oper, cond_interval, cond_period, cond_union, open_bracket, close_bracket)
    }

    function set_bracket(id) {
        var bracket = ($('#cond_' + id).val() == '1') ? 0 : 1;
        $('#cond_' + id).val(bracket);
        $('#span_' + id).css('color', bracket ? 'black' : '#ddd');
        $('#span_' + id).prop('title', bracket ? lang.Disable_bracket: lang.Enable_bracket);
    }

    function del_cond(num) {
        $('#cond_' + num).remove();
        if (num == last_num) {
            for (var i = num - 1; i > 0; i--) {
                if (document.getElementById('cond_' + i)) {
                    last_num = i;
                    $('#cond_union_' + i).html(get_union_options(i));
                    break;
                }
            }
        }
        if (!$('#wizard_set').html()) add_cond(1);
        set_expert();
    }

    function set_expert() {
        var condition = "";
        var and_count = 0;
        var or_count = 0;
        for (var num = 1; num <= last_num; num++) {
            if (document.getElementById('cond_' + num) && $('#cond_field_' + num).val() == '-1') {
                condition += "{ldelim}new_record{rdelim}" + $('#cond_union_' + num).val();
            }
            if (document.getElementById('cond_' + num) && ($('#cond_field_' + num).val() > '0' || $('#cond_field_' + num).val() == '-2')) {
                var cond_field = +$('#cond_field_' + num).val();
                var cond_term = $('#cond_term_' + num).val();
                var cond_value = $('#cond_value_' + num).val();
                var cond_date = $('#cond_date_' + num).val();
                var cond_oper = $('#cond_oper_' + num).val();
                var cond_interval = $('#cond_interval_' + num).val();
                var cond_period = $('#cond_period_' + num).val();
                var cond_union = $('#cond_union_' + num).val();
                var open_bracket = $('#cond_ob_' + num).val() == '1' ? '(' : '';
                var close_bracket = $('#cond_cb_' + num).val() == '1' ? ')' : '';
                
                if (cond_value == 'null' || typeof cond_value == 'object') cond_value = '0'; // Для полй типа Связь устанавливаем 0 для пустого значения
                if (search_fields[cond_field].type_field == 5 && search_fields[cond_field].mult_value == 1)
                    cond_value = '-' + cond_value + '-';
                if (cond_term == "{ldelim}changed{rdelim}") {
                    cond_value = '';
                }

                if ($('#cond_field_' + num).val() == '-2')
                    cond_field = "'{ldelim}current{rdelim}'"
                else
                    cond_field = "`" + search_fields[cond_field].name_field + "`";
                if (cond_term == " like " || cond_term == " not like ") cond_value = "%" + cond_value + "%";
                if (cond_value == "fix_date")
                    cond_value = "'" + cond_date + "'";
                else if (cond_value != "curdate()" && cond_value != "now()" && cond_value != "week()" && cond_value != "month()" && cond_value != "year()" && cond_term != "{ldelim}changed{rdelim}") {
                    cond_value = "'" + cond_value.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
                }
                if (cond_value == "curdate()")
                    var one_cond = "left(" + cond_field + ",10)" + cond_term + cond_value + cond_oper + cond_interval + cond_period;
                else if (cond_value == "week()") {
                    if (cond_term == "=")
                        var one_cond = "(" + cond_field + ">='{ldelim}begin_week{rdelim}' " + cond_oper + cond_interval + cond_period + " and " + cond_field + "<='{ldelim}end_week{rdelim}'" + cond_oper + cond_interval + cond_period + ")";
                    else if (cond_term == "!=")
                        var one_cond = "(" + cond_field + "<='{ldelim}begin_week{rdelim}' " + cond_oper + cond_interval + cond_period + " or " + cond_field + ">='{ldelim}end_week{rdelim}'" + cond_oper + cond_interval + cond_period + ")";
                    else if (cond_term == ">")
                        var one_cond = cond_field + ">'{ldelim}end_week{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == "<")
                        var one_cond = cond_field + "<'{ldelim}begin_week{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == ">=")
                        var one_cond = cond_field + ">='{ldelim}begin_week{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == "<=")
                        var one_cond = cond_field + "<='{ldelim}end_week{rdelim}'" + cond_oper + cond_interval + cond_period;
                }
                else if (cond_value == "month()") {
                    if (cond_term == "=")
                        var one_cond = "(" + cond_field + ">='{ldelim}begin_month{rdelim}' " + cond_oper + cond_interval + cond_period + " and " + cond_field + "<=DATE_FORMAT(LAST_DAY('{ldelim}end_month{rdelim}'" + cond_oper + cond_interval + cond_period + "),'%Y-%m-%d 23:59:59'))";
                    else if (cond_term == "!=")
                        var one_cond = "(" + cond_field + "<='{ldelim}begin_month{rdelim}' " + cond_oper + cond_interval + cond_period + " or " + cond_field + ">=DATE_FORMAT(LAST_DAY('{ldelim}end_month{rdelim}'" + cond_oper + cond_interval + cond_period + "),'%Y-%m-%d 23:59:59'))";
                    else if (cond_term == ">")
                        var one_cond = cond_field + ">DATE_FORMAT(LAST_DAY('{ldelim}end_month{rdelim}'" + cond_oper + cond_interval + cond_period + "),'%Y-%m-%d 23:59:59')";
                    else if (cond_term == "<")
                        var one_cond = cond_field + "<'{ldelim}begin_month{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == ">=")
                        var one_cond = cond_field + ">='{ldelim}begin_month{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == "<=")
                        var one_cond = cond_field + "<=DATE_FORMAT(LAST_DAY('{ldelim}end_month{rdelim}'" + cond_oper + cond_interval + cond_period + "),'%Y-%m-%d 23:59:59')";
                }
                else if (cond_value == "year()") {
                    if (cond_term == "=")
                        var one_cond = "(" + cond_field + ">='{ldelim}begin_year{rdelim}' " + cond_oper + cond_interval + cond_period + " and " + cond_field + "<='{ldelim}end_year{rdelim}'" + cond_oper + cond_interval + cond_period + ")";
                    else if (cond_term == "!=")
                        var one_cond = "(" + cond_field + "<='{ldelim}begin_year{rdelim}' " + cond_oper + cond_interval + cond_period + " or " + cond_field + ">='{ldelim}end_year{rdelim}'" + cond_oper + cond_interval + cond_period + ")";
                    else if (cond_term == ">")
                        var one_cond = cond_field + ">'{ldelim}end_year{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == "<")
                        var one_cond = cond_field + "<'{ldelim}begin_year{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == ">=")
                        var one_cond = cond_field + ">='{ldelim}begin_year{rdelim}'" + cond_oper + cond_interval + cond_period;
                    else if (cond_term == "<=")
                        var one_cond = cond_field + "<='{ldelim}end_year{rdelim}'" + cond_oper + cond_interval + cond_period;
                }
                else
                    var one_cond = cond_field + cond_term + cond_value + cond_oper + cond_interval + cond_period;

                if ((cond_value == "now()" || cond_value == "curdate()") && cond_term.substring(0, 1) == '<')
                    one_cond = "(" + one_cond + " and " + cond_field + "!='0000-00-00 00:00:00')";
                condition += open_bracket + one_cond + close_bracket + cond_union;
                and_count += (cond_union == ' and ') ? 1 : 0;
                or_count  += (cond_union == ' or ' ) ? 1 : 0;
            }
        }
        if (condition.substring(condition.length - 5) == " and ") condition = condition.substring(0, condition.length - 5);
        if (condition.substring(condition.length - 4) == " or ") condition = condition.substring(0, condition.length - 4);
        $("#condition").val(condition);
        if (and_count == 0 || or_count == 0) {
            $('.brackets').css('visibility', 'hidden');
        } else {
            $('.brackets').css('visibility', 'visible');
        }
    }

    function check_brackets() {
        var open_brackets = 0;
        var close_brackets = 0;
        for (var num = 1; num <= last_num; num++) {
            if (document.getElementById('cond_' + num) && $('#cond_field_' + num).val() != 0 && !$('#cond_field_' + num).prop("disabled")) {
                open_brackets += +$('#cond_ob_' + num).val();
                close_brackets += +$('#cond_cb_' + num).val();
                if (close_brackets && !open_brackets) break;
            }
        }
        if (open_brackets != close_brackets) {
            return false;
        } else {
            return true;
        }
    }

    $(function () {
        var last_num = 0;
        {foreach from=$cond_set item=cond key=num}
        add_cond({$num}, {$cond.field}, '{$cond.term}', '{$cond.value|replace:"'":"\'"}', '{$cond.value_link}', '{$cond.date}', '{$cond.oper}', '{$cond.interval}', '{$cond.period}', '{$cond.union}', '{$cond.open_bracket}', '{$cond.close_bracket}');
        {foreachelse}
        add_cond(1);
        {/foreach}
    });

    // Проверяем заполненность полей
    function checkInformersFields() {
        const informerName = $('#name');
        const informerText = $('#text');

        // Имя информера
        if (informerName.val().replace(/\s/g,'').length < 1) {
            jalert(lang.Empty_informer_title);
            return false;
        }

        // Текст информера
        if (informerText.val().replace(/\s/g,'').length < 1) {
            const fieldName = informerText.attr('field_name');

            jalert(lang.Qst_required_alert + ' "' + fieldName + '"');
            return false;
        }
    }

    //создаем пременные цветов кнопок
    {foreach from=$buttonColors key=one_name item=one_color}
        var color_{$one_name} = '{$one_color}';
    {/foreach}

    // Изменение цвета информера при изменении значения в списке
    function changeСolor(colorSelect) {
        const curOptBgColor = $(colorSelect).val();
        const curOptTxtColor = $(colorSelect).find('option[value="' + curOptBgColor + '"]').attr('txt_col');
        const bgColorVal = $('#bg_color_val');
        const txtColorVal = $('#txt_color_val');
        const informerExample = $('#colors_exapmle');
        const exampleBgcolor = curOptBgColor !== 'null' ? this['color_' + curOptBgColor] : '';
        const exampleTxtcolor = curOptBgColor !== 'null' ? curOptTxtColor : '';

        informerExample.css('background-color', exampleBgcolor);
        informerExample.css('color', exampleTxtcolor);

        bgColorVal.val(exampleBgcolor);
        txtColorVal.val(exampleTxtcolor);
    }

    {literal}
    // Разрешаем пользователю вводить больше 120 символов, но при этом текст будет впоследствии обрезаться до 120 символов
    // Информация об этом прописана в справке по полю (знак вопроса)
    function checkValueLength(item) {
        var $item = $(item);
        if (item == undefined) {
            $item = $('#text');
        }
        var errorMsg = $('.status-max-length__error');
        var saveBtn = $('#saveInformer');
        var curValue = $item.val();
        var valueLength = $item.val().length;
        const templateStart = curValue.indexOf("}") > -1;
        const templateEnd = curValue.indexOf("{") > -1;

        // if (valueLength > 120) {                   
        //     errorMsg.css('display', '');
        //     return false;

        //     //$item.css('box-shadow', 'none');
        //     //$item.css('border', '1px solid red');
        //     //saveBtn.attr('disabled', true);     
        //     //$item.val(curValue.substr(0, 121));
        // } else {
        //     if (templateStart && templateEnd) {
        //         errorMsg.css('display', '');
        //     } else {
        //         $item.css('border', '');
        //         errorMsg.css('display', 'none');
        //     }
            
        //     //$item.css('box-shadow', 'inset 0 1px 1px rgba(0,0,0,.075)');           
        //     //saveBtn.attr('disabled', false)
        // }
    }
    {/literal}

    //функция show/hide режима редактироваия цвета
    function changeColorMode() {
        const standartMode = $('#color-standart');
        const paletteMode = $('#color-palette');
        const standartModeBtn = $('#standart-mode');
        const paletteModeBtn = $('#palette-mode');
        const select = $('#color-select');

        if (standartModeBtn.attr('checked')) {
            const hiddenValBg = $('#palette_bg').val();
            const hiddenValTxt = $('#palette_txt').val();
            const bgColorVal = $('#bg_color_val');
            const txtColorVal = $('#txt_color_val');

            bgColorVal.val(hiddenValBg);
            txtColorVal.val(hiddenValTxt);
            paletteMode.show();
            standartMode.hide();
            paletteModeBtn.attr('checked', true);
            standartModeBtn.removeAttr('checked');
        } else {
            changeСolor(select);
            standartMode.show();
            paletteMode.hide();
            standartModeBtn.attr('checked', true);
            paletteModeBtn.removeAttr('checked');
        }
    }
</script>
<br>
<div align=center>
    {if $no_save_mode}<img src="images/lock.svg" style="width:20px; padding-right:5px;" title="{$lang.Element_no_edit_msg}">{/if}
    {if $informer_id eq -1}{$lang.Create_informer}{else}{$lang.Edit_informer} "{$name}"{/if} {$lang.of_table} "{$name_table}"
    {if $informer_id != -1 && !$blocked}
        <div style="left: 10px; top: 2px; float: none;"
            onclick="switchOnObject('{$informer_id}')"
            class="switch-btn {if !$disabled}switch-on{/if}"
            id="switch-on-btn_{$informer_id}"></div>
        <script>
            let ajaxObj = new XMLHTTP("edit_status.php");
            ajaxObj.format = 0;
            ajaxObj.method = "POST";
            function switchOnObject(status_id) {
                $('#switch-on-btn_'+status_id).toggleClass('switch-on');
                $('#switch-on-btn_'+status_id).trigger('on.switch');
                ajaxObj.call('status_id='+status_id+'&sel=disable&enbl='+($('#switch-on-btn_'+status_id).hasClass('switch-on')?1:0)+'&csrf={$csrf}',()=>{});
            }
        </script>
    {/if}
</div>
<br>
{if $message}
    <div style="text-align:center;font-size: 13px;">
        <span id="edit_config__info-maessage" style="color:green">{$message}</span><br><br>
    </div>
{/if}
{if $error}
    <div style="text-align:center;font-size: 13px;">
        <span id="edit_config__info-maessage" style="color:red">{$error}</span><br><br>
    </div>
{/if}
{if $blocked}
    <div style="text-align:center;font-size: 13px;">
        <a href="edit_status.php?table={$table_id}">{$lang.Return}</a>
    </div>
{else}
<form action="edit_status.php?table={$table_id}&informer={$informer_id}" method=post id="informer_form" enctype="multipart/form-data">
    <input type=hidden name=back_url value="{$base64_back_url}">
    <input type=hidden name=csrf value="{$csrf}">
    <table border=0 cellpadding=3>
        <tr>
            <td align=right width=130>{$lang.Name2}<span class='help_bt' h_id='Informer_name'></span>:</td>
            <td><input class="form-control form-control-250" type=text size=50 name="name" id="name" value="{$name}"></td>
        </tr>
        <tr>
            <td></td>
        </tr>
        <tr>
            <td align=right>{$lang.Conditions}<span class='help_bt' h_id='Informer_conditions'></span>:</td>
            <td>
                <input type=radio name="mode" value="wizard" {if $mode=="wizard"}checked{/if}
                       onclick="document.getElementById('wizard_mode').style.display=''; document.getElementById('expert_mode').style.display='none';"> {$lang.wizard_mode}
                &nbsp;&nbsp;
                <input type=radio name="mode" value="expert" {if $mode=="expert"}checked{/if}
                       onclick="document.getElementById('expert_mode').style.display=''; document.getElementById('wizard_mode').style.display='none';"
                       {if !$all_modules.pro_tariff && $mode != "expert"}disabled title="{$lang.Pro_tariff_func_message}"{/if}>
                <span {if !$all_modules.pro_tariff && $mode != "expert"}style="color: #999;"{/if}>{$lang.expert_mode}</span>
                &nbsp;&nbsp;
            </td>
        </tr>
        <tr id="wizard_mode" {if $mode=="expert"}style="display:none"{/if}>
            <td></td>
            <td id="wizard_set"></td>
        </tr>
        <tr id="expert_mode" {if $mode=="wizard"}style="display:none"{/if}>
            <td></td>
            <td><textarea class="form-control" name="cond_value" id="condition" cols=100 rows=5
                          {if $user.group_id!=1}readonly="1"{/if}>{$cond_value}</textarea></td>
        </tr>
        <tr>
            <td></td>
        </tr>
        <tr>
            <td align=right>{$lang.Text}<span class='help_bt' h_id='Informer_text'></span>:</td>
            <td><textarea class="form-control status-text" onBlur="checkValueLength(this);" 
                onChange="checkValueLength(this);" onkeyup="checkValueLength(this);" 
                name="text" id="text" field_name="{$lang.Text}" cols=3 rows=3>{$text}</textarea>
            </td>
        </tr>
        <tr>
            <td></td>
            <td style="display: flex;"><span class="status-max-length__error" style="display: none;">{$lang.InforemerMaxLength}</span></td>
        </tr>
        <tr>
            <td align=right>
                {$lang.Insert_field_template}<span class='help_bt' h_id='Informer_insert_field_template'></span>:
            </td>
            <td>
                <select class="form-control form-control-250" id="ins_field_text">{$sel_ins_field}</select>
                <input class="btn btn-default btn-sm" type=button value=OK onclick="insert_field('text')">
            </td>
        </tr>
        <tr>
            <td></td>
        </tr>

        <tr>
            <td align=right>{$lang.Color_mode}<span class='help_bt' h_id='Informer_color_mode'></span>:</td>
            <td>
                <table>
                    <tr>
                        <td>
                            <label class="radio-inline">
                                <input type="radio" id="standart-mode" onchange="changeColorMode();" 
                                       name="color_mode" value="0" {if !$color_mode}checked{/if}>{$lang.Standart}
                            </label>
                            <label class="radio-inline">
                                <input type="radio" id="palette-mode" onchange="changeColorMode();" 
                                       name="color_mode" value="1" {if $color_mode}checked{/if}>{$lang.Paint}
                            </label>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>

        <!-- Выбор цвета из готовых комбинаций -->
        <tr class="informer-bg-color" id="color-standart" {if $color_mode}style="display: none;"{/if}>
            <td align="right">{$lang.Informer_color}<span class="help_bt" h_id="Informer_color_set"></span>:</td>
            <td>
                <table>
                    <tbody>
                        <tr>
                            <td>
                                <select class="form-control form-control-160" id="color-select" 
                                        onchange="changeСolor(this);">
                                            {$color_options}
                                </select>
                            </td>
                            <td class="informer__color-example--row">
                                <div class="informer__color-example--div" id="colors_exapmle"
                                     style="background-color:{if $bg_color}{$bg_color}{else}#ededed{/if};color:{if $txt_color}{$txt_color}{else}#4b4b4b{/if};">
                                        <span id="informer_example">{$lang.Informer}</span>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>

        <tr>
            <td></td>
        </tr>

        <!-- Выбор цвета с помощью колопикеров -->
        <tr class='informer-colors' id="color-palette" {if !$color_mode}style="display: none;"{/if}>
            <td align="right">{$lang.BackgroundColor}<span class='help_bt' h_id='Informer_bg_color'></span>:</td>
            <td>
                <table>
                    <tr>
                        <td class="informer__txt-settings">
                            <input type="text" id="bg_color" class="colorSelector" value="{if $bg_color}{$bg_color}{/if}" />
                        </td>
                        <td align="right">{$lang.Text_color}<span class="help_bt" h_id="Informer_txt_color"></span>:</td>
                        <td class="informer__txt-settings">
                            <input type="text" id="txt_color" class="colorSelector" value="{if $txt_color}{$txt_color}{/if}" />
                        </td>
                        <td class="informer__color-example--row">
                            <div class="informer__color-example--div" id="informer_colors_exapmle"
                                 style="{if $bg_color}background-color:{$bg_color};{/if}{if $txt_color}color:{$txt_color};{/if}">
                                    <span id="informer_example">{$lang.Informer}</span>
                            </div>
                            <input type="hidden" id="palette_bg" class="hidden" value="{if $bg_color}{$bg_color}{/if}" />
                            <input type="hidden" id="palette_txt" class="hidden" value="{if $txt_color}{$txt_color}{/if}" />
                        </td>
                    </tr>
                </table>

                <script>
                    colorpickerSetings.clearText = lang.Reset;
                    colorpickerSetings.allowEmpty = true;

                    colorpickerSetings.show = function (e) {
                        $('.sp-clear.sp-clear-display').each(function (btnIndex, btn) {
                            let clearBtn = $(btn);
                            let hiddenInputForDataText = $('#txt_color_val'); 
                            let hiddenInputForDataBg = $('#bg_color_val'); 
                            let example = $('#informer_colors_exapmle');

                            clearBtn.on('click', function(e) {
                                const activePicker = $('.sp-replacer.sp-light.sp-active');
                                const hiddenValBg = $('#palette_bg');
                                const hiddenValTxt = $('#palette_txt');

                                if (activePicker.prev().attr('id') === 'bg_color') {
                                    hiddenInputForDataBg.val('');
                                    example.css('background-color', '');
                                    hiddenValBg.val('');
                                }
                                if (activePicker.prev().attr('id') === 'txt_color') {
                                    hiddenInputForDataText.val('');
                                    example.css('color', '');
                                    hiddenValTxt.val('');
                                }
                            });
                        });
                    }

                    colorpickerSetings.change = function (color) {
                        if (color) {
                            const curColor = color.toHexString();
                            const hiddenValBg = $('#palette_bg');

                            hiddenValBg.val(curColor);
                            $('#bg_color_val').val(curColor);
                            $('#informer_colors_exapmle').css('background-color', curColor);                       
                        }
                    };
                    $('#bg_color').spectrum(colorpickerSetings);

                    colorpickerSetings.change = function (color) {
                        if (color) {
                            const curColor = color.toHexString();
                            const hiddenValTxt = $('#palette_txt');

                            hiddenValTxt.val(curColor);
                            $('#txt_color_val').val(curColor);
                            $('#informer_colors_exapmle').css('color', curColor);
                        }
                    };
                    $('#txt_color').spectrum(colorpickerSetings);

                    $(document).ready(() => {
                        $('#informer_colors_exapmle').css('background-color', $('#bg_color_val').val());
                        $('#informer_colors_exapmle').css('color', $('#txt_color_val').val());
                    });
                </script>

            </td>
        </tr>
        <input type="hidden" name="bg_color" id="bg_color_val" value="{if $bg_color}{$bg_color}{else}{if !$color_mode}#ededed{else}{/if}{/if}" />
        <input type="hidden" name="txt_color" id="txt_color_val" value="{if $txt_color}{$txt_color}{else}{if !$color_mode}#4b4b4b{else}{/if}{/if}" />

        <tr>
            <td></td>
        </tr>
        <tr>
            <td align="right">
                {$lang.Informer_description}<span class="help_bt" h_id="Informer_help_info"></span>:
            </td>
            <td>
                <textarea class="form-control informer__color--description" name="description" rows="3" cols="3">{if $description}{$description}{else}{/if}</textarea>
            </td>
        </tr>

        <tbody 
          id='additional' 
          class='additional'
        >
        </tbody>
        <tr>
            <td></td>
            <td>
                {if $config.protect_of_elements && $user.id == 1}<a href="" id="protect_switch" style="width: 60px;display: inline-block">{$lang.Protect}</a>{/if}
                {if $informer_id > 0}<a href="edit_log.php?st_date=00&f_text=edit_status.php?table%3D{$table_id}%26informer%3D{$informer_id}>" target="_blank">{$lang.Log}</a>{/if}
            </td>
        </tr>
        <tr class="config_access_rules_window access_window_header">
            <td align=right></td>
            <td>
                {$lang.Display_in}
            </td>
        </tr>

        {foreach from=$access_data key=gid item=acc}
            <tr class="config_access_rules_window access_window_eyes access_checkbox_wrapper">
                <td style="padding: 0" align=right>{$acc.name}:</td>
                <td style="padding: 0">
                    <div style="float: left;margin:0 50px 0 32px;width: 31px; padding-top: 8px; padding-bottom: 6px; text-align: center;">
                        <input name="ob_access[{$gid}]" value="{$acc.access}" data-o_value="{$acc.access}"
                               data-type="access" data-gid="{$gid}" {if $acc.pid}data-parent="{$acc.parent}"
                               data-pid='{$acc.pid.access}'{/if} type="hidden">
                        <img src="images/check_{if $acc.access==2}dis_on{elseif $acc.access==3}dis_off{elseif $acc.access}on{else}off{/if}_m.png">
                    </div>
                </td>
            </tr>
        {/foreach}
        {if $config.protect_of_elements && $user.id == 1}
        <tbody id="protect_block" style="display:none">
            <tr>
                <td align="right">{$lang.Protected}<span class='help_bt' h_id='Protect_of_element'></span>:</td>
                <td>
                    <input type="checkbox" name="protected" {if $protected}checked{/if} onclick="$('[id^=pr_]').prop('disabled', !this.checked)">
                    <span class="access_param_wrapper">{$lang.View2}<span class='help_bt' h_id='protect_of_view'></span></span>
                    <span class="access_param_wrapper">{$lang.Edit3}<span class='help_bt' h_id='protect_of_edit'></span></span>
                </td>
            </tr>
            <tr>
                <td align="right"></td>
                <td>
                    <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 15px; text-align: center;">
                        <input type="checkbox" id="pr_view_all" {if !$protected}disabled{/if}
                               onclick="$('[id^=pr_view]').prop('checked', this.checked); if (!this.checked) $('[id^=pr_edit]').prop('checked', 0);">
                    </div>
                    <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 0; text-align: center;">
                        <input type="checkbox" id="pr_edit_all" {if !$protected}disabled{/if}
                               onclick="$('[id^=pr_edit]').prop('checked', this.checked); if ( this.checked) $('[id^=pr_view]').prop('checked', 1);">
                    </div>
                </td>
            </tr>
            {foreach from=$protect key=gid item=acc}
                <tr>
                    <td align="right" style="padding-top: 11px;">{$acc.name}:</td>
                    <td style="display: flex; flex-wrap: nowrap;">
                        <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 15px; text-align: center;">
                            <input type="checkbox" name="protect_rights[{$gid}][view]" id="pr_view{$gid}" value="1"
                                   {if $acc.view}checked{/if} {if !$protected}disabled{/if}
                                   onclick="if (!this.checked) $('#pr_edit{$gid}').prop('checked', 0)">
                        </div>
                        <div style="float: left; margin:0 34px; width: 60px; padding: 8px 0 6px 0; text-align: center;">
                            <input type="checkbox" name="protect_rights[{$gid}][edit]" id="pr_edit{$gid}" value="1"
                                   {if $acc.edit}checked{/if} {if !$protected}disabled{/if}
                                   onclick="if ( this.checked) $('#pr_view{$gid}').prop('checked', 1)">
                        </div>
                    </td>
                </tr>
            {/foreach}
            <tr><td></td></tr>
            <tr>
                <td align=right>{$lang.Comment}<span class='help_bt' h_id='protect_comment'></span>:</td>
                <td><textarea class="form-control form-control-250" name="protect_comment" rows=5>{$protect_comment}</textarea></td>
            </tr>
        </tbody>
        {/if}
        <tr>
            <td colspan="4" align="center"><br>
                <input class="btn btn-default btn-sm" type=submit name="save" value="{$lang.Save}" id="saveInformer"
                       onClick="link_fields_in_condition(); checkValueLength();
                       if (!check_brackets()) { jalert('{$lang.Incorrect_brackets_alert}'); return false; }; return checkInformersFields();"
                       {if $no_save_mode}disabled title="{$lang.Element_no_edit_msg}"{/if}>
                <br/><br/>
                <a href="edit_status.php?table={$table_id}{$back_url_prm}">{$lang.Return}</a> 
            </td>
        </tr>
    </table>
</form>
{/if}
<script src="include/js/configuration.js?{$revision}"></script>