<template>
  <div
    :class="[
      componentClass,
      getComponentFormatTypeClass,
      {
        'c-focus': inputFocus,
        'c-readonly': readonly,
        'c-disabled': isDisabled,
        'c-autofocus': autofocus,
        'c-lookuponly': lookupOnly,
        'c-lbl-suffix': suffixLabel != null
      },
      componentErrorClass,
      componentInfoClass,
      lookupPlacement,
      componentWarningClass,
      (isRequired && 'c-required')
    ]"
    @focusin="componentFocusin"
    @focusout="componentFocusout"
  >
    <label v-if="showToggleIsActive" class="toggle">
      <input type="checkbox" @input="toggleIsActive" :checked="isActive" />
      <span class="switch"></span>
    </label>
    <div>
      <label
        class="c-lbl label"
        v-if="showLabel && (isLabel || hasSlot('label')) && labelLocation == 'left'"
        v-bind:style="{ width: getLabelWidth }"
        :for="componentId"
        >
        <slot name="label">{{ label }}</slot>
      </label>
      <div class="edit">
        <input v-if="!isMultiLine"
          :id="componentId"
          :class="['input', getFormatTypeClass]"
          :value="formatValue(dataFieldValue, getFormatType)"
          :placeholder="getPlaceholderValue"
          :type="getType"
          :name="name"
          :disabled="isDisabled"
          :readonly="isInputReadonly"
          :indeterminate.prop="isIndeterminate"
          :checked="isCheckedValue"
          @[inputEvent]="onValueInput"
          v-on:keydown="onKeyDown"
          v-on:keyup="onKeyUp"
          v-on:focus="onFocus"
          v-on:blur="onBlur"
          tabindex="0"
          ref="input"
          :autocomplete="autocomplete"
          :autofocus="autofocus"
        />
        <textarea v-if="isMultiLine"
          :class="['input', getFormatTypeClass]"
          :id="componentId"
          :value="this.dataFieldValue"
          :placeholder="getPlaceholderValue"
          :type="getType"
          :name="name"
          :disabled="isDisabled"
          :readonly="isInputReadonly"
          @[inputEvent]="onValueInput"
          v-on:keydown="onKeyDown"
          v-on:keyup="onKeyUp"
          v-on:focus="onFocus"
          v-on:blur="onBlur"
          tabindex="0"
          ref="input"
          :autocomplete="autocomplete"
          :autofocus="autofocus"
        />
        <label
          v-if="getType == 'checkbox'"
          :for="componentId"
          class="c-checkbox"
        ></label>
        <i
          class="btn-clear"
          v-if="hasClear"
          tabindex="-1"
          ref="btnClear"
          v-on:click="clearDataFieldValue"
          >&#xE907;</i
        >
        <i
          class="btn-refresh"
          v-if="hasRefresh"
          tabindex="-1"
          ref="btnRefresh"
          v-on:click="refreshData"
          >&#xE911;</i
        >
        <button
          v-if="getShowTogglePasswordVisibility"
          :class="getType == 'password' ? 'c-btn-show-pwd' : 'c-btn-hide-pwd'"
          v-on:click="togglePasswordVisibility"
          type="button"
          tabindex="-1"
        >
        </button>
        <i
          class="btn-dropdown"
          v-if="hasLookup && !lookupVisible"
          tabindex="-1"
          v-on:click="displayLookup"
          >&#xE904;</i
        >
        <i
          class="btn-dropup"
          v-if="hasLookup && showDropDown && lookupVisible"
          tabindex="-1"
          v-on:click="hideLookup"
          >&#xE904;</i
        >
        <i
          class="c-btn-calendar"
          v-if="hasCalendar && !calendarVisible"
          tabindex="-1"
          v-on:click="displayCalendar"
        />
        <i
          class="c-btn-calendar"
          v-if="hasCalendar && calendarVisible"
          tabindex="-1"
          v-on:click="hideCalendar"
        />
      </div>
      <label
        class="c-lbl-suffix"
        v-if="dataFieldIdent4SuffixLabel != null"
        v-bind:style="{ width: getSuffixLabelWidth }"
        :for="componentId"
        >{{ suffixLabel }}</label>
      <label
        class="label"
        v-if="showLabel && (isLabel || hasSlot('label')) && labelLocation == 'right'"
        v-bind:style="{ width: getLabelWidth }"
        :for="componentId"
        >
        <slot name="label">{{ label }}</slot>
      </label>
      <div
        class="c-whereList"
        v-if="hasWhereList"
      >
        <div
          class="c-whereList-item"
          v-for="rowWhere in whereList"
          :key="rowWhere[dataFieldIdent]"
        >
          <div class="c-whereList-item-label">
            {{ rowWhere[dataFieldIdent] }}
          </div>
          <i
            class="c-whereList-item-btn-close"
            v-on:click="
              deleteWhereListItem(rowWhere)
            "
            >&#xE907;</i
          >
        </div>
      </div>
    </div>
    <div
      class="c-lookup"
      v-if="hasLookup"
      :class="{ 'c-list-visible': lookupVisible , 'c-lookup-focus': lookupFocus}"
      :style="{
        width: getLookupListWidth,
        height: lookupHeight,
        '--c-list-width': getLookupListWidth != 'null' && getLookupListWidth != null & getLookupListWidth != '' ? getLookupListWidth : null,
        '--c-list-max-height': lookupHeight,
        '--c-el-offset-height': elOffsetHeight,
        '--c-el-client-height': elClientHeight
      }"
      ref="lookupCont"
    >
      <c-lookup
        :appWindowIdent="appWindowIdentLookup"
        v-if="hasLookup && lookupVisible"
        tabindex="1"
        ref="lookup"
      ></c-lookup>
    </div>
    <div class="c-calendar" v-if="hasCalendar && calendarVisible">
      <div class="c-header">
        <div class="c-btn-prev" tabindex="-1" v-on:click="monthLeft" />
        <div class="c-m-y">{{ month }} {{ year }}</div>
        <div class="c-btn-next" tabindex="-1" v-on:click="monthRight" />
      </div>
      <table cellspacing="0">
        <colgroup>
          <col v-for="n in 8" :key="n" />
        </colgroup>
        <thead>
          <tr>
            <td></td>
            <td v-for="wd in 7" :key="wd">
              {{ weekdays[wd - 1] }}
            </td>
          </tr>
        </thead>
        <tbody>
          <tr v-for="r in 6" :key="r">
            <td class="c-wk">{{ getWeekNumber(r, 1) }}</td>
            <td
              v-for="c in 7"
              :key="c"
              :class="[
                'c-day',
                getCalendarDayClass(r, c),
                getCalendarDayOutOfRangeClass(r, c),
                {
                  'c-weekend' : c === 6 || c === 7
                }
              ]"
              tabindex="3"
              v-on:click="setDate(getDate(r, c))"
            >
              {{ getDay(r, c) }}
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div
      v-if="infoMessageText != null && infoMessageText != ''"
      class="c-info-txt"
    >{{ infoMessageText }}</div>
    <div
      v-if="warningMessageText != null && warningMessageText != ''"
      class="c-warning-txt"
    >{{ warningMessageText }}</div>
    <div
      v-if="errorMessageText != null && errorMessageText != ''"
      class="c-error-txt"
    >{{ errorMessageText }}</div>
  </div>
