/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { InvalidMetadataError, MetadataConflictError } from "#decoration/errors.js";
import { Semantics } from "#decoration/semantics/Semantics.js";
import { Decorator } from "#general";
import { Model } from "#models/Model.js";
import { Schema } from "#models/Schema.js";
function element(kind, ...modifiers) {
  const forceType = !(modifiers[0] instanceof kind);
  return Decorator((target, context) => {
    const semantics = Semantics.of(context);
    if (forceType) {
      semantics.modelType = kind;
    }
    if (context.kind === "class") {
      semantics.new = target;
    }
    let result = void 0;
    for (const modifier of modifiers) {
      switch (typeof modifier) {
        case "number":
          semantics.mutableModel.id = modifier;
          continue;
        case "string":
          semantics.mutableModel.name = modifier;
          continue;
        case "function":
          if ("Tag" in modifier) {
            semantics.modelType = modifier;
          } else if (Decorator.is(modifier)) {
            const subresult = modifier(target, context);
            if (subresult) {
              if (result) {
                throw new MetadataConflictError(`Multiple modifiers returned a value`);
              }
              result = subresult;
            }
          } else {
            const model = Schema(modifier);
            if (model === void 0) {
              throw new InvalidMetadataError(
                `Cannot use undecorated class ${modifier.name || "(anonymous)"} as type for ${String(context.name || "(anonymous)")}`
              );
            }
            model.finalize();
            semantics.mutableModel = model;
          }
          continue;
        case "object":
          if (modifier instanceof Model) {
            semantics.mutableModel = modifier;
            continue;
          }
          break;
      }
      throw new InvalidMetadataError(`Unsupported modifier ${modifier}`);
    }
    return result;
  });
}
((element2) => {
  function property(kind) {
    return (...modifiers) => {
      return element2(kind, ...modifiers);
    };
  }
  element2.property = property;
  function klass(kind) {
    return (...modifiers) => {
      return element2(kind, ...modifiers);
    };
  }
  element2.klass = klass;
})(element || (element = {}));
export {
  element
};
//# sourceMappingURL=element.js.map
