'use strict';

const log = require('./global-slimmer-registry-7bbdb1f2.js');
const number = require('./number-4816603d.js');

const BASE_BASIC_Z_INDEX = 10000;
const TOP_BASIC_Z_INDEX = 11000;
/**
 * Base level is for custom element such as modal, tooltip, dropdown, sidenav and header.
 * 	the z-index of current showing element is highly than already show.
 * Top level is for element that always display to top, such as notification.
 */
class InternalVegaZIndexManager {
  constructor() {
    this.baseBasicZIndex = BASE_BASIC_Z_INDEX;
    this.topBasicZIndex = TOP_BASIC_Z_INDEX;
    this.levelEntry = {
      base: {
        zIndex: this.baseBasicZIndex,
        elements: [],
      },
      top: {
        zIndex: this.topBasicZIndex,
        elements: [],
      },
    };
  }
  /**
   * "If the element is not already the current element, then increment the z-index and set the element
   * to the current element."
   *
   * The function is a little more complicated than that, but not much. The function takes an element and
   * a level. The level is optional and defaults to 'base'. The level is used to keep track of the
   * z-index for each level. The function uses a private variable, levelStatus, to keep track of the
   * current element and z-index for each level
   *
   * @param {HTMLElement} element - The element to set the z-index of.
   * @param {ZIndexLevelType} [level=base] - The level of the element.
   * @returns {void}
   */
  setZIndex(element, level = 'base') {
    if (element === null)
      return;
    this.removeZIndex(element, level);
    const zIndexEntry = this.levelEntry[level];
    if (element && zIndexEntry) {
      if (level === 'base' && this.isBaseLevelOver()) {
        log.LogUtility.warn(`The max 'z-index' of base level is '11000', but the current 'z-index' is over, Please optimize the use of 'z-index', otherwise there will be some performance overhead.`);
        this.increaseTopEntry();
      }
      zIndexEntry.elements.push(element);
      zIndexEntry.zIndex += 1;
      element.style.zIndex = zIndexEntry.zIndex.toString();
    }
  }
  /**
   * It removes the element from the level's array of elements, and then decrements the z-index of all
   * elements after the removed element
   *
   * @param {HTMLElement} element - HTMLElement - The element to move
   * @param {ZIndexLevelType} [level=base] - Level = 'base'
   * @returns {void}
   */
  removeZIndex(element, level = 'base') {
    if (element === null)
      return;
    const zIndexEntry = this.levelEntry[level];
    if (element && zIndexEntry) {
      let startAt = -1;
      zIndexEntry.elements.forEach((e, index) => {
        if (e === element)
          startAt = index;
        if (startAt >= 0 && index > startAt) {
          e.style.zIndex = `${number.convertToNumber(e.style.zIndex) - 1}`;
        }
      });
      if (startAt >= 0) {
        element.style.removeProperty('z-index');
        zIndexEntry.elements.splice(startAt, 1);
        zIndexEntry.zIndex -= 1;
      }
    }
  }
  /**
   * The function "overrideZIndexBasicValues" updates the base and top basic z-index values based on the
   * input provided.
   *
   * @param {ZIndexBasicValues} input - The input parameter is of type ZIndexBasicValues, which is an
   * object with two properties: base and top. Both properties are optional and can be either a number or
   * undefined.
   */
  overrideZIndexBasicValues(input) {
    const basicValues = this.formatZIndexBasicValues(input);
    if (this.validBasicValues(basicValues)) {
      this.updateBasicValues(basicValues);
    }
  }
  /**
   * The function `formatZIndexBasicValues` takes an input object and returns a new object with additional
   * properties `base` and `top` added to it.
   *
   * @param {ZIndexBasicValues} input - The input parameter is of type ZIndexBasicValues. It is an object
   * that contains properties for base and top.
   * @returns {ZIndexBasicValues} - an object that combines the properties of the input object `input` with the properties
   * `base` and `top`. The values of `base` and `top` are taken from the `this.baseBasicZIndex` and
   * `this.topBasicZIndex` variables respectively.
   */
  formatZIndexBasicValues(input) {
    return Object.assign({
      base: this.baseBasicZIndex,
      top: this.topBasicZIndex,
    }, input);
  }
  /**
   * The function checks if the input values for base and top levels of a z-index are valid.
   *
   * @param {ZIndexBasicValues} input - The input parameter is an object of type ZIndexBasicValues. It
   * has two properties: base and top. Both properties should be of type number.
   * @returns {boolean} a boolean value.
   */
  validBasicValues(input) {
    if (typeof input.base !== 'number' || typeof input.top !== 'number') {
      log.LogUtility.error('Change z-index basic value failed, both base level and top level should be of type number!');
      return false;
    }
    else if (input.base >= input.top) {
      log.LogUtility.error('Change z-index basic value failed, the base level should be smaller than the top level!');
      return false;
    }
    return true;
  }
  /**
   * The function updates the z-index values of elements based on the input values.
   *
   * @param {ZIndexBasicValues} input - The input parameter is an object of type ZIndexBasicValues. It
   * has two properties: base and top, both of which are optional and can be of type number.
   */
  updateBasicValues(input) {
    // update basic z-index value
    this.baseBasicZIndex = input.base;
    this.topBasicZIndex = input.top;
    // update base level entry
    const baseLevel = this.levelEntry.base;
    baseLevel.elements.forEach((element, index) => {
      element.style.zIndex = `${this.baseBasicZIndex + index + 1}`;
    });
    baseLevel.zIndex = this.baseBasicZIndex + baseLevel.elements.length;
    // update top level entry
    const topLevel = this.levelEntry.top;
    topLevel.elements.forEach((element, index) => {
      element.style.zIndex = `${this.topBasicZIndex + index + 1}`;
    });
    topLevel.zIndex = this.topBasicZIndex + topLevel.elements.length;
  }
  /**
   * It increases the z-index of all the elements in the top entry by 1
   *
   * @returns {void}
   */
  increaseTopEntry() {
    const topEntry = this.levelEntry['top'];
    topEntry.elements.forEach((element) => {
      element.style.zIndex = `${number.convertToNumber(element.style.zIndex) + 1}`;
    });
    topEntry.zIndex += 1;
  }
  /**
   * If the z-index of the level is over 1000 greater than the basic z-index of the level, then return
   * true.
   *
   * @returns {boolean} - The zIndexEntry.zIndex - this.getBasicZIndexByLevel(level) >= 1000 is being returned.
   */
  isBaseLevelOver() {
    const baseEntry = this.levelEntry['base'];
    return baseEntry.zIndex >= this.topBasicZIndex;
  }
}
const InternalVegaZIndexManager$1 = new InternalVegaZIndexManager();

exports.InternalVegaZIndexManager = InternalVegaZIndexManager$1;
