import { __extends, __assign, __decorate, __metadata } from 'tslib';
import { classNamesFunction } from '@uifabric-vue/utilities';
import { Prop, Component } from 'vue-property-decorator';
import { DirectionalHint } from '../../common/DirectionalHint.js';
import { clickedOutside } from '../../utilities/clickedOutside.js';
import BaseComponent from '../BaseComponent.js';
import { positionCallout, getMaxHeight } from '../../utilities/positioning/positioning.js';

var getClassNames = classNamesFunction();
var CalloutContentBase = function(_super) {
  __extends(CalloutContentBase2, _super);
  function CalloutContentBase2() {
    var _this = _super !== null && _super.apply(this, arguments) || this;
    _this.internalKey = new Date();
    _this.positions = null;
    _this.maxHeight = 0;
    _this.blockResetHeight = false;
    _this.heightOffset = 0;
    _this.positionAttempts = 0;
    return _this;
  }
  CalloutContentBase2.prototype.created = function() {
    window.addEventListener("click", this.onGlobalClick, true);
    window.addEventListener("scroll", this.onGlobalScroll, true);
  };
  CalloutContentBase2.prototype.beforeDestroy = function() {
    window.removeEventListener("click", this.onGlobalClick, true);
    window.removeEventListener("scroll", this.onGlobalScroll, true);
  };
  CalloutContentBase2.prototype.updated = function() {
    this.internalKey = new Date();
  };
  CalloutContentBase2.prototype.mounted = function() {
    this.updatePosition();
  };
  Object.defineProperty(CalloutContentBase2.prototype, "classNames", {
    get: function() {
      var _a = this, theme = _a.theme, className = _a.className, calloutMaxWidth = _a.calloutMaxWidth; _a.calloutMaxHeight; var backgroundColor = _a.backgroundColor, finalHeight = _a.finalHeight, positions = _a.positions, styles = _a.styles, calloutWidth = _a.calloutWidth, beakWidth = _a.beakWidth;
      return getClassNames(styles, {
        theme: theme,
        className: className,
        overflowYHidden: !!finalHeight,
        calloutWidth: calloutWidth,
        positions: positions,
        beakWidth: beakWidth,
        backgroundColor: backgroundColor,
        calloutMaxWidth: calloutMaxWidth
      });
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(CalloutContentBase2.prototype, "actualBeakWidth", {
    get: function() {
      return Math.sqrt(this.beakWidth * this.beakWidth * 2);
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(CalloutContentBase2.prototype, "positionCss", {
    get: function() {
      if (!this.positions)
        return null;
      var positionCss = this.positions;
      for (var key in positionCss.elementPosition) {
        positionCss.elementPosition[key] = "".concat(positionCss.elementPosition[key], "px");
      }
      for (var key in positionCss.beakPosition.elementPosition) {
        positionCss.beakPosition.elementPosition[key] = "".concat(positionCss.beakPosition.elementPosition[key], "px");
      }
      return positionCss;
    },
    enumerable: false,
    configurable: true
  });
  CalloutContentBase2.prototype.updatePosition = function() {
    var positions = this.positions;
    var currentProps = __assign({}, this.$props);
    currentProps.bounds = this.bounds;
    currentProps.target = this.target;
    var newPositions = positionCallout(currentProps, this.$refs.hostElement, this.$refs.calloutElement, this.positions);
    if (!positions && newPositions || positions && newPositions && !this._arePositionsEqual(positions, newPositions) && this.positionAttempts < 5) {
      this.positionAttempts++;
      this.positions = newPositions;
    } else if (this.positionAttempts > 0) {
      this.positionAttempts = 0;
      this.$emit("positioned", this.positions);
    }
  };
  CalloutContentBase2.prototype.onGlobalClick = function(e) {
    var outside = clickedOutside(e, this.$refs.calloutElement);
    if (outside)
      this.$emit("dismiss", e);
  };
  CalloutContentBase2.prototype.onGlobalScroll = function(e) {
    this.$emit("dismiss", e);
  };
  Object.defineProperty(CalloutContentBase2.prototype, "bounds", {
    get: function() {
      return {
        top: 0 + this.minPagePadding,
        left: 0 + this.minPagePadding,
        right: window.innerWidth - this.minPagePadding,
        bottom: window.innerHeight - this.minPagePadding,
        width: window.innerWidth - this.minPagePadding * 2,
        height: window.innerHeight - this.minPagePadding * 2
      };
    },
    enumerable: false,
    configurable: true
  });
  CalloutContentBase2.prototype._getMaxHeight = function() {
    var _this = this;
    if (!this.maxHeight) {
      if (this.directionalHintFixed && this.target) {
        var beakWidth = this.isBeakVisible ? this.beakWidth : 0;
        var gapSpace = this.gapSpace ? this.gapSpace : 0;
        var totalGap_1 = gapSpace + beakWidth;
        this._async.requestAnimationFrame(function() {
          if (_this.target) {
            _this.maxHeight = getMaxHeight(_this.target, _this.directionalHint, totalGap_1, _this.bounds, _this.coverTarget);
            _this.blockResetHeight = true;
            _this.$forceUpdate();
          }
        }, this.target);
      } else {
        this.maxHeight = this.bounds.height;
      }
    }
    return this.maxHeight;
  };
  CalloutContentBase2.prototype._arePositionsEqual = function(positions, newPosition) {
    return this._comparePositions(positions.elementPosition, newPosition.elementPosition) && this._comparePositions(positions.beakPosition.elementPosition, newPosition.beakPosition.elementPosition);
  };
  CalloutContentBase2.prototype._comparePositions = function(oldPositions, newPositions) {
    for (var key in newPositions) {
      if (newPositions.hasOwnProperty(key)) {
        var oldPositionEdge = oldPositions[key];
        var newPositionEdge = newPositions[key];
        if (oldPositionEdge !== void 0 && newPositionEdge !== void 0) {
          if (oldPositionEdge.toFixed(2) !== newPositionEdge.toFixed(2)) {
            return false;
          }
        } else {
          return false;
        }
      }
    }
    return true;
  };
  CalloutContentBase2.prototype.render = function(h) {
    var _a = this, classNames = _a.classNames, positionCss = _a.positionCss, calloutMaxHeight = _a.calloutMaxHeight, overflowYHidden = _a.overflowYHidden, isBeakVisible = _a.isBeakVisible;
    var getContentMaxHeight = this._getMaxHeight() ? this._getMaxHeight() + this.heightOffset : void 0;
    var contentMaxHeight = calloutMaxHeight && getContentMaxHeight && calloutMaxHeight < getContentMaxHeight ? calloutMaxHeight : getContentMaxHeight;
    var overflowStyle = __assign({
      maxHeight: contentMaxHeight
    }, overflowYHidden && { overflowY: "hidden" });
    return h("div", {
      ref: "hostElement",
      class: classNames.container
    }, [
      h("div", {
        ref: "calloutElement",
        class: classNames.root,
        style: positionCss ? positionCss.elementPosition : null
      }, [
        isBeakVisible && h("div", {
          class: classNames.beak,
          style: positionCss && positionCss.beakPosition ? positionCss.beakPosition.elementPosition : null
        }),
        isBeakVisible && h("div", { class: classNames.beakCurtain }),
        h("div", { class: classNames.calloutMain, style: overflowStyle }, [
          this.$slots.default
        ])
      ])
    ]);
  };
  __decorate([
    Prop({ type: HTMLElement, required: true }),
    __metadata("design:type", HTMLElement)
  ], CalloutContentBase2.prototype, "target", void 0);
  __decorate([
    Prop({ type: Number, default: null }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "calloutWidth", void 0);
  __decorate([
    Prop({ type: Number, default: 16 }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "beakWidth", void 0);
  __decorate([
    Prop({ type: Number, default: 8 }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "minPagePadding", void 0);
  __decorate([
    Prop({ type: Boolean, default: true }),
    __metadata("design:type", Boolean)
  ], CalloutContentBase2.prototype, "isBeakVisible", void 0);
  __decorate([
    Prop({ type: Boolean, default: false }),
    __metadata("design:type", Boolean)
  ], CalloutContentBase2.prototype, "coverTarget", void 0);
  __decorate([
    Prop({ type: Number, default: 0 }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "gapSpace", void 0);
  __decorate([
    Prop({ type: Number, default: void 0 }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "finalHeight", void 0);
  __decorate([
    Prop({ type: Number, default: void 0 }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "calloutMaxWidth", void 0);
  __decorate([
    Prop({ type: Number, default: void 0 }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "calloutMaxHeight", void 0);
  __decorate([
    Prop({ type: String, default: void 0 }),
    __metadata("design:type", String)
  ], CalloutContentBase2.prototype, "backgroundColor", void 0);
  __decorate([
    Prop({ type: Number, default: DirectionalHint.bottomAutoEdge }),
    __metadata("design:type", Number)
  ], CalloutContentBase2.prototype, "directionalHint", void 0);
  __decorate([
    Prop({ type: Boolean, default: false }),
    __metadata("design:type", Boolean)
  ], CalloutContentBase2.prototype, "directionalHintFixed", void 0);
  __decorate([
    Prop({ type: Boolean, default: false }),
    __metadata("design:type", Boolean)
  ], CalloutContentBase2.prototype, "overflowYHidden", void 0);
  CalloutContentBase2 = __decorate([
    Component
  ], CalloutContentBase2);
  return CalloutContentBase2;
}(BaseComponent);

export { CalloutContentBase };
