"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var ClusterBehavior_exports = {};
__export(ClusterBehavior_exports, {
  ClusterBehavior: () => ClusterBehavior
});
module.exports = __toCommonJS(ClusterBehavior_exports);
var import_general = require("#general");
var import_types = require("#types");
var import_Behavior = require("../Behavior.js");
var import_NetworkBehavior = require("../system/network/NetworkBehavior.js");
var import_ClusterBehaviorUtil = require("./ClusterBehaviorUtil.js");
var import_ClusterInterface = require("./ClusterInterface.js");
/**
 * @license
 * Copyright 2022-2024 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class ClusterBehavior extends import_Behavior.Behavior {
  /**
   * The ID of ClusterBehavior implementations is the uncapitalized cluster name.
   */
  static id;
  /**
   * The cluster implemented by this behavior.
   */
  get cluster() {
    return this.constructor.cluster;
  }
  /**
   * Supported features as a flag object.
   */
  get features() {
    return this.cluster.supportedFeatures;
  }
  /**
   * Every cluster behavior has an associated ClusterType defined statically.
   */
  static cluster = import_types.ClusterType.Unknown;
  /**
   * Method definitions.
   */
  static Interface = import_ClusterInterface.ClusterInterface.Empty;
  /**
   * All ClusterBehavior initialization currently runs as part of {@link Endpoint} initialization.
   */
  static early = true;
  /**
   * Keep networking alive until I'm destroyed.
   */
  static dependencies = [import_NetworkBehavior.NetworkBehavior];
  constructor(agent, backing) {
    super(agent, backing);
    const cluster = this.constructor.cluster;
    if (!cluster) {
      throw new import_general.ImplementationError("ClusterBehavior class has no cluster defined");
    }
  }
  /**
   * Create a new behavior for a specific {@link ClusterType}.
   *
   * If you invoke directly on {@link ClusterBehavior} you will receive a new implementation that reports all commands
   * as unimplemented.
   *
   * If you invoke on an existing subclass, you will receive a new implementation with the cluster in the subclass
   * replaced.  You should generally only do this with a {@link ClusterType} with the same ID.
   */
  static for(cluster, schema) {
    return (0, import_ClusterBehaviorUtil.createType)(cluster, this, schema);
  }
  /**
   * Create a new behavior with different cluster features.
   */
  static with(...features) {
    const newCluster = new import_types.ClusterComposer(this.cluster).compose(features);
    return this.for(newCluster);
  }
  /**
   * Create a new behavior with modified cluster elements.
   */
  static alter(alterations) {
    return this.for(new import_types.ElementModifier(this.cluster).alter(alterations));
  }
  /**
   * Create a new behavior with additional cluster features marked "mandatory".
   *
   * This informs matter.js that an application supports these elements.
   */
  static enable(flags) {
    return this.for(new import_types.ElementModifier(this.cluster).enable(flags));
  }
  /**
   * Create a ClusterBehavior like this one with different interface methods.
   *
   * The Interface "property" is type-only.  We define a method however to keep the API consistent.  At runtime the
   * method is a no-op.
   */
  static withInterface() {
    return this;
  }
  static supports(other) {
    if (!import_Behavior.Behavior.supports.call(this, other)) {
      return false;
    }
    const otherCluster = other.cluster;
    if (!otherCluster) {
      return false;
    }
    const otherFeatures = otherCluster.supportedFeatures;
    const myFeatures = this.cluster.supportedFeatures;
    for (const name in otherFeatures) {
      if (otherFeatures[name] && !myFeatures[name]) {
        return false;
      }
    }
    return true;
  }
  requireAttributeEnabled(attributeName) {
    if (this.state[attributeName] === void 0) {
      throw new import_general.ImplementationError(
        `To use this feature, please enable attribute ${String(attributeName)} by setting the value during initialization.`
      );
    }
    return this.state[attributeName];
  }
  assertAttributeEnabled(attributeName) {
    if (this.state[attributeName] === void 0) {
      throw new import_general.ImplementationError(
        `To use this feature, please enable attribute ${String(attributeName)} by setting the value during initialization.`
      );
    }
  }
}
((ClusterBehavior2) => {
  class Events extends import_general.EventEmitter {
    /**
     * Emitted when state associated with this behavior is first mutated by a specific interaction.
     */
    interactionBegin = (0, import_general.Observable)();
    /**
     * Emitted when a mutating interaction completes.
     */
    interactionEnd = (0, import_general.AsyncObservable)();
  }
  ClusterBehavior2.Events = Events;
})(ClusterBehavior || (ClusterBehavior = {}));
//# sourceMappingURL=ClusterBehavior.js.map
