'use strict';

var utils = require('./utils.js');
var stringResources = require('./stringResources.js');
var enums = require('./enums.js');
var RCV = require('@progress/telerik-common-report-viewer');

var parameterEditorsMatch = {
  // AvailableValues PROVIDED, MultiValue is TRUE and trv.parameters.editors.multiSelect is unset
  MultiSelect: (parameter, editorsType) => {
    return Boolean(parameter.availableValues) && parameter.multivalue && (!editorsType || !editorsType.multiSelect || editorsType.multiSelect !== enums.ParameterEditorTypes.COMBO_BOX);
  },
  // AvailableValues PROVIDED, MultiValue is TRUE and trv.parameters.editors.multiSelect is set to COMBO_BOX
  MultiSelectCombo: (parameter, editorsType) => {
    return Boolean(parameter.availableValues) && parameter.multivalue && (editorsType && editorsType.multiSelect && editorsType.multiSelect === enums.ParameterEditorTypes.COMBO_BOX);
  },
  // AvailableValues PROVIDED, MultiValue is FALSE and trv.parameters.editors.singleSelect is unset
  SingleSelect: (parameter, editorsType) => {
    return Boolean(parameter.availableValues) && !parameter.multivalue && (!editorsType || !editorsType.singleSelect || editorsType.singleSelect !== enums.ParameterEditorTypes.COMBO_BOX);
  },
  // AvailableValues PROVIDED, MultiValue is FALSE and trv.parameters.editors.singleSelect is set to COMBO_BOX
  SingleSelectCombo: (parameter, editorsType) => {
    return Boolean(parameter.availableValues) && !parameter.multivalue && (editorsType && editorsType.singleSelect && editorsType.singleSelect === enums.ParameterEditorTypes.COMBO_BOX);
  },
  // AvailableValues NOT PROVIDED and MultiValue is TRUE
  MultiValue: (parameter) => {
    return Boolean(parameter.multivalue);
  },
  DateTime: (parameter) => {
    return parameter.type === enums.ParameterTypes.DATETIME;
  },
  String: (parameter) => {
    return parameter.type === enums.ParameterTypes.STRING;
  },
  Number: (parameter) => {
    switch (parameter.type) {
      case enums.ParameterTypes.INTEGER:
      case enums.ParameterTypes.FLOAT:
        return true;
      default:
        return false;
    }
  },
  Boolean: (parameter) => {
    return parameter.type === enums.ParameterTypes.BOOLEAN;
  },
  Default: (parameter) => {
    return true;
  }
};
var multivalueUtils = function() {
  var lineSeparator = "\n";
  return {
    formatValue: (value) => {
      var text = "";
      if (value) {
        [].concat(value).forEach((val) => {
          if (text.length > 0) {
            text += lineSeparator;
          }
          text += val;
        });
      }
      return text;
    },
    parseValues: (text) => {
      return ("" + text).split(lineSeparator);
    }
  };
}();
function integerInputBehavior(input) {
  function isValid(newValue) {
    return /^(\-|\+)?([0-9]*)$/.test(newValue);
  }
  function onKeyPress(event) {
    if (utils.isSpecialKey(event.keyCode)) {
      return true;
    }
    return isValid($(input).val() + String.fromCharCode(event.charCode));
  }
  function onPaste(event) {
  }
  function attach(input2) {
    $(input2).on("keypress", onKeyPress).on("paste", onPaste);
  }
  function detach(input2) {
    $(input2).off("keypress", onKeyPress).off("paste", onPaste);
  }
  attach(input);
  return {
    dispose: () => {
      detach(input);
    }
  };
}
function floatInputBehavior(input) {
  function isValid(newValue) {
    return /^(\-|\+)?([0-9]*(\.[0-9]*)?)$/.test(newValue);
  }
  function onKeyPress(event) {
    if (utils.isSpecialKey(event.keyCode)) {
      return true;
    }
    return isValid($(input).val() + String.fromCharCode(event.charCode));
  }
  function onPaste(event) {
  }
  function attach(input2) {
    $(input2).on("keypress", onKeyPress).on("paste", onPaste);
  }
  function detach(input2) {
    $(input2).off("keypress", onKeyPress).off("paste", onPaste);
  }
  attach(input);
  return {
    dispose: () => {
      detach(input);
    }
  };
}
function applyClass(apply, cssClass, item) {
  var fn = apply ? $.fn.addClass : $.fn.removeClass;
  fn.call(item, cssClass);
}
function enableItem(item, enable) {
  applyClass(!enable, "k-disabled", item);
}
function selectItem(item, select) {
  applyClass(select, "k-selected", item);
  item.attr("aria-selected", select);
}
function addAccessibilityAttributes(editor, type, caption, additionalInfo, error) {
  if (!additionalInfo) {
    additionalInfo = "";
  }
  var label = utils.stringFormat("{0}. {1} {2}. {3}", [caption, type, stringResources.stringResources.ariaLabelParameter, additionalInfo]);
  editor.attr("aria-label", label);
  setAccessibilityErrorAttributes(editor, error);
}
var containerTabIndex;
var editorsIndex = 0;
function setEditorTabIndex(editor) {
  if (!containerTabIndex) {
    var $container = $(".trv-parameters-area-content");
    if ($container.length > 0) {
      var tabIndexAttr = $container.attr("tabIndex");
      if (tabIndexAttr) {
        containerTabIndex = RCV.tryParseInt(tabIndexAttr);
      }
    }
    if (!containerTabIndex || isNaN(containerTabIndex)) {
      containerTabIndex = 300;
    }
  }
  var wrapper = editor.closest(".trv-parameter-value");
  var selectAll = wrapper.find(".trv-select-all");
  var clearSelection = wrapper.find(".trv-select-none");
  var widgetParent = editor.closest(".k-widget");
  var hasFocusableElement = widgetParent.find(".k-input");
  var isComboWidget = hasFocusableElement && hasFocusableElement.length;
  if (selectAll && selectAll.length) {
    selectAll.attr("tabindex", containerTabIndex + ++editorsIndex);
  }
  if (clearSelection && clearSelection.length) {
    clearSelection.attr("tabindex", containerTabIndex + ++editorsIndex);
  }
  if (isComboWidget) {
    hasFocusableElement.attr("tabindex", containerTabIndex + ++editorsIndex);
  } else {
    editor.attr("tabindex", containerTabIndex + ++editorsIndex);
  }
}
function setAccessibilityErrorAttributes(editor, error) {
  var errToken = utils.stringFormat(" {0}:", [stringResources.stringResources.ariaLabelErrorMessage]);
  var label = editor.attr("aria-label");
  if (!label) {
    return;
  }
  var errIdx = label.indexOf(errToken);
  if (errIdx > -1) {
    label = label.substring(0, errIdx);
  }
  if (error && error !== "") {
    editor.attr("aria-required", true);
    editor.attr("aria-invalid", true);
    label += errToken + error;
  } else {
    editor.removeAttr("aria-invalid");
  }
  editor.attr("aria-label", label);
}
function navigatableEnabledForList(enableAccessibility) {
  return kendo.version >= "2017.3.1018" || enableAccessibility;
}
var ParameterEditors = [
  {
    match: parameterEditorsMatch.MultiSelect,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var enabled = true;
      $placeholder.html(options.templates["trv-parameter-editor-available-values-multiselect"]);
      var $list = $placeholder.find(".trv-list");
      var $selectAll = $placeholder.find(".trv-select-all");
      var $selectNone = $placeholder.find(".trv-select-none");
      var listView;
      var parameter;
      var updateTimeout;
      var valueChangeCallback = options.parameterChanged;
      var initialized;
      if ($selectAll.length > 0) {
        $selectAll.text(stringResources.stringResources[$selectAll.text()]);
        $selectAll = new kendo.ui.Button($selectAll, {
          size: "small",
          click: (e) => {
            e.preventDefault();
            if (!enabled) {
              return;
            }
            setSelectedItems(parameter.availableValues.map((av) => {
              return av.value;
            }));
          }
        });
      }
      if ($selectNone.length > 0) {
        $selectNone.text(stringResources.stringResources[$selectNone.text()]);
        $selectNone = new kendo.ui.Button($selectNone, {
          size: "small",
          click: (e) => {
            e.preventDefault();
            if (!enabled)
              return;
            setSelectedItems([]);
          }
        });
      }
      function onSelectionChanged(selection) {
        if (initialized) {
          applyAriaSelected(selection);
          notifyParameterChanged(selection);
        }
      }
      function applyAriaSelected(selection) {
        var children = $list.find(".trv-listviewitem");
        Array.from(children).forEach((item) => {
          var $item = $(item);
          var isSelected = selection.filter($item).length > 0;
          $item.attr("aria-selected", isSelected);
        });
      }
      function notifyParameterChanged(selection) {
        var availableValues = parameter.availableValues;
        var values = $.map(selection, (item) => {
          return availableValues[$(item).index()].value;
        });
        clearPendingChange();
        var immediateUpdate = !parameter.autoRefresh && !parameter.childParameters;
        updateTimeout = window.setTimeout(() => {
          if (!utils.areEqualArrays(parameter.value, values)) {
            valueChangeCallback(parameter, values);
          }
          updateTimeout = null;
        }, immediateUpdate ? 0 : 1e3);
      }
      function clearPendingChange() {
        if (updateTimeout) {
          window.clearTimeout(updateTimeout);
        }
      }
      function getSelectedItems() {
        return $(listView.element).find(".k-selected");
      }
      function onItemClick(e) {
        if (!enabled)
          return;
        var clickedItem = $(e.target);
        var selectedItems = listView.select();
        if (clickedItem.hasClass("k-selected")) {
          selectedItems.splice($.inArray(clickedItem[0], selectedItems), 1);
        } else {
          selectedItems.push(clickedItem);
        }
        listView.clearSelection();
        listView.select(selectedItems);
        listView.trigger("change");
      }
      function onChange(e) {
        onSelectionChanged(getSelectedItems());
      }
      function onKeydown(event) {
        if (!enabled)
          return;
        if (event.which !== 32) {
          return;
        }
        var focused = listView.element.find(".k-focus");
        if (focused.length > 0) {
          focused.toggleClass("k-selected");
          onSelectionChanged(getSelectedItems());
          event.preventDefault();
        }
      }
      function init($list2) {
        setEditorTabIndex($list2);
        setSelectedItems(parameter.value);
        listView.element.off().on("touch click", ".trv-listviewitem", onItemClick);
        listView.element.on("keydown", onKeydown);
        initialized = true;
      }
      function clear() {
        initialized = false;
        if (listView) {
          listView.element.off("touch click", ".trv-listviewitem", onItemClick);
          listView.element.off("keydown", onKeydown);
        }
      }
      function setSelectedItems(items) {
        setSelectedItemsCore(items);
        onSelectionChanged(getSelectedItems());
      }
      function setSelectedItemsCore(items) {
        if (!Array.isArray(items)) {
          items = [items];
        }
        var children = $list.find(".trv-listviewitem");
        $.each(parameter.availableValues, (i, av) => {
          var selected = false;
          $.each(items, (j, v) => {
            var availableValue = av.value;
            if (v instanceof Date) {
              availableValue = RCV.parseToLocalDate(av.value);
            }
            selected = utils.areEqual(v, availableValue);
            return !selected;
          });
          selectItem($(children[i]), selected);
        });
      }
      return {
        beginEdit: (param) => {
          clear();
          parameter = param;
          try {
            listView = $list.kendoListView({
              template: kendo.template('<div class="trv-listviewitem" style="cursor: pointer">${name}</div>'),
              dataSource: { data: parameter.availableValues },
              selectable: "MULTIPLE",
              navigatable: navigatableEnabledForList(options.enableAccessibility),
              change: onChange
            }).data("kendoListView");
          } catch (e) {
            console.error("Instantiation of Kendo ListView as MultiSelect parameter editor threw an exception", e);
            throw e;
          }
          init($list);
        },
        enable: (enable) => {
          enabled = enable;
          enableItem($list, enabled);
        },
        clearPendingChange,
        addAccessibility: (param) => {
          var info = utils.stringFormat(stringResources.stringResources.ariaLabelParameterInfo, [param.availableValues.length]);
          addAccessibilityAttributes($list, stringResources.stringResources.ariaLabelMultiSelect, param.text, info, param.Error);
          $list.attr("aria-multiselectable", "true");
          var items = $list.find(".trv-listviewitem");
          Array.from(items).forEach((item) => {
            $(item).attr("aria-label", item.innerText);
          });
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($list, param.Error);
        },
        destroy: () => {
          listView.destroy();
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.MultiSelectCombo,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var enabled = true;
      var selector = ".trv-combo";
      var template = "trv-parameter-editor-available-values-multiselect-combo";
      var valueChangeCallback = options.parameterChanged;
      var $editorDom;
      var $selectNone;
      var $selectAll;
      var editor;
      var updateTimeout;
      var popUpIsClosed = true;
      var parameter;
      $placeholder.html(options.templates[template]);
      $editorDom = $placeholder.find(selector);
      $selectAll = $placeholder.find(".trv-select-all");
      if ($selectAll.length > 0) {
        $selectAll.text(stringResources.stringResources[$selectAll.text()]);
        $selectAll = new kendo.ui.Button($selectAll, {
          size: "small",
          click: (e) => {
            e.preventDefault();
            if (!enabled) {
              return;
            }
            var values = $.map(parameter.availableValues, (dataItem) => {
              return dataItem.value;
            });
            editor.value(values);
            editor.trigger("change");
          }
        });
      }
      $selectNone = $placeholder.find(".trv-select-none");
      if ($selectNone.length > 0) {
        $selectNone.text(stringResources.stringResources[$selectNone.text()]);
        $selectNone = new kendo.ui.Button($selectNone, {
          size: "small",
          click: (e) => {
            e.preventDefault();
            editor.value([]);
            editor.trigger("change");
          }
        });
      }
      function onSelectionChanged(selection) {
        notifyParameterChanged(selection);
      }
      function notifyParameterChanged(values) {
        clearPendingChange();
        var immediateUpdate = !parameter.autoRefresh && !parameter.childParameters;
        updateTimeout = window.setTimeout(() => {
          if (!utils.areEqualArrays(parameter.value, values)) {
            valueChangeCallback(parameter, values);
          }
          updateTimeout = null;
        }, immediateUpdate ? 0 : 1e3);
      }
      function clearPendingChange() {
        if (updateTimeout) {
          window.clearTimeout(updateTimeout);
        }
      }
      function getSelectedItems() {
        return editor.value();
      }
      function onChange() {
        if (popUpIsClosed) {
          onSelectionChanged(getSelectedItems());
        }
      }
      function init($editorDom2) {
        setEditorTabIndex($editorDom2);
        editor.bind("change", onChange);
      }
      function reset() {
        if (editor) {
          editor.unbind("change", onChange);
        }
      }
      return {
        beginEdit: (param) => {
          reset();
          parameter = param;
          try {
            editor = $editorDom.kendoMultiSelect({
              itemTemplate: '<div class="trv-editoritem">${name}</div>',
              dataSource: parameter.availableValues,
              dataTextField: "name",
              dataValueField: "value",
              value: parameter.value,
              filter: "contains",
              autoClose: false,
              open: () => {
                popUpIsClosed = false;
              },
              close: (e) => {
                popUpIsClosed = true;
                onChange();
              },
              autoWidth: true,
              clearButton: false
            }).data("kendoMultiSelect");
          } catch (e) {
            console.error("Instantiation of Kendo MultiSelect as MultiSelectCombo parameter editor threw an exception", e);
            throw e;
          }
          init($editorDom);
        },
        enable: (enable) => {
          enabled = enable;
          editor.enable(enable);
        },
        clearPendingChange,
        addAccessibility: (param) => {
          var $accessibilityDom = editor.input;
          var info = utils.stringFormat(stringResources.stringResources.ariaLabelParameterInfo, [param.availableValues.length]);
          addAccessibilityAttributes($accessibilityDom, stringResources.stringResources.ariaLabelMultiSelect, param.text, info, param.Error);
          var items = editor.items();
          Array.from(items).forEach((item) => {
            $(item).attr("aria-label", item.innerText);
          });
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($editorDom, param.Error);
        },
        destroy: () => {
          editor.destroy();
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.SingleSelect,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var enabled = true;
      $placeholder.html(options.templates["trv-parameter-editor-available-values"]);
      var $list = $placeholder.find(".trv-list");
      var $selectNone = $placeholder.find(".trv-select-none");
      var listView;
      var parameter;
      var valueChangeCallback = options.parameterChanged;
      if ($selectNone.length > 0) {
        $selectNone.text(stringResources.stringResources[$selectNone.text()]);
        $selectNone = new kendo.ui.Button($selectNone, {
          size: "small",
          click: (e) => {
            e.preventDefault();
            listView.clearSelection();
            listView.trigger("change");
          }
        });
      }
      function onSelectionChanged(selection) {
        notifyParameterChanged(selection);
      }
      function notifyParameterChanged(selection) {
        var availableValues = parameter.availableValues;
        var values = $.map(selection, (item) => {
          return availableValues[$(item).index()].value;
        });
        if (Array.isArray(values)) {
          values = values[0];
        }
        valueChangeCallback(parameter, values);
      }
      function getSelectedItems() {
        return listView.select();
      }
      function onChange() {
        onSelectionChanged(getSelectedItems());
      }
      function init($list2) {
        setEditorTabIndex($list2);
        setSelectedItems(parameter.value);
        listView.bind("change", onChange);
      }
      function reset() {
        if (listView) {
          listView.unbind("change", onChange);
        }
      }
      function setSelectedItems(value) {
        var items = $list.find(".trv-listviewitem");
        $.each(parameter.availableValues, (i, av) => {
          var availableValue = av.value;
          if (value instanceof Date) {
            availableValue = RCV.parseToLocalDate(av.value);
          }
          if (utils.areEqual(value, availableValue)) {
            listView.select(items[i]);
            return false;
          }
          return true;
        });
      }
      return {
        beginEdit: (param) => {
          reset();
          parameter = param;
          try {
            listView = $list.kendoListView({
              template: '<div class="trv-listviewitem">${name}</div>',
              dataSource: { data: parameter.availableValues },
              selectable: true,
              navigatable: navigatableEnabledForList(options.enableAccessibility)
            }).data("kendoListView");
          } catch (e) {
            console.error("Instantiation of Kendo ListView as SingleSelect parameter editor threw an exception", e);
            throw e;
          }
          init($list);
        },
        enable: (enable) => {
          enabled = enable;
          enableItem($list, enabled);
          if (enabled) {
            listView.bind("change", onChange);
            $list.addClass("k-selectable");
          } else {
            listView.unbind("change", onChange);
            $list.removeClass("k-selectable");
          }
        },
        addAccessibility: (param) => {
          var info = utils.stringFormat(stringResources.stringResources.ariaLabelParameterInfo, [param.availableValues.length]);
          addAccessibilityAttributes($list, stringResources.stringResources.ariaLabelSingleValue, param.text, info, param.Error);
          var items = $list.find(".trv-listviewitem");
          Array.from(items).forEach((item) => {
            $(item).attr("aria-label", item.innerText);
          });
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($list, param.Error);
        },
        destroy: () => {
          listView.destroy();
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.SingleSelectCombo,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var selector = ".trv-combo";
      var template = "trv-parameter-editor-available-values-combo";
      var valueChangeCallback = options.parameterChanged;
      var $editorDom;
      var $selectNone;
      var editor;
      var parameter;
      $placeholder.html(options.templates[template]);
      $editorDom = $placeholder.find(selector);
      $selectNone = $placeholder.find(".trv-select-none");
      if ($selectNone.length > 0) {
        $selectNone.text(stringResources.stringResources[$selectNone.text()]);
        $selectNone = new kendo.ui.Button($selectNone, {
          size: "small",
          click: (e) => {
            e.preventDefault();
            editor.value("");
            editor.trigger("change");
          }
        });
      }
      function onSelectionChanged(selection, value) {
        notifyParameterChanged(selection, value);
      }
      function notifyParameterChanged(selection, value) {
        var values = value || "";
        var availableValues;
        if (!value && selection >= 0) {
          availableValues = parameter.availableValues;
          values = availableValues[selection].value;
        }
        valueChangeCallback(parameter, values);
      }
      function getSelectedItems() {
        return editor.select();
      }
      function onChange(event) {
        onSelectionChanged(getSelectedItems(), event.sender.value());
      }
      function init($editorDom2) {
        setEditorTabIndex($editorDom2);
        editor.bind("change", onChange);
      }
      function reset() {
        if (editor) {
          editor.unbind("change", onChange);
        }
      }
      return {
        beginEdit: (param) => {
          reset();
          parameter = param;
          try {
            editor = $editorDom.kendoComboBox({
              template: '<div class="trv-editoritem">${name}</div>',
              dataSource: parameter.availableValues,
              dataTextField: "name",
              dataValueField: "value",
              value: parameter.value,
              filter: "contains",
              suggest: true,
              clearButton: false
            }).data("kendoComboBox");
          } catch (e) {
            console.error("Instantiation of Kendo ComboBox as SingleSelectCombo parameter editor threw an exception", e);
            throw e;
          }
          init($editorDom);
        },
        enable: (enable) => {
          editor.enable(enable);
        },
        addAccessibility: (param) => {
          var $accessibilityDom = editor.input;
          var info = utils.stringFormat(stringResources.stringResources.ariaLabelParameterInfo, [param.availableValues.length]);
          addAccessibilityAttributes($accessibilityDom, stringResources.stringResources.ariaLabelSingleValue, param.text, info, param.Error);
          var items = editor.items();
          Array.from(items).forEach((item) => {
            $(item).attr("aria-label", item.innerText);
          });
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($editorDom, param.Error);
        },
        destroy: () => {
          editor.destroy();
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.MultiValue,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var parameter;
      $placeholder.html(options.templates["trv-parameter-editor-multivalue"]);
      var $textArea = $placeholder.find("textarea").on("change", (event) => {
        if (options.parameterChanged) {
          options.parameterChanged(parameter, multivalueUtils.parseValues(event.currentTarget.value));
        }
      });
      function setValue(value) {
        parameter.value = value;
        $textArea.val(multivalueUtils.formatValue(value));
      }
      return {
        beginEdit: (param) => {
          parameter = param;
          setValue(param.value);
          setEditorTabIndex($textArea);
        },
        enable: (enable) => {
          enableItem($textArea, enable);
          $textArea.prop("disabled", !enable);
        },
        addAccessibility: (param) => {
          addAccessibilityAttributes($textArea, stringResources.stringResources.ariaLabelMultiValue, param.text, null, param.Error);
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($textArea, param.Error);
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.DateTime,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var parameter;
      $placeholder.html(options.templates["trv-parameter-editor-datetime"]);
      try {
        var $dateTimePicker = $placeholder.find("input[type=datetime]").kendoDatePicker({
          change: (event) => {
            var handler = options.parameterChanged;
            if (handler) {
              var dtv = event.sender.value();
              if (null !== dtv) {
                dtv = utils.adjustTimezone(dtv);
              }
              handler(parameter, dtv);
            }
          }
        });
        var dateTimePicker = $dateTimePicker.data("kendoDatePicker");
      } catch (e) {
        console.error("Instantiation of Kendo DatePicker as DateTime parameter editor threw an exception", e);
        throw e;
      }
      function setValue(value) {
        parameter.value = value;
        var dt = null;
        try {
          if (value) {
            dt = utils.unadjustTimezone(value);
          }
        } catch (e) {
          dt = null;
        }
        dateTimePicker.value(dt);
      }
      return {
        beginEdit: (param) => {
          parameter = param;
          setValue(param.value);
          setEditorTabIndex($dateTimePicker);
        },
        enable: (enable) => {
          dateTimePicker.enable(enable);
          enableItem($dateTimePicker, enable);
        },
        addAccessibility: (param) => {
          addAccessibilityAttributes($dateTimePicker, stringResources.stringResources.ariaLabelParameterDateTime, param.text, null, param.Error);
          $dateTimePicker.attr("aria-live", "assertive");
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($dateTimePicker, param.Error);
        },
        destroy: () => {
          dateTimePicker.destroy();
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.String,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var parameter;
      $placeholder.html(options.templates["trv-parameter-editor-text"]);
      var $input = $placeholder.find('input[type="text"]').change(() => {
        if (options.parameterChanged) {
          options.parameterChanged(parameter, $input.val());
        }
      });
      function setValue(value) {
        parameter.value = value;
        $input.val(value);
      }
      return {
        beginEdit: (param) => {
          parameter = param;
          setValue(param.value);
          setEditorTabIndex($input);
        },
        enable: (enabled) => {
          $input.prop("disabled", !enabled);
          enableItem($input, enabled);
        },
        addAccessibility: (param) => {
          addAccessibilityAttributes($input, stringResources.stringResources.ariaLabelParameterString, param.text, null, param.Error);
          $input.attr("aria-live", "assertive");
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($input, param.Error);
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.Number,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var parameter;
      var inputBehavior;
      $placeholder.html(options.templates["trv-parameter-editor-number"]);
      var $input = $placeholder.find("input[type=number]").on("change", () => {
        if (options.parameterChanged) {
          options.parameterChanged(parameter, $input.val());
        }
      });
      return {
        beginEdit: (param) => {
          if (inputBehavior) {
            inputBehavior.dispose();
          }
          parameter = param;
          $input.val(parameter.value);
          if (parameter.type === enums.ParameterTypes.INTEGER) {
            inputBehavior = integerInputBehavior($input);
          } else {
            inputBehavior = floatInputBehavior($input);
          }
          setEditorTabIndex($input);
        },
        enable: (enable) => {
          $input.prop("disabled", !enable);
          enableItem($input, enable);
        },
        addAccessibility: (param) => {
          addAccessibilityAttributes($input, stringResources.stringResources.ariaLabelParameterNumerical, param.text, null, param.Error);
          $input.attr("aria-live", "assertive");
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($input, param.Error);
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.Boolean,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      var parameter;
      $placeholder.html(options.templates["trv-parameter-editor-boolean"]);
      var $input = $placeholder.find("input[type=checkbox]").on("change", (event) => {
        if (options.parameterChanged) {
          options.parameterChanged(parameter, event.currentTarget.checked);
        }
      });
      function setValue(value) {
        parameter.value = value;
        $input[0].checked = value === true;
      }
      return {
        beginEdit: (param) => {
          parameter = param;
          setValue(param.value);
          setEditorTabIndex($input);
        },
        enable: (enable) => {
          enableItem($input, enable);
          $input.attr("disabled", !enable);
        },
        addAccessibility: (param) => {
          addAccessibilityAttributes($input, stringResources.stringResources.ariaLabelParameterBoolean, param.text, null, param.Error);
          $input.attr("aria-live", "assertive");
        },
        setAccessibilityErrorState: (param) => {
          setAccessibilityErrorAttributes($input, param.Error);
        }
      };
    }
  },
  {
    match: parameterEditorsMatch.Default,
    createEditor: (placeholder, options) => {
      var $placeholder = $(placeholder);
      $placeholder.html('<div class="trv-parameter-editor-generic"></div>');
      return {
        beginEdit: (parameter) => {
          $placeholder.find(".trv-parameter-editor-generic").text(parameter.Error ? "(error)" : parameter.value);
        },
        enable: (enable) => {
        }
      };
    }
  }
];

exports.ParameterEditors = ParameterEditors;
exports.parameterEditorsMatch = parameterEditorsMatch;
