fcf.module({
  name: "fcfControls:templates/datetime-edit.wrapper.js",
  dependencies: ["fcfControls:templates/view.wrapper.js"],
  module: function(Wrapper){
    return class WrapperEx extends Wrapper{

      constructor(a_initializeOptions){
        super(a_initializeOptions);
        let self = this;
        this._skeepClick = false;
        this._displayTD = false;
        this._tdsel = undefined;
      }

      destroy(){
        if (this._tdsel && this._tdsel.dtbox)
          this._tdsel.dtbox.visible = false;
        if (this._tdsel && this._tdsel.dtbox && this._tdsel.dtbox.el && this._tdsel.dtbox.el && this._tdsel.dtbox.el.wrapper)
          this._tdsel.dtbox.el.wrapper.remove();
        return super.destroy();
      }

      attach(){
        let self = this;
        if (this._tdsel && this._tdsel.dtbox && this._tdsel.dtbox.el && this._tdsel.dtbox.el && this._tdsel.dtbox.el.wrapper)
          this._tdsel.dtbox.el.wrapper.remove();
        this._tdsel = new fcfdtsel.DTS(
                          this.select("[name=dtsel]")[0],
                          {
                            showDate: this._isEnableDate(),
                            showTime: this._isEnableTime(),
                            width:    fcf.width(this.getDomElement()),
                            zindex:   fcf.getModalZIndex(),
                          });

        fcf.addDomListener(window, "click", this, (a_event)=>{
          setTimeout(()=>{
            self.onGlobalClick(a_event);
          },
          10);
        });
        fcf.addDomListener(window, "resize", this, (a_event)=>{
          self._setPositionBox(a_event);
        });

        return super.attach();
      }

      onArg(a_argName, a_value, a_editor, a_ignoreRedrawing, a_isInnerCall) {
        if (!a_isInnerCall)
          this.update();
        else
          this.recalculate();
      }

      onArgValue(a_value, a_edditor, a_ignoreRedrawing, a_isInnerCall){
        if (!a_isInnerCall)
          return;
        let date         = new Date(a_value);
        let displayValue = !isNaN(date.getTime()) ? fcf.dateFormat(date, this.getArg("format")) : "";
        this.select("[name='input']")[0].value = displayValue;
      }

      onClick(a_event) {
        if (this._displayTD)
          return;
        if (!this.getArg("enable"))
          return;

        let self = this;
        this._skeepClick = true;
        this._displayTD = true;

        let event = new Event("focus");
        this.select("[name=dtsel]")[0].dispatchEvent(event);
        this._setDTValues();
        this._setPositionBox();
        if (!this._originSetInputValue){
          this._originSetInputValue = this._tdsel.dtbox.setInputValue;
          this._tdsel.dtbox.setInputValue = function(){
            self._originSetInputValue.call(this);
            self.onInputDT();
          }
        }
      }

      onInput(){
        let input = this.select("[name='input']")[0];
        let selectionStart = input.selectionStart;
        input.value = input.value.substr(0, selectionStart) + input.value.substr(selectionStart+1);
        let text  = input.value;
        let date  = fcf.parseDate(text, this.getArg("format"));
        if (isNaN(date.getTime())){
          if (isNaN((new Date(this.getArg("value"))).getTime())){
            let defaultDate = fcf.parseDate("2000-01-01 00:00:00", "Y-m-d H:i:s");
            let newDisplayValue = fcf.dateFormat(defaultDate, this.getArg("format"));
            newDisplayValue     = text + newDisplayValue.substr(text.length);
            if (isNaN(fcf.parseDate(newDisplayValue, this.getArg("format")).getTime()))
              newDisplayValue = fcf.dateFormat(new Date(), this.getArg("format"));
            let newValue      = fcf.parseDate(newDisplayValue, this.getArg("format"));
            this._setArg("value", newValue);
            input.value = newDisplayValue;
          } else {
            input.value = fcf.dateFormat(this.getArg("value"), this.getArg("format"));
          }
          input.setSelectionRange(selectionStart, selectionStart);
        } else {
          this._setArg("value", date);
          this._setDTValues();
          input.setSelectionRange(selectionStart, selectionStart);
        }
      }

      onInputDT(){
        let date = new Date();
        date.setYear(this._tdsel.dtbox.year);
        date.setMonth(this._tdsel.dtbox.month);
        date.setDate(this._tdsel.dtbox.day);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        date.setMilliseconds(0);
        date = new Date(date.getTime() + this._tdsel.dtbox.time);
        this._originSetInputValue.call(this._tdsel.dtbox);
        this._setArg("value", date.toISOString());
      }

      onGlobalClick(a_event){
        if (this._skeepClick){
          this._skeepClick = false;
          return;
        }
        if (!this._displayTD)
          return;
        let element = a_event.target;
        while(element != document.body){
          if (!element)
            return
          if (element === this._tdsel.dtbox.el.wrapper){
            if (document.activeElement)
              document.activeElement.blur()
            return;
          }
          if (element === this.getDomElement())
            break;
          element = element.parentNode;
        }
        let event = new Event("blur");
        this._displayTD = false;
        this._tdsel.dtbox.visible = false;
        let el = this.select("[name=dtsel]")[0];
        if (el)
          el.blur();

      }

      _setPositionBox(){
        if (!this._tdsel || !this._tdsel.dtbox || !this._tdsel.dtbox.el || !this._tdsel.dtbox.el.wrapper)
          return;
        let rect = this.getDomElement().getBoundingClientRect();
        let offsetX = window.scrollX !== undefined ? window.scrollX : document.documentElement.scrollLeft;
        let offsetY = window.scrollY !== undefined ? window.scrollY : document.documentElement.scrollTop;
        this._tdsel.dtbox.el.wrapper.style.left = (rect.left + offsetX) + "px";
        this._tdsel.dtbox.el.wrapper.style.top  = (rect.bottom + offsetY + 8) + "px";
      }

      _setDTValues(){
        let date = new Date(this.getArg("value"));
        if (!isNaN(date.getTime()) && this._tdsel.dtbox) {
          this._tdsel.dtbox.value = date;
          this._tdsel.dtbox.year = date.getYear()+1900;
          this._tdsel.dtbox.month = date.getMonth();
          this._tdsel.dtbox.day = date.getDate();
          this._tdsel.dtbox.hours = date.getHours();
          this._tdsel.dtbox.minutes = date.getMinutes();
          this._tdsel.dtbox.seconds = date.getSeconds();
          this._tdsel.dtbox.setInputValue();
          if (this._tdsel.dtbox.settings.config.showDate) {
            this._tdsel.dtbox.setHeaderContent();
            this._tdsel.dtbox.setBodyContent();
          }
          if (this._tdsel.dtbox.settings.config.showTime) {
            this._tdsel.dtbox.setFooterContent();
          }
        }
      }

      _isEnableDate(){
        return fcf.find(this.getArg("format"), ["Y","m","d"]) !== undefined;
      }

      _isEnableTime(){
        return fcf.find(this.getArg("format"), ["H","h","i","s"]) !== undefined;
      }


    };
  }
});
