"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Series = require("../model/Series.js");
const util = require("../../../../../zrender@5.4.4/node_modules/zrender/lib/core/util.js");
const morphTransitionHelper = require("./morphTransitionHelper.js");
const Path = require("../../../../../zrender@5.4.4/node_modules/zrender/lib/graphic/Path.js");
require("../util/graphic.js");
const DataDiffer = require("../data/DataDiffer.js");
const model = require("../util/model.js");
const log = require("../util/log.js");
const basicTransition = require("./basicTransition.js");
const Displayable = require("../../../../../zrender@5.4.4/node_modules/zrender/lib/graphic/Displayable.js");
var DATA_COUNT_THRESHOLD = 1e4;
var getUniversalTransitionGlobalStore = model.makeInner();
function getGroupIdDimension(data) {
  var dimensions = data.dimensions;
  for (var i = 0; i < dimensions.length; i++) {
    var dimInfo = data.getDimensionInfo(dimensions[i]);
    if (dimInfo && dimInfo.otherDims.itemGroupId === 0) {
      return dimensions[i];
    }
  }
}
function flattenDataDiffItems(list) {
  var items = [];
  util.each(list, function(seriesInfo) {
    var data = seriesInfo.data;
    if (data.count() > DATA_COUNT_THRESHOLD) {
      if (process.env.NODE_ENV !== "production") {
        log.warn("Universal transition is disabled on large data > 10k.");
      }
      return;
    }
    var indices = data.getIndices();
    var groupDim = getGroupIdDimension(data);
    for (var dataIndex = 0; dataIndex < indices.length; dataIndex++) {
      items.push({
        dataGroupId: seriesInfo.dataGroupId,
        data,
        dim: seriesInfo.dim || groupDim,
        divide: seriesInfo.divide,
        dataIndex
      });
    }
  });
  return items;
}
function fadeInElement(newEl, newSeries, newIndex) {
  newEl.traverse(function(el) {
    if (el instanceof Path.default) {
      basicTransition.initProps(el, {
        style: {
          opacity: 0
        }
      }, newSeries, {
        dataIndex: newIndex,
        isFrom: true
      });
    }
  });
}
function removeEl(el) {
  if (el.parent) {
    var computedTransform = el.getComputedTransform();
    el.setLocalTransform(computedTransform);
    el.parent.remove(el);
  }
}
function stopAnimation(el) {
  el.stopAnimation();
  if (el.isGroup) {
    el.traverse(function(child) {
      child.stopAnimation();
    });
  }
}
function animateElementStyles(el, dataIndex, seriesModel) {
  var animationConfig = basicTransition.getAnimationConfig("update", seriesModel, dataIndex);
  animationConfig && el.traverse(function(child) {
    if (child instanceof Displayable.default) {
      var oldStyle = basicTransition.getOldStyle(child);
      if (oldStyle) {
        child.animateFrom({
          style: oldStyle
        }, animationConfig);
      }
    }
  });
}
function isAllIdSame(oldDiffItems, newDiffItems) {
  var len = oldDiffItems.length;
  if (len !== newDiffItems.length) {
    return false;
  }
  for (var i = 0; i < len; i++) {
    var oldItem = oldDiffItems[i];
    var newItem = newDiffItems[i];
    if (oldItem.data.getId(oldItem.dataIndex) !== newItem.data.getId(newItem.dataIndex)) {
      return false;
    }
  }
  return true;
}
function transitionBetween(oldList, newList, api) {
  var oldDiffItems = flattenDataDiffItems(oldList);
  var newDiffItems = flattenDataDiffItems(newList);
  function updateMorphingPathProps(from, to, rawFrom, rawTo, animationCfg) {
    if (rawFrom || from) {
      to.animateFrom({
        style: rawFrom && rawFrom !== from ? (
          // dividingMethod like clone may override the style(opacity)
          // So extend it to raw style.
          util.extend(util.extend({}, rawFrom.style), from.style)
        ) : from.style
      }, animationCfg);
    }
  }
  function findKeyDim(items) {
    for (var i2 = 0; i2 < items.length; i2++) {
      if (items[i2].dim) {
        return items[i2].dim;
      }
    }
  }
  var oldKeyDim = findKeyDim(oldDiffItems);
  var newKeyDim = findKeyDim(newDiffItems);
  var hasMorphAnimation = false;
  function createKeyGetter(isOld, onlyGetId) {
    return function(diffItem) {
      var data = diffItem.data;
      var dataIndex = diffItem.dataIndex;
      if (onlyGetId) {
        return data.getId(dataIndex);
      }
      var dataGroupId = diffItem.dataGroupId;
      var keyDim = isOld ? oldKeyDim || newKeyDim : newKeyDim || oldKeyDim;
      var dimInfo = keyDim && data.getDimensionInfo(keyDim);
      var dimOrdinalMeta = dimInfo && dimInfo.ordinalMeta;
      if (dimInfo) {
        var key = data.get(dimInfo.name, dataIndex);
        if (dimOrdinalMeta) {
          return dimOrdinalMeta.categories[key] || key + "";
        }
        return key + "";
      }
      var itemVal = data.getRawDataItem(dataIndex);
      if (itemVal && itemVal.groupId) {
        return itemVal.groupId + "";
      }
      return dataGroupId || data.getId(dataIndex);
    };
  }
  var useId = isAllIdSame(oldDiffItems, newDiffItems);
  var isElementStillInChart = {};
  if (!useId) {
    for (var i = 0; i < newDiffItems.length; i++) {
      var newItem = newDiffItems[i];
      var el = newItem.data.getItemGraphicEl(newItem.dataIndex);
      if (el) {
        isElementStillInChart[el.id] = true;
      }
    }
  }
  function updateOneToOne(newIndex, oldIndex) {
    var oldItem = oldDiffItems[oldIndex];
    var newItem2 = newDiffItems[newIndex];
    var newSeries = newItem2.data.hostModel;
    var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
    var newEl = newItem2.data.getItemGraphicEl(newItem2.dataIndex);
    if (oldEl === newEl) {
      newEl && animateElementStyles(newEl, newItem2.dataIndex, newSeries);
      return;
    }
    if (
      // We can't use the elements that already being morphed
      oldEl && isElementStillInChart[oldEl.id]
    ) {
      return;
    }
    if (newEl) {
      stopAnimation(newEl);
      if (oldEl) {
        stopAnimation(oldEl);
        removeEl(oldEl);
        hasMorphAnimation = true;
        morphTransitionHelper.applyMorphAnimation(morphTransitionHelper.getPathList(oldEl), morphTransitionHelper.getPathList(newEl), newItem2.divide, newSeries, newIndex, updateMorphingPathProps);
      } else {
        fadeInElement(newEl, newSeries, newIndex);
      }
    }
  }
  new DataDiffer.default(oldDiffItems, newDiffItems, createKeyGetter(true, useId), createKeyGetter(false, useId), null, "multiple").update(updateOneToOne).updateManyToOne(function(newIndex, oldIndices) {
    var newItem2 = newDiffItems[newIndex];
    var newData = newItem2.data;
    var newSeries = newData.hostModel;
    var newEl = newData.getItemGraphicEl(newItem2.dataIndex);
    var oldElsList = util.filter(util.map(oldIndices, function(idx) {
      return oldDiffItems[idx].data.getItemGraphicEl(oldDiffItems[idx].dataIndex);
    }), function(oldEl) {
      return oldEl && oldEl !== newEl && !isElementStillInChart[oldEl.id];
    });
    if (newEl) {
      stopAnimation(newEl);
      if (oldElsList.length) {
        util.each(oldElsList, function(oldEl) {
          stopAnimation(oldEl);
          removeEl(oldEl);
        });
        hasMorphAnimation = true;
        morphTransitionHelper.applyMorphAnimation(morphTransitionHelper.getPathList(oldElsList), morphTransitionHelper.getPathList(newEl), newItem2.divide, newSeries, newIndex, updateMorphingPathProps);
      } else {
        fadeInElement(newEl, newSeries, newItem2.dataIndex);
      }
    }
  }).updateOneToMany(function(newIndices, oldIndex) {
    var oldItem = oldDiffItems[oldIndex];
    var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
    if (oldEl && isElementStillInChart[oldEl.id]) {
      return;
    }
    var newElsList = util.filter(util.map(newIndices, function(idx) {
      return newDiffItems[idx].data.getItemGraphicEl(newDiffItems[idx].dataIndex);
    }), function(el2) {
      return el2 && el2 !== oldEl;
    });
    var newSeris = newDiffItems[newIndices[0]].data.hostModel;
    if (newElsList.length) {
      util.each(newElsList, function(newEl) {
        return stopAnimation(newEl);
      });
      if (oldEl) {
        stopAnimation(oldEl);
        removeEl(oldEl);
        hasMorphAnimation = true;
        morphTransitionHelper.applyMorphAnimation(
          morphTransitionHelper.getPathList(oldEl),
          morphTransitionHelper.getPathList(newElsList),
          oldItem.divide,
          // Use divide on old.
          newSeris,
          newIndices[0],
          updateMorphingPathProps
        );
      } else {
        util.each(newElsList, function(newEl) {
          return fadeInElement(newEl, newSeris, newIndices[0]);
        });
      }
    }
  }).updateManyToMany(function(newIndices, oldIndices) {
    new DataDiffer.default(oldIndices, newIndices, function(rawIdx) {
      return oldDiffItems[rawIdx].data.getId(oldDiffItems[rawIdx].dataIndex);
    }, function(rawIdx) {
      return newDiffItems[rawIdx].data.getId(newDiffItems[rawIdx].dataIndex);
    }).update(function(newIndex, oldIndex) {
      updateOneToOne(newIndices[newIndex], oldIndices[oldIndex]);
    }).execute();
  }).execute();
  if (hasMorphAnimation) {
    util.each(newList, function(_a) {
      var data = _a.data;
      var seriesModel = data.hostModel;
      var view = seriesModel && api.getViewOfSeriesModel(seriesModel);
      var animationCfg = basicTransition.getAnimationConfig("update", seriesModel, 0);
      if (view && seriesModel.isAnimationEnabled() && animationCfg && animationCfg.duration > 0) {
        view.group.traverse(function(el2) {
          if (el2 instanceof Path.default && !el2.animators.length) {
            el2.animateFrom({
              style: {
                opacity: 0
              }
            }, animationCfg);
          }
        });
      }
    });
  }
}
function getSeriesTransitionKey(series) {
  var seriesKey = series.getModel("universalTransition").get("seriesKey");
  if (!seriesKey) {
    return series.id;
  }
  return seriesKey;
}
function convertArraySeriesKeyToString(seriesKey) {
  if (util.isArray(seriesKey)) {
    return seriesKey.sort().join(",");
  }
  return seriesKey;
}
function getDivideShapeFromData(data) {
  if (data.hostModel) {
    return data.hostModel.getModel("universalTransition").get("divideShape");
  }
}
function findTransitionSeriesBatches(globalStore, params) {
  var updateBatches = util.createHashMap();
  var oldDataMap = util.createHashMap();
  var oldDataMapForSplit = util.createHashMap();
  util.each(globalStore.oldSeries, function(series, idx) {
    var oldDataGroupId = globalStore.oldDataGroupIds[idx];
    var oldData = globalStore.oldData[idx];
    var transitionKey = getSeriesTransitionKey(series);
    var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
    oldDataMap.set(transitionKeyStr, {
      dataGroupId: oldDataGroupId,
      data: oldData
    });
    if (util.isArray(transitionKey)) {
      util.each(transitionKey, function(key) {
        oldDataMapForSplit.set(key, {
          key: transitionKeyStr,
          dataGroupId: oldDataGroupId,
          data: oldData
        });
      });
    }
  });
  function checkTransitionSeriesKeyDuplicated(transitionKeyStr) {
    if (updateBatches.get(transitionKeyStr)) {
      log.warn("Duplicated seriesKey in universalTransition " + transitionKeyStr);
    }
  }
  util.each(params.updatedSeries, function(series) {
    if (series.isUniversalTransitionEnabled() && series.isAnimationEnabled()) {
      var newDataGroupId = series.get("dataGroupId");
      var newData = series.getData();
      var transitionKey = getSeriesTransitionKey(series);
      var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
      var oldData = oldDataMap.get(transitionKeyStr);
      if (oldData) {
        if (process.env.NODE_ENV !== "production") {
          checkTransitionSeriesKeyDuplicated(transitionKeyStr);
        }
        updateBatches.set(transitionKeyStr, {
          oldSeries: [{
            dataGroupId: oldData.dataGroupId,
            divide: getDivideShapeFromData(oldData.data),
            data: oldData.data
          }],
          newSeries: [{
            dataGroupId: newDataGroupId,
            divide: getDivideShapeFromData(newData),
            data: newData
          }]
        });
      } else {
        if (util.isArray(transitionKey)) {
          if (process.env.NODE_ENV !== "production") {
            checkTransitionSeriesKeyDuplicated(transitionKeyStr);
          }
          var oldSeries_1 = [];
          util.each(transitionKey, function(key) {
            var oldData2 = oldDataMap.get(key);
            if (oldData2.data) {
              oldSeries_1.push({
                dataGroupId: oldData2.dataGroupId,
                divide: getDivideShapeFromData(oldData2.data),
                data: oldData2.data
              });
            }
          });
          if (oldSeries_1.length) {
            updateBatches.set(transitionKeyStr, {
              oldSeries: oldSeries_1,
              newSeries: [{
                dataGroupId: newDataGroupId,
                data: newData,
                divide: getDivideShapeFromData(newData)
              }]
            });
          }
        } else {
          var oldData_1 = oldDataMapForSplit.get(transitionKey);
          if (oldData_1) {
            var batch = updateBatches.get(oldData_1.key);
            if (!batch) {
              batch = {
                oldSeries: [{
                  dataGroupId: oldData_1.dataGroupId,
                  data: oldData_1.data,
                  divide: getDivideShapeFromData(oldData_1.data)
                }],
                newSeries: []
              };
              updateBatches.set(oldData_1.key, batch);
            }
            batch.newSeries.push({
              dataGroupId: newDataGroupId,
              data: newData,
              divide: getDivideShapeFromData(newData)
            });
          }
        }
      }
    }
  });
  return updateBatches;
}
function querySeries(series, finder) {
  for (var i = 0; i < series.length; i++) {
    var found = finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id;
    if (found) {
      return i;
    }
  }
}
function transitionSeriesFromOpt(transitionOpt, globalStore, params, api) {
  var from = [];
  var to = [];
  util.each(model.normalizeToArray(transitionOpt.from), function(finder) {
    var idx = querySeries(globalStore.oldSeries, finder);
    if (idx >= 0) {
      from.push({
        dataGroupId: globalStore.oldDataGroupIds[idx],
        data: globalStore.oldData[idx],
        // TODO can specify divideShape in transition.
        divide: getDivideShapeFromData(globalStore.oldData[idx]),
        dim: finder.dimension
      });
    }
  });
  util.each(model.normalizeToArray(transitionOpt.to), function(finder) {
    var idx = querySeries(params.updatedSeries, finder);
    if (idx >= 0) {
      var data = params.updatedSeries[idx].getData();
      to.push({
        dataGroupId: globalStore.oldDataGroupIds[idx],
        data,
        divide: getDivideShapeFromData(data),
        dim: finder.dimension
      });
    }
  });
  if (from.length > 0 && to.length > 0) {
    transitionBetween(from, to, api);
  }
}
function installUniversalTransition(registers) {
  registers.registerUpdateLifecycle("series:beforeupdate", function(ecMOdel, api, params) {
    util.each(model.normalizeToArray(params.seriesTransition), function(transOpt) {
      util.each(model.normalizeToArray(transOpt.to), function(finder) {
        var series = params.updatedSeries;
        for (var i = 0; i < series.length; i++) {
          if (finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id) {
            series[i][Series.SERIES_UNIVERSAL_TRANSITION_PROP] = true;
          }
        }
      });
    });
  });
  registers.registerUpdateLifecycle("series:transition", function(ecModel, api, params) {
    var globalStore = getUniversalTransitionGlobalStore(api);
    if (globalStore.oldSeries && params.updatedSeries && params.optionChanged) {
      var transitionOpt = params.seriesTransition;
      if (transitionOpt) {
        util.each(model.normalizeToArray(transitionOpt), function(opt) {
          transitionSeriesFromOpt(opt, globalStore, params, api);
        });
      } else {
        var updateBatches_1 = findTransitionSeriesBatches(globalStore, params);
        util.each(updateBatches_1.keys(), function(key) {
          var batch = updateBatches_1.get(key);
          transitionBetween(batch.oldSeries, batch.newSeries, api);
        });
      }
      util.each(params.updatedSeries, function(series) {
        if (series[Series.SERIES_UNIVERSAL_TRANSITION_PROP]) {
          series[Series.SERIES_UNIVERSAL_TRANSITION_PROP] = false;
        }
      });
    }
    var allSeries = ecModel.getSeries();
    var savedSeries = globalStore.oldSeries = [];
    var savedDataGroupIds = globalStore.oldDataGroupIds = [];
    var savedData = globalStore.oldData = [];
    for (var i = 0; i < allSeries.length; i++) {
      var data = allSeries[i].getData();
      if (data.count() < DATA_COUNT_THRESHOLD) {
        savedSeries.push(allSeries[i]);
        savedDataGroupIds.push(allSeries[i].get("dataGroupId"));
        savedData.push(data);
      }
    }
  });
}
exports.installUniversalTransition = installUniversalTransition;
