"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const tslib_es6 = require("../../../../../../../tslib@2.6.2/node_modules/tslib/tslib.es6.js");
const isAnimationControls = require("../../animation/utils/is-animation-controls.js");
const isKeyframesTarget = require("../../animation/utils/is-keyframes-target.js");
const shallowCompare = require("../../utils/shallow-compare.js");
const animation = require("./animation.js");
const types = require("./types.js");
const variants = require("./variants.js");
var variantPriorityOrder = [
  types.AnimationType.Animate,
  types.AnimationType.InView,
  types.AnimationType.Focus,
  types.AnimationType.Hover,
  types.AnimationType.Tap,
  types.AnimationType.Drag,
  types.AnimationType.Exit
];
var reversePriorityOrder = tslib_es6.__spreadArray([], tslib_es6.__read(variantPriorityOrder), false).reverse();
var numAnimationTypes = variantPriorityOrder.length;
function animateList(visualElement) {
  return function(animations) {
    return Promise.all(animations.map(function(_a) {
      var animation$1 = _a.animation, options = _a.options;
      return animation.animateVisualElement(visualElement, animation$1, options);
    }));
  };
}
function createAnimationState(visualElement) {
  var animate = animateList(visualElement);
  var state = createState();
  var allAnimatedKeys = {};
  var isInitialRender = true;
  var buildResolvedTypeValues = function(acc, definition) {
    var resolved = variants.resolveVariant(visualElement, definition);
    if (resolved) {
      resolved.transition;
      var transitionEnd = resolved.transitionEnd, target = tslib_es6.__rest(resolved, ["transition", "transitionEnd"]);
      acc = tslib_es6.__assign(tslib_es6.__assign(tslib_es6.__assign({}, acc), target), transitionEnd);
    }
    return acc;
  };
  function isAnimated(key) {
    return allAnimatedKeys[key] !== void 0;
  }
  function setAnimateFunction(makeAnimator) {
    animate = makeAnimator(visualElement);
  }
  function animateChanges(options, changedActiveType) {
    var _a;
    var props = visualElement.getProps();
    var context = visualElement.getVariantContext(true) || {};
    var animations = [];
    var removedKeys = /* @__PURE__ */ new Set();
    var encounteredKeys = {};
    var removedVariantIndex = Infinity;
    var _loop_1 = function(i2) {
      var type = reversePriorityOrder[i2];
      var typeState = state[type];
      var prop = (_a = props[type]) !== null && _a !== void 0 ? _a : context[type];
      var propIsVariant = variants.isVariantLabel(prop);
      var activeDelta = type === changedActiveType ? typeState.isActive : null;
      if (activeDelta === false)
        removedVariantIndex = i2;
      var isInherited = prop === context[type] && prop !== props[type] && propIsVariant;
      if (isInherited && isInitialRender && visualElement.manuallyAnimateOnMount) {
        isInherited = false;
      }
      typeState.protectedKeys = tslib_es6.__assign({}, encounteredKeys);
      if (
        // If it isn't active and hasn't *just* been set as inactive
        !typeState.isActive && activeDelta === null || // If we didn't and don't have any defined prop for this animation type
        !prop && !typeState.prevProp || // Or if the prop doesn't define an animation
        isAnimationControls.isAnimationControls(prop) || typeof prop === "boolean"
      ) {
        return "continue";
      }
      var variantDidChange = checkVariantsDidChange(typeState.prevProp, prop);
      var shouldAnimateType = variantDidChange || // If we're making this variant active, we want to always make it active
      type === changedActiveType && typeState.isActive && !isInherited && propIsVariant || // If we removed a higher-priority variant (i is in reverse order)
      i2 > removedVariantIndex && propIsVariant;
      var definitionList = Array.isArray(prop) ? prop : [prop];
      var resolvedValues = definitionList.reduce(buildResolvedTypeValues, {});
      if (activeDelta === false)
        resolvedValues = {};
      var _b = typeState.prevResolvedValues, prevResolvedValues = _b === void 0 ? {} : _b;
      var allKeys = tslib_es6.__assign(tslib_es6.__assign({}, prevResolvedValues), resolvedValues);
      var markToAnimate = function(key2) {
        shouldAnimateType = true;
        removedKeys.delete(key2);
        typeState.needsAnimating[key2] = true;
      };
      for (var key in allKeys) {
        var next = resolvedValues[key];
        var prev = prevResolvedValues[key];
        if (encounteredKeys.hasOwnProperty(key))
          continue;
        if (next !== prev) {
          if (isKeyframesTarget.isKeyframesTarget(next) && isKeyframesTarget.isKeyframesTarget(prev)) {
            if (!shallowCompare.shallowCompare(next, prev) || variantDidChange) {
              markToAnimate(key);
            } else {
              typeState.protectedKeys[key] = true;
            }
          } else if (next !== void 0) {
            markToAnimate(key);
          } else {
            removedKeys.add(key);
          }
        } else if (next !== void 0 && removedKeys.has(key)) {
          markToAnimate(key);
        } else {
          typeState.protectedKeys[key] = true;
        }
      }
      typeState.prevProp = prop;
      typeState.prevResolvedValues = resolvedValues;
      if (typeState.isActive) {
        encounteredKeys = tslib_es6.__assign(tslib_es6.__assign({}, encounteredKeys), resolvedValues);
      }
      if (isInitialRender && visualElement.blockInitialAnimation) {
        shouldAnimateType = false;
      }
      if (shouldAnimateType && !isInherited) {
        animations.push.apply(animations, tslib_es6.__spreadArray([], tslib_es6.__read(definitionList.map(function(animation2) {
          return {
            animation: animation2,
            options: tslib_es6.__assign({ type }, options)
          };
        })), false));
      }
    };
    for (var i = 0; i < numAnimationTypes; i++) {
      _loop_1(i);
    }
    allAnimatedKeys = tslib_es6.__assign({}, encounteredKeys);
    if (removedKeys.size) {
      var fallbackAnimation_1 = {};
      removedKeys.forEach(function(key) {
        var fallbackTarget = visualElement.getBaseTarget(key);
        if (fallbackTarget !== void 0) {
          fallbackAnimation_1[key] = fallbackTarget;
        }
      });
      animations.push({ animation: fallbackAnimation_1 });
    }
    var shouldAnimate = Boolean(animations.length);
    if (isInitialRender && props.initial === false && !visualElement.manuallyAnimateOnMount) {
      shouldAnimate = false;
    }
    isInitialRender = false;
    return shouldAnimate ? animate(animations) : Promise.resolve();
  }
  function setActive(type, isActive, options) {
    var _a;
    if (state[type].isActive === isActive)
      return Promise.resolve();
    (_a = visualElement.variantChildren) === null || _a === void 0 ? void 0 : _a.forEach(function(child) {
      var _a2;
      return (_a2 = child.animationState) === null || _a2 === void 0 ? void 0 : _a2.setActive(type, isActive);
    });
    state[type].isActive = isActive;
    var animations = animateChanges(options, type);
    for (var key in state) {
      state[key].protectedKeys = {};
    }
    return animations;
  }
  return {
    isAnimated,
    animateChanges,
    setActive,
    setAnimateFunction,
    getState: function() {
      return state;
    }
  };
}
function checkVariantsDidChange(prev, next) {
  if (typeof next === "string") {
    return next !== prev;
  } else if (variants.isVariantLabels(next)) {
    return !shallowCompare.shallowCompare(next, prev);
  }
  return false;
}
function createTypeState(isActive) {
  if (isActive === void 0) {
    isActive = false;
  }
  return {
    isActive,
    protectedKeys: {},
    needsAnimating: {},
    prevResolvedValues: {}
  };
}
function createState() {
  var _a;
  return _a = {}, _a[types.AnimationType.Animate] = createTypeState(true), _a[types.AnimationType.InView] = createTypeState(), _a[types.AnimationType.Hover] = createTypeState(), _a[types.AnimationType.Tap] = createTypeState(), _a[types.AnimationType.Drag] = createTypeState(), _a[types.AnimationType.Focus] = createTypeState(), _a[types.AnimationType.Exit] = createTypeState(), _a;
}
exports.checkVariantsDidChange = checkVariantsDidChange;
exports.createAnimationState = createAnimationState;
exports.variantPriorityOrder = variantPriorityOrder;
//# sourceMappingURL=animation-state.js.map