</template>

<script>
const props = {
  lookupListWidth: {
    type: String,
    default: null
  },
  showLabel: {
    type: Boolean,
    default: true
  },
  labelLocation: {
    type: String,
    default: 'left'
  },
  labelWidth: {
    type: String,
    default: '150px'
  },
  dataFieldIdent4SuffixLabel: {
    type: String,
    default: null
  },
  suffixLabelWidth: {
    type: String
  },
  formatType: {
    type: String,
    default: 'none'
  },
  name: {
    type: String,
    default: null
  },
  dataFieldIdent: {
    type: String,
    default: null
  },
  valueChecked: {
    type: Number,
    default: 1
  },
  valueUnChecked: {
    type: Number,
    default: 0
  },
  indeterminate: {
    type: Boolean,
    default: false
  },
  showLookup: {
    type: Boolean,
    default: true
  },
  showRefresh: {
    type: Boolean,
    default: false
  },
  showDropDown: {
    type: Boolean,
    default: true
  },
  showClear: {
    type: Boolean,
    default: true
  },
  showTogglePasswordVisibility: {
    type: Boolean,
    default: true
  },
  type: {
    type: String,
    default: null
  },
  isRequired: {
    type: Boolean,
    default: false
  },
  isMultiLine: {
    type: Boolean,
    default: false
  },
  autocomplete:{
    type: String,
    default: 'off'
  },
  disabled:{
    type: Boolean,
    default: false
  },
  readonly: {
    type: Boolean,
    default: false
  },
  autofocus: {
    type: Boolean,
    default: false
  },  
  oncfTrigger: {
    type: String,
    default: 'timeout'
  },
  lookupTimeout: {
    type: Number,
    default: 650
  },
  oncfTimeout: {
    type: Number,
    default: 400
  },
  lookupMinHeight: {
    type: Number,
    default: 200
  },
  selectAllTextOnFocus: {
    type: Boolean,
    default: false
  },
  lookupOpenKind: {
    type: String,
    default: null
  },
  showToggleIsActive: {
    type: Boolean,
    default: false
  },
  // Callback used to validate/modify value when modified
  // Return null to signify failed validation, cancelling change
  // Return value to be assigned
  onValueChange: {
    type: Function,
    default: null
  },
  // If set, don't update the store on input, only on change
  // Prevents cases of formatting changes in the middle of typing
  lazy: Boolean,
  clearErrorOnValueInput: Boolean,
  // Acts like readonly, but allows lookups and clearing
  // Intended for cases where the value can be edited, but cannot
  // be written directly, only via things like lookups
  lookupOnly: Boolean,

  //Array of keys codes, keys and key modifiers to block (prevent default behaviour) on key down event
  keyDownToBlock: Array
}

