import { toFunction as i, Controller as n } from "@arcgis/lumina/controllers";
/*! All material copyright GeoScene, All Rights Reserved, unless otherwise specified.
See https://js.geoscene.cn/4.33/geoscene/copyright.txt for details.
v4.33.18 */
class o {
  constructor() {
    this._groups = /* @__PURE__ */ new Map();
  }
  /**
   * A handle to a [highlight](https://next.gha.afd.geoscene.cn/javascript/latest/api-reference/geoscene-views-layers-FeatureLayerView.html#highlight) call result.
   * The handle can be used to remove the installed highlight.
   *
   * @typedef module:geoscene/core/Handles~Handle
   *
   * @property {Function} remove - Removes the handle.
   */
  //--------------------------------------------------------------------------
  //
  //  Lifecycle
  //
  //--------------------------------------------------------------------------
  /**
   * Destroys the object, removing all the handles.
   *
   * @method destroy
   * @instance
   *
   * @example
   * let handles = new Handles();
   *
   * handles.add(reactiveUtils.when(
   *   () => !view.updating,
   *   () => {
   *     wkidSelect.disabled = false;
   *   },
   *   { once: true }
   * ));
   *
   * handles.destroy();
   */
  destroy() {
    this.removeAll();
  }
  //--------------------------------------------------------------------------
  //
  //  Public Methods
  //
  //--------------------------------------------------------------------------
  /**
   * Adds a group of handles.
   *
   * @method add
   * @param {module:geoscene/core/Accessor~WatchHandle | module:geoscene/core/Accessor~WatchHandle[] | module:geoscene/core/Collection<module:geoscene/core/Accessor~WatchHandle>} handles - An array or collection handles to group.
   * @param {*} [groupKey]
   *    Key identifying the group to which the handles should be added. All the handles in the group
   *    can later be removed with [Handles.remove()](https://next.gha.afd.geoscene.cn/javascript/latest/api-reference/geoscene-core-Handles.html#remove). If no
   *    key is provided the handles are added to a default group.
   *
   * @example
   * let handles = new Handles();
   *
   * handles.add(handle); // added to the default group
   * handles.add([handle1, handle2]); // added to the default group
   *
   * handles.add(handle, "handle-group");
   * handles.add([handle1, handle2], "other-handle-group");
   * @example
   * let handles = new Handles();
   *
   * handles.add(reactiveUtils.when(
   *   () => !view.updating,
   *   () => {
   *     wkidSelect.disabled = false;
   *   },
   *   { once: true }
   * ));
   * @instance
   */
  add(e, s) {
    if (Array.isArray(e)) {
      const r = this._getOrCreateGroup(s);
      for (const t of e)
        this._isHandle(t) && r.push(t);
    } else this._isHandle(e) && this._getOrCreateGroup(s).push(e);
    return this;
  }
  forEach(e, s) {
    if (typeof e == "function")
      this._groups.forEach((r) => r.forEach(e));
    else {
      const r = this._getGroup(e);
      r && s && r.forEach(s);
    }
  }
  /**
   * Returns true if a group exists for the provided group key, false otherwise.
   *
   * @method has
   * @instance
   * @param {*} groupKey - group handle key
   * @return {boolean}
   */
  has(e) {
    return this._groups.has(this._ensureGroupKey(e));
  }
  /**
   * Removes a group of handles.
   *
   * @method remove
   * @instance
   * @param {*} [groupKey] - A group key or an array or collection of group keys to remove.
   *
   * @example
   * let handles = new Handles();
   *
   * handles.remove(); // removes handles from default group
   *
   * handles.remove("handle-group");
   * handles.remove("other-handle-group");
   */
  remove(e) {
    if (typeof e != "string" && Array.isArray(e)) {
      for (const s of e)
        this.remove(s);
      return this;
    }
    return this.has(e) ? (this._removeAllFromGroup(this._getGroup(e)), this._groups.delete(this._ensureGroupKey(e)), this) : this;
  }
  /**
   * Removes all handles.
   *
   * @method removeAll
   * @instance
   */
  removeAll() {
    return this._groups.forEach((e) => this._removeAllFromGroup(e)), this._groups.clear(), this;
  }
  //--------------------------------------------------------------------------
  //
  //  Private Methods
  //
  //--------------------------------------------------------------------------
  _isHandle(e) {
    return e && (!!e.remove || e instanceof o);
  }
  _getOrCreateGroup(e) {
    if (this.has(e))
      return this._getGroup(e);
    const s = [];
    return this._groups.set(this._ensureGroupKey(e), s), s;
  }
  _getGroup(e) {
    return this._groups.get(this._ensureGroupKey(e));
  }
  _ensureGroupKey(e) {
    return e || "_default_";
  }
  _removeAllFromGroup(e) {
    for (const s of e)
      s instanceof o ? s.removeAll() : s.remove();
  }
}
class h extends n {
  constructor(e) {
    super(), this.destroyed = !1, e === "disconnect" ? this.onDisconnected(() => this.removeAllHandles()) : this.onDestroy(() => this.destroy());
  }
  /**
   * Adds one or more handles which are to be tied to the lifecycle of the object. The handles will
   * be removed when the object is destroyed.
   *
   * ```js
   * // Manually manage handles
   * const handle = reactiveUtils.when(
   *   () => !view.updating,
   *   () => {
   *     wkidSelect.disabled = false;
   *   },
   *   { once: true }
   * );
   *
   * this.addHandles(handle);
   *
   * // Destroy the object
   * this.destroy();
   * ```
   *
   * @method addHandles
   * @since 4.25
   * @instance
   * @param {module:geoscene/core/Accessor~WatchHandle | module:geoscene/core/Accessor~WatchHandle[]} handleOrHandles
   *    Handles marked for removal once the object is destroyed.
   * @param {*} [groupKey]
   *    Key identifying the group to which the handles should be added. All the handles in the group
   *    can later be removed with [Accessor.removeHandles()](https://next.gha.afd.geoscene.cn/javascript/latest/api-reference/geoscene-core-Accessor.html#removeHandles).
   *    If no key is provided the handles are added to a default group.
   */
  addHandles(e, s) {
    if (this.destroyed) {
      const r = Array.isArray(e) ? e : [e];
      for (const t of r)
        t.remove();
      return;
    }
    this._handles ??= new o(), this._handles.add(e, s);
  }
  /**
   * Removes a group of handles owned by the object.
   *
   * @method removeHandles
   * @since 4.25
   * @instance
   * @param {*} [groupKey] - A group key or an array or collection of group keys to remove.
   *
   * @example
   * obj.removeHandles(); // removes handles from default group
   *
   * obj.removeHandles("handle-group");
   * obj.removeHandles("other-handle-group");
   */
  removeHandles(e) {
    this._handles?.remove(e);
  }
  /**
   * Removes all the handles currently associated with the object.
   *
   * @private
   */
  removeAllHandles() {
    this._handles?.removeAll();
  }
  destroy() {
    this.destroyed = !0, this.removeAllHandles();
  }
  /**
   * Returns true if a named group of handles exist.
   *
   * @method hasHandles
   * @since 4.25
   * @instance
   * @param {*} [groupKey] - A group key.
   * @return {boolean} Returns `true` if a named group of handles exist.
   *
   * @example
   * // Remove a named group of handles if they exist.
   * if (obj.hasHandles("watch-view-updates")) {
   *   obj.removeHandles("watch-view-updates");
   * }
   */
  hasHandles(e) {
    return this._handles?.has(e) ?? !1;
  }
}
const l = i(h);
export {
  l as u
};