fcf.module({
  name: "fcfControls:templates/dialog.wrapper.js",
  dependencies: ["fcf:NClient/Wrapper.js"],
  module: function(Wrapper){
    return class DialogWrapper extends Wrapper{

      constructor(a_initializeOptions){
        super(a_initializeOptions);
        let self = this;
        this._locker = undefined;
        this._mouseStartDDPos = undefined;
        this._relativeOffsetX = -1;
        this._offsetY = -1;

        fcf.addDomListener(window, "resize", this);

        setTimeout(()=>{
          self.getDomElement().style.marginTop   = "0px";
          self.getDomElement().style.marginLeft  = "0px";
          self._setCenterPosition();
          self.setArg("fcfStyleInner", "", true);
        }, 1);

        if (this.getArg("modal")) {
          this._locker = fcf.locker({
            content:  "",
            selector: "body"
          });
          this._zIndex = fcf.getModalZIndex();
          this.getDomElement().style.zIndex = this._zIndex;
        }
      }

      onResize(a_event) {
        this._reposition();
      }

      attach(a_cb) {
        let self = this;
        let position = this.getArg("position");
        let element = this.getDomElement();

        this.getDomElement().style.zIndex = this._zIndex;
        if (this._relativeOffsetX != -1)
          this._reposition();

        fcf.addDomListener(fcf.select(this.getDomElement(), ".fcf-dialog-title")[0], "mousedown", this, function(a_event) {
          self.onTitleMouseDown(a_event);
        });
        fcf.addDomListener(document.body, "mouseup", this, function(a_event) {
          self.onTitleMouseUp(a_event);
        });
        fcf.addDomListener(document.body, "mousemove", this, function(a_event) {
          self.onTitleMouseMove(a_event);
        });

        return super.attach();
      }



      onTitleMouseDown(a_event){
        a_event.preventDefault();
        if (a_event.buttons != 1 || this._mouseStartDDPos)
          return;
        this._mouseStartDDPos = {x: a_event.screenX, y: a_event.screenY};
      }

      onTitleMouseUp(a_event){
        if (a_event.buttons != 0 || !this._mouseStartDDPos)
          return;
        var element = this.getDomElement();
        var offsetX = a_event.screenX - this._mouseStartDDPos.x;
        var offsetY = a_event.screenY - this._mouseStartDDPos.y;
        var left = parseInt(element.getAttribute("left")) + offsetX;
        var top  = parseInt(element.getAttribute("top")) + offsetY;
        element.setAttribute("left", left);
        element.setAttribute("top", top);
        this._saveRelativePosition();

        this._mouseStartDDPos = undefined;
      }

      onTitleMouseMove(a_event){
        if (!this._mouseStartDDPos)
          return;
        var element = this.getDomElement();
        var offsetX = a_event.screenX - this._mouseStartDDPos.x;
        var offsetY = a_event.screenY - this._mouseStartDDPos.y;
        var left = parseInt(element.getAttribute("left")) + offsetX;
        var top  = parseInt(element.getAttribute("top")) + offsetY;
        element.style.left = left + "px";
        element.style.top  = top + "px";
        element.style.marginLeft  = "0px";

        this._saveRelativePosition();
      }

      close(a_reason){
        let event = this.emit("close", {reason: a_reason, wrapper: this});
        if (!event.stopDefault)
          this.destroy();
      }

      destroy(){
        if (this._locker){
          this._locker.remove();
          this._locker = undefined;
        }
        super.destroy();
      }

      getBodyDomElement(){
        return fcf.select(this.getDomElement(), "[name=body]")[0];
      }

      _setCenterPosition(){
        let self = this;
        let element = this.getDomElement();
        let selfRect = element.getBoundingClientRect();

        let screenTop    = document.body.scrollTop;
        let screenHeight = window.innerHeight;
        let screenLeft   = document.body.scrollLeft;
        let screenWidth  = window.innerWidth;
        let screenOffsetTop  = (screenHeight / 2);
        let screenOffsetLeft = screenLeft + (screenWidth / 2);
        let sizeСompression = document.body.offsetWidth <= element.offsetWidth;
        let left;
        let top;
        if (sizeСompression){
          left = 0;
          top  = element.offsetHeight <= screenHeight
                    ? Math.floor(screenOffsetTop - (element.offsetHeight/2)) + screenTop
                    : screenTop;
          if (top < 0)
            top = 0;
        } else {
          left = Math.floor(screenOffsetLeft - (element.offsetWidth/2));
          top  = element.offsetHeight <= screenHeight
                    ? Math.floor(screenOffsetTop - (element.offsetHeight/2)) + screenTop
                    : screenTop;
          if (top < 0)
            top = 0;
        }

        element.style.position = "absolute";
        element.style.left = left + "px";
        element.style.top  = top + "px";
        element.style.marginLeft  = "0px";
        element.setAttribute("left", left);
        element.setAttribute("top", top);
        this._saveRelativePosition();
        setTimeout(()=>{
          self._saveRelativePosition();
        },1);
      }

      _reposition() {
        let lastPositionLockerStyle = null;
        let lastPositionDialogStyle = null;
        if (this._locker){
          lastPositionLockerStyle = this._locker.style.position;
          this._locker.style.position = "fixed";
        }

        let element = this.getDomElement();
        lastPositionDialogStyle = element.style.position;
        element.style.position = "fixed";
        let centerX = document.body.scrollWidth * this._relativeOffsetX;
        element.style.position = lastPositionDialogStyle;

        let sizeСompression = document.body.offsetWidth <= element.offsetWidth;
        let left = undefined;
        if (this._locker)
          this._locker.style.position = lastPositionLockerStyle;
        if (sizeСompression) {
          left    = 0;
        } else {
          left    = centerX - (element.offsetWidth)/2;
        }
        if (left < 0)
          left = 0;
        element.style.left = left + "px";
        element.style.top  = this._offsetY + "px";
        element.style.marginLeft  = "0px";
        element.setAttribute("left", left);
        element.setAttribute("top", this._offsetY);
      }

      _saveRelativePosition() {
        let element = this.getDomElement();
        let offsetX = window.scrollX !== undefined ? window.scrollX : document.documentElement.scrollLeft;
        this._relativeOffsetX = (offsetX + (element.offsetLeft + element.offsetWidth/2)) / document.body.scrollWidth;
        this._offsetY = element.offsetTop;
      }

    };
  }
});