import base from './c-base'
import controlUtils from '../classes/controlUtils'
import stringUtils from '../classes/stringUtils'
import dataSetUtils from '../classes/dataSetUtils'
import { mapActions, mapGetters } from 'vuex'
import moment from 'moment'

export default {
  extends: base,
  data: function() {
    return {
      componentClass: 'c-edit',
      focusClass: null,
      lookupHeight: null,
      lookupPlacement: '',
      calendarVisible: false,
      date: null,
      months: null,
      weekdays: null,
      inputFocus: false, 
      lookupTimer: null,
      lookupFocus: false,
      componentFocus: false,
      componentFocusTimer: null,
      componentFocusTimeout: 50,
      inputTypeInitial: null,
      inputType: this.type,
      elClientHeight: null,
      elOffsetHeight: null
    }
  },
  props,
  computed: {
    ...mapGetters('csAppWindowsUtils', [
      'getDataSetWhereList',
      'getDataSetRowsFieldValue'
    ]),
    isInputReadonly: function() {
      return this.readonly || this.lookupOnly
    },
    hasClear: function() {
      return (
        (this.getType == null || this.getType == 'text')
        && this.showClear === true
        && (this.dataFieldValue !== null || (this.whereList && this.whereList.length > 0))
        && this.readonly == false
        && this.isDisabled == false
      )
    },
    hasRefresh: function() {
      return (
        (this.getType == null || this.getType == 'text') &&
        this.showRefresh === true
      )
    },
    lookupDef: function() {
      return this.dataSet && this.showLookup && this.dataSet.lookupDefs
        ? this.dataSet.lookupDefs.find(
            item => item.dataFieldIdent === this.dataFieldIdent
          ) || null
        : null
    },
    lookupDataSetIdent: function(){
      return this.lookupDef && this.lookupDef.lookupSettersRefresh ? 
        this.lookupDef.lookupSettersRefresh[0].dataSetIdentFrom : 
        (
          this.lookupDef && this.lookupDef.lookupGettersRefresh ?
          this.lookupDef.lookupGettersRefresh[0].dataSetIdentTo : 
          null
        )
    },
    lookupAppWindowIdent: function(){
      return this.lookupDef && this.lookupDef.lookupSettersRefresh ? 
        this.lookupDef.lookupSettersRefresh[0].appWindowIdentFrom : 
        (
          this.lookupDef && this.lookupDef.lookupGettersRefresh ?
          this.lookupDef.lookupGettersRefresh[0].appWindowIdentTo : 
          null
        )
    },
    hasCalendar: function() {
      return this.getFormatType == 'calendar' || this.getFormatType == 'date'
    },
    hasLookup: function() {
      //return this.showLookup && this.lookupDef !== null ? true : false
      return (this.showLookup
        && this.lookupDef !== null
        && this.readonly == false
        && this.isDisabled == false
      )
    },
    hasWhereList: function() {
      return (this.showLookup
        && this.lookupDef !== null
        && this.whereList != null
        && this.whereList.length > 0
      )
    },
    appWindowIdentLookup: function() {
      return this.lookupDef !== null
        ? this.lookupDef.appWindowIdentLookup
        : null
    },
    appWindowIdentLookupDef: function() {
      return this.lookupDef !== null
        ? this.lookupDef.appWindowIdentLookupDef
        : null
    },
    lookupVisible: function() {
      if (this.sourceKind === 'rows')
        return this.lookupDef && this.lookupDef.lookupVisible && this.contextRow && this.contextRow._lookupVisible[this.lookupDef.appWindowIdentLookup]
      return this.lookupDef ? this.lookupDef.lookupVisible : false
    },
    label: function() {
      let result
      if (this.sourceKind == 'where') {
        result = this.labelLocation === 'none' ||
          this.whereFieldsIdentsDataField === null ||
          this.whereFieldsIdentsDataField === undefined
          ? null
          : this.whereFieldsIdentsDataField.dataFieldLabTranslatedDesc
      } else if (this.sourceKind == 'rows') {
        result = this.labelLocation === 'none' ||
          this.fieldsIdentsDataField === null ||
          this.fieldsIdentsDataField === undefined
          ? null
          : this.fieldsIdentsDataField.dataFieldLabTranslatedDesc
      }
      return result
    },
    suffixLabel: function() {
      if (this.dataFieldIdent4SuffixLabel == null) return
      return this.getDataSetRowsFieldValue(
          this.dataSet,
          this.dataFieldIdent4SuffixLabel,
          this.contextRow
        )
    },
    getPlaceholderValue: function() {
      let result
      if (this.sourceKind == 'where') {
        result = this.whereFieldsIdentsDataField?.dataFieldWatermarkTranslatedDesc
      } else if (this.sourceKind == 'rows') {
        result = this.fieldsIdentsDataField?.dataFieldWatermarkTranslatedDesc
      }
      return result
    },
    isLazy: function() {
      return this.lazy || controlUtils.checkFormatType(this.getFormatType).type == 'number'
    },
    inputEvent: function() {
      return this.isLazy ? "change" : "input"
    },
    isLabel: function() {
      return this.label !== null && this.label !== undefined
    },
    isIndeterminate: function() {
      if (!this.indeterminate) {
        return false
      }
      if (
        this.dataFieldValue != this.valueChecked &&
        this.dataFieldValue != this.valueUnChecked
      ) {
        return true
      } else {
        return false
      }
    },
    isDisabled: function() {
      if (this.disabled)
        return true
      if ((this.state === 0 || this.state === 2) && this.sourceKind == 'rows')
        return true
      if (this.oprState == dataSetUtils.oprState.inProgress)
        return true
      if (this.sourceKind == 'where')
        return !this.whereFieldsIdentsDataField?.isActive
      if(this.getFormatType == "boolean" && this.readonly == true)
        return true
      return false
    },
    isCheckedType: function() {
      return this.getType == 'checkbox'
    },
    isCheckedValue: function() {
      if (!this.isCheckedType) {
        return null
      }
      return this.dataFieldValue == this.valueChecked
    },
    getFormatType: function() {
      if (this.formatType !== 'none') return this.formatType
      let formatType
      if (this.sourceKind === 'rows') {
        formatType = this.fieldsIdentsDataField?.formatType
      }
      if (this.sourceKind === 'where') {
        formatType = this.whereFieldsIdentsDataField?.formatType
      }
      return formatType || 'none'
    },
    getType: function() {
      if (this.inputType == null) {
        let formatType = controlUtils.checkFormatType(this.getFormatType)
        if (formatType.type == 'number') {
          return 'text'
        }
        if (formatType.type == 'date') {
          return null
        }
        return formatType.type
      }
      return this.inputType
    },
    getComponentFormatTypeClass: function() {
      //return this.getType != null ? 'c-' + this.getType : null
      let type = this.inputType
      if (type == null) {
        let formatType = controlUtils.checkFormatType(this.getFormatType)
        type = formatType.type
      }
      return type != null ? 'c-' + type : null
    },
    getFormatTypeClass: function() {
      return controlUtils.checkFormatType(this.getFormatType).formatTypeClass
    },
    getLabelWidth: function() {
      return this.labelWidth.includes('px')
        ? this.labelWidth
        : this.labelWidth + 'px'
    },
    getSuffixLabelWidth: function() {
      return this.suffixLabelWidth != null ? (this.suffixLabelWidth.includes('px') ? this.suffixLabelWidth : this.suffixLabelWidth + 'px') : null
    },
    getLookupListWidth: function() {
      return (
        this.lookupListWidth +
        (!isNaN(this.lookupListWidth - parseFloat(this.lookupListWidth))
          ? 'px'
          : '')
      )
    },
    year: function() {
      let date = new Date(this.date)
      //return date.getUTCFullYear()
      return date.getFullYear()
    },
    month: function() {
      let date = new Date(this.date)
      // let month = date.getUTCMonth()
      let month = date.getMonth()
      return this.months[month]
    },
    whereList: function(){
      return this.getDataSetWhereList(this.dataSet, this.dataFieldIdent, this.sourceKind, this.contextRow)
    },
    getShowTogglePasswordVisibility: function() {
      return (this.inputTypeInitial == 'password' && this.showTogglePasswordVisibility)
    },
    isActive: function() {
      return this.sourceKind === 'where' ? this.whereFieldsIdentsDataField?.isActive : true
    }
  },
  methods: {
    ...mapActions('csAppWindowsUtils', [
      'addAppWindow',
      'refreshDataSetDependence',
      'setLookupDefVisible',
      'clearDataSetsFromSetters',
      'deleteDataSetWhereListsItem',
      'deleteDataSetWhereListItem',
      'clearLookupDataSetsSelection',
      "setDataSetPrevRow",
      "setDataSetNextRow",
      "setLookupDefSelection",
      "addLookupWindow",
      "setWhereFieldsIdentsDataFieldIsActive",
      "clearErrorField"
    ]),
    hasSlot: function(name) {
      return !!this.$slots[name]
    },
    componentFocusin: function(){
      clearTimeout(this.componentFocusTimer)
      this.componentFocus = true
    },
    componentFocusout: function(){
      this.componentFocusTimer = setTimeout(()=>{
        this.componentFocus = false
        if (this.lookupDef && this.lookupDef.closeKind === 'onLostFocus'){
          let payload = {
            appWindowIdent: this.appWindowIdent,
            dataSetIdent: this.dataSetIdent,
            dataFieldIdent: this.dataFieldIdent,
            lookupVisible: false,
            row: this.sourceKind === "rows" ? this.contextRow : undefined
          }
          this.setLookupDefVisible(payload)
        }
      }, this.componentFocusTimeout)
    },
    onValueInput: async function(evt) {
      this.clearErrorOnValueInput && this.clearErrorField(
          { 
            errorFields: this.errorFields,
            dataFieldIdent: this.dataFieldIdent 
          }
        )
      let dataFieldValue = evt.target.value === '' ? null : (evt.target.valueAsNumber || evt.target.value)
      if (this.isCheckedType) {
        dataFieldValue = evt.target.checked
          ? this.valueChecked
          : this.valueUnChecked
      }
      if (controlUtils.checkFormatType(this.getFormatType).type == 'number') {
        dataFieldValue = controlUtils.parseFloatWithLocales(dataFieldValue)
      }
      if (this.onValueChange) {
        dataFieldValue = this.onValueChange(dataFieldValue)
        if (dataFieldValue == null)
          return
      }
      if (dataFieldValue == null && this.hasLookup) {
        this.clearDataFieldValueInternall()
      }
      await this.setDataFieldValue({
        dataFieldIdent: this.dataFieldIdent,
        dataFieldValue: dataFieldValue,
        oncfTimeout: this.oncfTimeout,
        refreshLock: this.isCheckedType ? 0 : 1,
        onCFLock: stringUtils.isEqual(this.oncfTrigger, 'enter') ? 1 : 0
      })
      if (this.hasLookup) {
        this.setLookupVisible(true)
      }
    },
    setLookupVisible: function(visible, useTimeout = true) {
      clearTimeout(this.lookupTimer)
      let payload = null
      this.lookupFocus = false
      if (visible) {
        //this.setLookupHeight() //AKO - was replaced with function - setLookupHeightAndPlacement
        this.setLookupHeightAndPlacement()
        let payload = {
          appWindowIdent: this.appWindowIdentLookupDef,
          appWindowUniqIdent: this.appWindowIdentLookup,
          setActive: false,
          lookupDef: this.lookupDef,
          addRoutingData: false,
          path: null,
          row: this.sourceKind === "rows" ? this.contextRow : undefined,
          params: this.getAppWindowParams(this.appWindowIdent),
          showInManager: false
        }
        if (useTimeout)
          this.lookupTimer = setTimeout(() => {
            this.addLookupWindow(payload)
          }, this.lookupTimeout)
        else
          this.addLookupWindow(payload)
      }
      payload = {
        appWindowIdent: this.appWindowIdent,
        dataSetIdent: this.dataSetIdent,
        dataFieldIdent: this.dataFieldIdent,
        lookupVisible: visible,
        dataSet: this.dataSet,
        row: this.sourceKind === "rows" ? this.contextRow : undefined
      }
      this.setLookupDefVisible(payload)
    },
    onFocus: function() {
      this.inputFocus = true;
      if (this.hasLookup && this.lookupOpenKind === 'onFocus') this.setLookupVisible(true)
      if (this.getType !== 'checkbox' && this.selectAllTextOnFocus === true) {
        this.$refs.input.select(0, this.$refs.input.value.length);
      }
    },
    onBlur: function() {
      this.inputFocus = false
      this.lookupFocus = false
    },
    onKeyUp: async function(evt) {
      if (evt.key == 'Enter') {
        if (this.lookupFocus && this.hasLookup){
          this.lookupFocus = false
          await this.setLookupDefSelection({ appWindowIdent: this.lookupAppWindowIdent, dataSet: this.dataSet, row: this.contextRow })
          await this.setLookupVisible(false)
        }
        let dataFieldValue = evt.target.value === '' ? null : (evt.target.valueAsNumber || evt.target.value)
        if (this.isCheckedType) {
          dataFieldValue = evt.target.checked
            ? this.valueChecked
            : this.valueUnChecked
        }
        if (this.onValueChange) {
          dataFieldValue = this.onValueChange(dataFieldValue)
          if (dataFieldValue == null)
            return
        }
        this.setDataFieldValue({
          dataFieldIdent: this.dataFieldIdent, 
          dataFieldValue: dataFieldValue,
          onCFLock: stringUtils.isEqual(this.oncfTrigger, 'enter') ? 0 : 1
        })
      }
    },
    onKeyDown: async function(evt) {
      if (controlUtils.checkFormatType(this.getFormatType).type == 'number') {
        if (!(
          // delete, backspace, tab, escape, enter, comma and .
          [46, 8, 9, 27, 13, 188, 190].includes(evt.keyCode) ||
          // Ctrl/cmd+A, Ctrl/cmd+C, Ctrl/cmd+V, Ctrl/cmd+X
          ([65, 67, 86, 88].includes(evt.keyCode) && (evt.ctrlKey === true || evt.metaKey === true)) ||
          // home, end, left, right
          (evt.keyCode >= 35 && evt.keyCode <= 39)
        )) {
          // block any non-number
          if ((evt.shiftKey || (evt.keyCode < 48 || evt.keyCode > 57)) && (evt.keyCode < 96 || evt.keyCode > 105)) {
            evt.preventDefault();
          }
        }
        if (
          evt.target.selectionEnd - evt.target.selectionStart != 0 &&
          evt.target.selectionEnd - evt.target.selectionStart != evt.target.value.length &&
          (
            (
              evt.target.selectionDirection == 'forward' && 
              evt.target.selectionEnd <= evt.target.value.indexOf(',')
            ) ||
            (
              evt.target.selectionDirection == 'backward' && 
              evt.target.selectionStart >= evt.target.value.length - evt.target.value.indexOf(',')
            )
          )
        ) {
          evt.preventDefault()
        }
        if (
          evt.target.selectionEnd - evt.target.selectionStart === 0 &&
          [188, 190].includes(evt.keyCode) && 
          /[,.]/.test(evt.target.value)
        ) {
          const decimalSepPos = evt.target.value.indexOf(',') + 1
          evt.target.setSelectionRange(decimalSepPos, decimalSepPos)
          evt.preventDefault()
        }
      }
      if (this.keyDownToBlock != null) {
        for (var i = 0; i < this.keyDownToBlock.length; i++) {
          var keyDownToBlockItem = this.keyDownToBlock[i];
          if (
            (evt.altKey == keyDownToBlockItem.altKey && (keyDownToBlockItem.keyCode == null || evt.keyCode == keyDownToBlockItem.keyCode))
            || (evt.code != null && evt.code == keyDownToBlockItem.code)
            || (evt.ctrlKey == keyDownToBlockItem.ctrlKey && (keyDownToBlockItem.keyCode == null || evt.keyCode == keyDownToBlockItem.keyCode))
            || (evt.key != null && evt.key == keyDownToBlockItem.key)
            || (evt.keyCode != null && evt.keyCode == keyDownToBlockItem.keyCode && (keyDownToBlockItem.location == null || evt.location == keyDownToBlockItem.location))
            || (evt.shiftKey == keyDownToBlockItem.shiftKey && (keyDownToBlockItem.keyCode == null || evt.keyCode == keyDownToBlockItem.keyCode))
          ) {
            evt.preventDefault()
            return false
          }
        }
      }
      if (evt.key === 'Escape' && this.hasLookup) {
        await this.setLookupVisible(false)
        return
      }
      if (evt.key === 'ArrowDown' && this.hasLookup) {
        if (this.lookupVisible) {
          let lookupDataSet = this.getDataSet(this.lookupAppWindowIdent, this.lookupDataSetIdent)
          if (!lookupDataSet)
            return
          if (this.lookupFocus){
            await this.setDataSetNextRow(lookupDataSet)
          }
          else{
            this.lookupFocus = true
          }
          return
        }
        if (!this.lookupVisible) {
          await this.setLookupVisible(true, false)
          return
        }
      }
      if (evt.key === 'ArrowUp' && this.hasLookup) {
        if (this.lookupVisible) {
          let lookupDataSet = this.getDataSet(this.lookupAppWindowIdent, this.lookupDataSetIdent)
          if (!lookupDataSet)
            return
          if (this.lookupFocus){
            await this.setDataSetPrevRow(lookupDataSet)
          }
          return
        }
      }
    },
    refreshData: function() {
      if (this.sourceKind == 'where') this.refresh()
      else {
        this.refreshDataSetDependence({
          appWindowIdent: this.appWindowIdent,
          parentDataSetIdent: this.dataSetIdent,
          refreshAggregates: 1
        })
      }
    },
    displayLookup: function() {
      this.setLookupVisible(true, false)
      this.$refs.input.focus()
    },
    hideLookup: function() {
      this.setLookupVisible(false)
    },
    displayCalendar: function() {
      this.date = this.dataFieldValue || Date.now()
      this.calendarVisible = true
    },
    hideCalendar: function() {
      this.calendarVisible = false
    },
    deleteWhereListItem: function(item) {
      this.deleteDataSetWhereListItem({
        appWindowIdent: this.appWindowIdent,
        dataSetIdent: this.dataSetIdent,
        dataFieldIdent: this.dataFieldIdent,
        dataFieldValue: item[this.dataFieldIdent],
        _keyFieldsValues : item._keyFieldsValues,
        sourceKind: this.sourceKind,
        row: this.contextRow
      })
    },
    clearDataFieldValue: function() {
      this.clearDataFieldValueInternall()
      this.setDataFieldValue({dataFieldIdent: this.dataFieldIdent, dataFieldValue: null})
      if (this.hasLookup) this.setLookupVisible(false)
      this.hideCalendar()
      this.$refs.input.focus()
      this.inputFocus = true
    },
    clearDataFieldValueInternall: function() {
      let payload = {
        appWindowIdent: this.appWindowIdent,
        dataSetIdent: this.dataSetIdent,
        dataFieldIdent: this.dataFieldIdent,
        sourceKind: this.sourceKind,
        row: this.contextRow
      }
      this.deleteDataSetWhereListsItem(payload)
      this.clearLookupDataSetsSelection(payload)
      this.clearDataSetsFromSetters(payload)
    },
    setLookupHeightAndPlacement: function() {
      if (this.$el != null && this.lookupDef !== null) {
        let clippingParent = this.$el.parentElement
        let clippingParentStyle = getComputedStyle(clippingParent)
        while(clippingParentStyle.overflow != 'hidden') {
          clippingParent = clippingParent.parentElement
          if(clippingParent == null) break
          clippingParentStyle = getComputedStyle(clippingParent)
        }
        //
        let clippingParentBottom
        let clippingParentTop
        if(clippingParent != null) {
          clippingParentTop = clippingParent.getBoundingClientRect().top
          clippingParentBottom = clippingParent.getBoundingClientRect().bottom
        } else {
          clippingParentTop = 0
          clippingParentBottom = window.innerHeight
        }
        //
        let spaceBelow = Math.floor(clippingParentBottom - this.$el.getBoundingClientRect().bottom)
        if(spaceBelow >= this.lookupMinHeight) {
          this.lookupHeight = spaceBelow + 'px'
          this.lookupPlacement = ''
        } else {
          let spaceAbove = Math.floor(this.$el.getBoundingClientRect().top - clippingParentTop)
          if(spaceBelow >= spaceAbove) {
            this.lookupHeight = spaceBelow + 'px'
            this.lookupPlacement = ''
          } else {
            this.lookupHeight = spaceAbove + 'px'
            this.lookupPlacement = 'c-lookup-top'
          }
        }
      }
    },
    //AKO - was replaced with function -setLookupHeightAndPlacement
    // setLookupHeight: function() {
    //   let lookupHeightResult = null

    //   if (
    //     this.$el != null &&
    //     this.lookupDef !== null /*&& this.lookupDef.lookupVisible === true*/
    //   ) {
    //     let spaceBelow =
    //       window.innerHeight -
    //       this.$el.getBoundingClientRect().bottom -
    //       this.lookupMinHeight / 20

    //     if (spaceBelow > this.lookupMinHeight) {
    //       let lookupHeightTmp = Math.ceil(screen.height / 2)

    //       if (lookupHeightTmp > this.lookupMinHeight && lookupHeightTmp < spaceBelow)
    //         lookupHeightResult = lookupHeightTmp
    //       else lookupHeightResult = spaceBelow

    //       lookupHeightResult += 'px'
    //     }
    //   }
    //   this.lookupHeight = lookupHeightResult
    //   this.lookupPlacement = ''
    //   this.setLookupPlacement(this.$el)
    // },
    isLookupVisible: function(cont){
      const { bottom: contBottom } = cont.getBoundingClientRect()
      const { bottom } = this.$el.getBoundingClientRect()
      return bottom + this.lookupMinHeight <= contBottom
    },
    //AKO - was replaced with function -setLookupHeightAndPlacement
    // setLookupPlacement: function(el){
    //   const lookup = this.$refs.lookupCont
    //   if (!lookup){
    //     this.lookupPlacement = ''
    //     return
    //   }
    //   let parent = el.parentElement
    //   if (parent == null){
    //     this.lookupPlacement = ''
    //     return
    //   }
    //   let pStyles = getComputedStyle(parent)
    //   if (pStyles.overflowY == 'visible')
    //     return this.setLookupPlacement(parent)
    //   else if (this.isLookupVisible(parent))
    //     return this.setLookupPlacement(parent)
    //   else
    //     this.lookupPlacement = 'c-lookup-top'
    // },
    monthLeft: function() {
      let date = new Date(this.date)
      date.setMonth(date.getMonth() - 1)
      this.date = date
    },
    monthRight: function() {
      let date = new Date(this.date)
      date.setMonth(date.getMonth() + 1)
      this.date = date
    },
    getDate: function(r, c) {
      let day = (r - 1) * 7 + (c - 1)
      let date = new Date(this.date)
      date.setDate(1)
      let d = date.getDay()

      if (d == 0) {
        d = 6
      } else if (d >= 1) d = d - 1
      return moment(date)
        .add(day - d, 'days')
        .format('YYYY-MM-DD')
    },
    getDay: function(r, c) {
      return moment(this.getDate(r, c), 'YYYY-MM-DD').format('D')
    },
    getWeekNumber: function(r, c) {
      return moment(this.getDate(r, c), 'YYYY-MM-DD').format('W')
    },
    setDate: function(dataFieldValue) {
      if (this.onValueChange) {
        dataFieldValue = this.onValueChange(dataFieldValue)
        if (dataFieldValue == null)
          return
      }
      this.setDataFieldValue({dataFieldIdent: this.dataFieldIdent, dataFieldValue: dataFieldValue})
      this.hideCalendar()
    },
    getCalendarDayClass: function(r, c) {
      let date = this.getDate(r, c)
      if (date == moment(this.dataFieldValue).format('YYYY-MM-DD'))
        return 'c-set-value'
      if (date == moment().format('YYYY-MM-DD')) return 'c-today'
      let m = moment(date)
      if (m.diff(moment().format('YYYY-MM-DD')) < 0) return 'c-past'
      if (m.diff(moment().format('YYYY-MM-DD')) > 0) return 'c-future'
    },
    getCalendarDayOutOfRangeClass: function(r, c) {
      let date = this.getDate(r, c)
      if (new Date(date).getMonth() != new Date(this.date).getMonth())
        return 'c-outrange'
    },
    togglePasswordVisibility: function() {
      if (this.inputType == 'password') {
        this.inputType = 'text'
      } else if (this.inputType == 'text') {
        this.inputType = 'password'
      }
    },
    toggleIsActive: function(evt) {
      if (this.whereFieldsIdentsDataField == undefined) return
      this.setWhereFieldsIdentsDataFieldIsActive({
        whereFieldsIdentsDataField: this.whereFieldsIdentsDataField,
        isActive: evt.target.checked
      })
    }
  },
  created: function() {
    this.inputTypeInitial = this.type
    //
    this.months = [
      'styczeń',
      'luty',
      'marzec',
      'kwiecień',
      'maj',
      'czerwiec',
      'lipiec',
      'sierpień',
      'wrzesień',
      'październik',
      'listopad',
      'grudzień'
    ]
    this.weekdays = ['Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'N']
  },
  updated: function() {
    if(this.$el != null) {
      this.elClientHeight = this.$el.clientHeight != null ? this.$el.clientHeight + 'px' : null
      this.elOffsetHeight = this.$el.offsetHeight != null ? this.$el.offsetHeight + 'px' : null
    }
  }
}
</script>
