text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  var transition_1 = require("./transition");
  var TransitionController = /** @class */ (function () {
      function TransitionController(isInitiallyVisible, display) {
          if (isInitiallyVisible === void 0) { isInitiallyVisible = true; }
          if (display === void 0) { display = "block"; }
          // isInitiallyVisible sets whether the element starts out visible.
          this._isVisible = isInitiallyVisible;
          this._isHidden = !this._isVisible;
          this._display = display;
          this._queue = [];
          this._isAnimating = false;
      }
      Object.defineProperty(TransitionController.prototype, "_isReady", {
          // Used to delay animations until we have an element to animate.
          get: function () {
              return this._renderer != undefined && this._element != undefined && this._changeDetector != undefined;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(TransitionController.prototype, "isAnimating", {
          get: function () {
              return this._isAnimating;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(TransitionController.prototype, "isVisible", {
          get: function () {
              return this._isVisible;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(TransitionController.prototype, "isHidden", {
          get: function () {
              return this._isHidden;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(TransitionController.prototype, "_queueFirst", {
          // Gets the first transition in the queue.
          get: function () {
              return this._queue[0];
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(TransitionController.prototype, "_queueLast", {
          // Gets the last transition in the queue.
          get: function () {
              return this._queue[this._queue.length - 1];
          },
          enumerable: true,
          configurable: true
      });
      // Sets the renderer to be used for animating.
      TransitionController.prototype.registerRenderer = function (renderer) {
          this._renderer = renderer;
          this.performTransition();
      };
      // Sets the element to perform the animations on.
      TransitionController.prototype.registerElement = function (element) {
          this._element = element;
          this.performTransition();
      };
      // Sets the change detector to detect changes when using ChangeDetectionStrategy.OnPush.
      TransitionController.prototype.registerChangeDetector = function (changeDetector) {
          this._changeDetector = changeDetector;
          this.performTransition();
      };
      TransitionController.prototype.animate = function (transition) {
          // Test if transition is one of the list that doesn't change the visible state.
          // Should these eventually become classes?
          var isDirectionless = ["jiggle", "flash", "shake", "pulse", "tada", "bounce"].indexOf(transition.type) !== -1;
          if (isDirectionless) {
              transition.direction = transition_1.TransitionDirection.Static;
          }
          else if (transition.direction == undefined || transition.direction === transition_1.TransitionDirection.Either) {
              // Set the direction to the opposite of the current visible state automatically if not set, or set to either direction.
              transition.direction = this._isVisible ? transition_1.TransitionDirection.Out : transition_1.TransitionDirection.In;
              if (this._queueLast) {
                  // If there is an transition in the queue already, set the direction to the opposite of the direction of that transition.
                  if (this._queueLast.direction === transition_1.TransitionDirection.In) {
                      transition.direction = transition_1.TransitionDirection.Out;
                  }
                  else if (this._queueLast.direction === transition_1.TransitionDirection.Out) {
                      transition.direction = transition_1.TransitionDirection.In;
                  }
              }
          }
          // Store the transition in the queue before attempting to perform it.
          this._queue.push(transition);
          this.performTransition();
      };
      TransitionController.prototype.performTransition = function () {
          var _this = this;
          if (!this._isReady || this._isAnimating || !this._queueFirst) {
              // Don't transition until we are ready, or if we are animating, or if there aren't any transitions in the queue.
              return;
          }
          this._isAnimating = true;
          var transition = this._queueFirst;
          // Set the Semantic UI classes for transitioning.
          transition.classes.forEach(function (c) { return _this._renderer.addClass(_this._element, c); });
          this._renderer.addClass(this._element, "animating");
          this._renderer.addClass(this._element, transition.directionClass);
          // Set the Semantic UI styles for transitioning.
          this._renderer.setStyle(this._element, "animationDuration", transition.duration + "ms");
          this._renderer.setStyle(this._element, "display", this._display);
          if (transition.direction === transition_1.TransitionDirection.In) {
              // Unset hidden if we are transitioning in.
              this._isHidden = false;
          }
          // Wait the length of the animation before calling the complete callback.
          this._animationTimeout = window.setTimeout(function () { return _this.finishTransition(transition); }, transition.duration);
      };
      // Called when a transition has completed.
      TransitionController.prototype.finishTransition = function (transition) {
          var _this = this;
          // Unset the Semantic UI classes & styles for transitioning.
          transition.classes.forEach(function (c) { return _this._renderer.removeClass(_this._element, c); });
          this._renderer.removeClass(this._element, "animating");
          this._renderer.removeClass(this._element, transition.directionClass);
          this._renderer.removeStyle(this._element, "animationDuration");
          this._renderer.removeStyle(this._element, "display");
          if (transition.direction === transition_1.TransitionDirection.In) {
              // If we have just animated in, we are now visible.
              this._isVisible = true;
          }
          else if (transition.direction === transition_1.TransitionDirection.Out) {
              // If we have transitioned out, we should be invisible and hidden.
              this._isVisible = false;
              this._isHidden = true;
          }
          if (transition.onComplete) {
              // Call the user-defined transition callback.
              transition.onComplete();
          }
          // Delete the transition from the queue.
          this._queue.shift();
          this._isAnimating = false;
          this._changeDetector.markForCheck();
          // Immediately attempt to perform another transition.
          this.performTransition();
      };
      // Stops the current transition, leaves the rest of the queue intact.
      TransitionController.prototype.stop = function (transition) {
          if (transition === void 0) { transition = this._queueFirst; }
          if (!transition || !this._isAnimating) {
              return;
          }
          clearTimeout(this._animationTimeout);
          this.finishTransition(transition);
      };
      // Stops the current transition, and empties the queue.
      TransitionController.prototype.stopAll = function () {
          this.clearQueue();
          this.stop();
      };
      // Empties the transition queue but carries on with the current transition.
      TransitionController.prototype.clearQueue = function () {
          if (this.isAnimating) {
              this._queue = [this._queueFirst];
              return;
          }
          this._queue = [];
      };
      return TransitionController;
  }());
  exports.TransitionController = TransitionController;
  