import {CoreGraphNode as CoreGraphNode2} from "../../core/graph/CoreGraphNode";
import {UIData as UIData2} from "./utils/UIData";
import {FlagsControllerD} from "./utils/FlagsController";
import {StatesController as StatesController2} from "./utils/StatesController";
import {HierarchyParentController} from "./utils/hierarchy/ParentController";
import {HierarchyChildrenController} from "./utils/hierarchy/ChildrenController";
import {LifeCycleController as LifeCycleController2} from "./utils/LifeCycleController";
import {TypedContainerController} from "./utils/ContainerController";
import {NodeCookController} from "./utils/CookController";
import {NameController as NameController2} from "./utils/NameController";
import {NodeSerializer} from "./utils/Serializer";
import {ParamsController as ParamsController2} from "./utils/params/ParamsController";
import {ParamsValueAccessor as ParamsValueAccessor2} from "./utils/params/ParamsValueAccessor";
import {IOController as IOController2} from "./utils/io/IOController";
import {ParamsAccessor as ParamsAccessor2} from "./utils/params/ParamsAccessor";
export class TypedNode extends CoreGraphNode2 {
  constructor(scene, name = "BaseNode", params_init_value_overrides) {
    super(scene, name);
    this.params_init_value_overrides = params_init_value_overrides;
    this.container_controller = new TypedContainerController(this);
    this.pv = new ParamsValueAccessor2();
    this.p = new ParamsAccessor2();
    this._initialized = false;
  }
  copy_param_values(node) {
    const non_spare = this.params.non_spare;
    for (let param of non_spare) {
      const other_param = node.params.get(param.name());
      if (other_param) {
        param.copy_value(other_param);
      }
    }
  }
  get parentController() {
    return this._parent_controller = this._parent_controller || new HierarchyParentController(this);
  }
  static displayedInputNames() {
    return [];
  }
  get childrenControllerContext() {
    return this._children_controller_context;
  }
  _create_children_controller() {
    if (this._children_controller_context) {
      return new HierarchyChildrenController(this, this._children_controller_context);
    }
  }
  get childrenController() {
    return this._children_controller = this._children_controller || this._create_children_controller();
  }
  childrenAllowed() {
    return this._children_controller_context != null;
  }
  get uiData() {
    return this._ui_data = this._ui_data || new UIData2(this);
  }
  get states() {
    return this._states = this._states || new StatesController2(this);
  }
  get lifecycle() {
    return this._lifecycle = this._lifecycle || new LifeCycleController2(this);
  }
  get serializer() {
    return this._serializer = this._serializer || new NodeSerializer(this);
  }
  get cookController() {
    return this._cook_controller = this._cook_controller || new NodeCookController(this);
  }
  get io() {
    return this._io = this._io || new IOController2(this);
  }
  get nameController() {
    return this._name_controller = this._name_controller || new NameController2(this);
  }
  setName(name) {
    this.nameController.setName(name);
  }
  _set_core_name(name) {
    this._name = name;
  }
  get params() {
    return this._params_controller = this._params_controller || new ParamsController2(this);
  }
  initialize_base_and_node() {
    if (!this._initialized) {
      this._initialized = true;
      this.display_node_controller?.initializeNode();
      this.initializeBaseNode();
      this.initializeNode();
      if (this.polyNodeController) {
        this.polyNodeController.initializeNode();
      }
    } else {
      console.warn("node already initialized");
    }
  }
  initializeBaseNode() {
  }
  initializeNode() {
  }
  static type() {
    throw "type to be overriden";
  }
  type() {
    const c = this.constructor;
    return c.type();
  }
  static nodeContext() {
    console.error("node has no node_context", this);
    throw "node_context requires override";
  }
  nodeContext() {
    const c = this.constructor;
    return c.nodeContext();
  }
  static require_webgl2() {
    return false;
  }
  require_webgl2() {
    const c = this.constructor;
    return c.require_webgl2();
  }
  setParent(parent) {
    this.parentController.setParent(parent);
  }
  parent() {
    return this.parentController.parent();
  }
  root() {
    return this._scene.root();
  }
  fullPath(relative_to_parent) {
    return this.parentController.fullPath(relative_to_parent);
  }
  create_params() {
  }
  addParam(type, name, default_value, options) {
    return this._params_controller?.addParam(type, name, default_value, options);
  }
  param_default_value(name) {
    return null;
  }
  cook(input_contents) {
    return null;
  }
  async requestContainer() {
    if (!this.isDirty()) {
      return this.container_controller.container;
    } else {
      return await this.container_controller.requestContainer();
    }
  }
  setContainer(content, message = null) {
    this.container_controller.container.set_content(content);
    if (content != null) {
      if (!content.name) {
        content.name = this.fullPath();
      }
      if (!content.node) {
        content.node = this;
      }
    }
    this.cookController.end_cook(message);
  }
  createNode(node_class, params_init_value_overrides) {
    return this.childrenController?.createNode(node_class, params_init_value_overrides);
  }
  create_operation_container(type, operation_container_name, params_init_value_overrides) {
    return this.childrenController?.create_operation_container(type, operation_container_name, params_init_value_overrides);
  }
  removeNode(node) {
    this.childrenController?.removeNode(node);
  }
  dispose() {
    super.dispose();
    this.setParent(null);
    this.io.inputs.dispose();
    this.lifecycle.dispose();
    this.display_node_controller?.dispose();
    this.nameController.dispose();
    this.childrenController?.dispose();
    this.params.dispose();
  }
  children() {
    return this.childrenController?.children() || [];
  }
  node(path) {
    return this.parentController?.find_node(path) || null;
  }
  nodeSibbling(name) {
    const parent = this.parent();
    if (parent) {
      const node = parent.childrenController?.child_by_name(name);
      if (node) {
        return node;
      }
    }
    return null;
  }
  nodesByType(type) {
    return this.childrenController?.nodesByType(type) || [];
  }
  setInput(input_index_or_name, node, output_index_or_name = 0) {
    this.io.inputs.setInput(input_index_or_name, node, output_index_or_name);
  }
  emit(event_name, data = null) {
    this.scene().dispatchController.dispatch(this, event_name, data);
  }
  toJSON(include_param_components = false) {
    return this.serializer.toJSON(include_param_components);
  }
  async requiredModules() {
  }
  usedAssembler() {
  }
  integrationData() {
  }
}
export class BaseNodeClass extends TypedNode {
}
export class BaseNodeClassWithDisplayFlag extends TypedNode {
  constructor() {
    super(...arguments);
    this.flags = new FlagsControllerD(this);
  }
}
