import {TypedObjNode} from "./_Base";
import {Scene as Scene2} from "three/src/scenes/Scene";
import {Fog as Fog2} from "three/src/scenes/Fog";
import {FogExp2 as FogExp22} from "three/src/scenes/FogExp2";
import {NodeContext as NodeContext2} from "../../poly/NodeContext";
import {HierarchyController as HierarchyController2} from "./utils/HierarchyController";
var BackgroundMode;
(function(BackgroundMode2) {
  BackgroundMode2["NONE"] = "none";
  BackgroundMode2["COLOR"] = "color";
  BackgroundMode2["TEXTURE"] = "texture";
})(BackgroundMode || (BackgroundMode = {}));
const BACKGROUND_MODES = [BackgroundMode.NONE, BackgroundMode.COLOR, BackgroundMode.TEXTURE];
var FogType;
(function(FogType2) {
  FogType2["LINEAR"] = "linear";
  FogType2["EXPONENTIAL"] = "exponential";
})(FogType || (FogType = {}));
const FOG_TYPES = [FogType.LINEAR, FogType.EXPONENTIAL];
import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig";
class SceneObjParamConfig extends NodeParamsConfig {
  constructor() {
    super(...arguments);
    this.autoUpdate = ParamConfig.BOOLEAN(1);
    this.backgroundMode = ParamConfig.INTEGER(BACKGROUND_MODES.indexOf(BackgroundMode.NONE), {
      menu: {
        entries: BACKGROUND_MODES.map((mode, i) => {
          return {name: mode, value: i};
        })
      }
    });
    this.bgColor = ParamConfig.COLOR([0, 0, 0], {
      visibleIf: {backgroundMode: BACKGROUND_MODES.indexOf(BackgroundMode.COLOR)}
    });
    this.bgTexture = ParamConfig.OPERATOR_PATH("", {
      visibleIf: {backgroundMode: BACKGROUND_MODES.indexOf(BackgroundMode.TEXTURE)},
      nodeSelection: {
        context: NodeContext2.COP
      },
      dependentOnFoundNode: false
    });
    this.useEnvironment = ParamConfig.BOOLEAN(0);
    this.environment = ParamConfig.OPERATOR_PATH("", {
      visibleIf: {useEnvironment: 1},
      nodeSelection: {
        context: NodeContext2.COP
      },
      dependentOnFoundNode: false
    });
    this.useFog = ParamConfig.BOOLEAN(0);
    this.fogType = ParamConfig.INTEGER(FOG_TYPES.indexOf(FogType.EXPONENTIAL), {
      visibleIf: {useFog: 1},
      menu: {
        entries: FOG_TYPES.map((mode, i) => {
          return {name: mode, value: i};
        })
      }
    });
    this.fogColor = ParamConfig.COLOR([1, 1, 1], {visibleIf: {useFog: 1}});
    this.fogNear = ParamConfig.FLOAT(1, {
      range: [0, 100],
      rangeLocked: [true, false],
      visibleIf: {useFog: 1, fogType: FOG_TYPES.indexOf(FogType.LINEAR)}
    });
    this.fogFar = ParamConfig.FLOAT(100, {
      range: [0, 100],
      rangeLocked: [true, false],
      visibleIf: {useFog: 1, fogType: FOG_TYPES.indexOf(FogType.LINEAR)}
    });
    this.fogDensity = ParamConfig.FLOAT(25e-5, {
      visibleIf: {useFog: 1, fogType: FOG_TYPES.indexOf(FogType.EXPONENTIAL)}
    });
    this.useOverrideMaterial = ParamConfig.BOOLEAN(0);
    this.overrideMaterial = ParamConfig.OPERATOR_PATH("/MAT/mesh_standard1", {
      visibleIf: {useOverrideMaterial: 1},
      nodeSelection: {
        context: NodeContext2.MAT
      },
      dependentOnFoundNode: false
    });
  }
}
const ParamsConfig2 = new SceneObjParamConfig();
export class SceneObjNode extends TypedObjNode {
  constructor() {
    super(...arguments);
    this.params_config = ParamsConfig2;
    this.hierarchy_controller = new HierarchyController2(this);
  }
  static type() {
    return "scene";
  }
  create_object() {
    const scene = new Scene2();
    scene.matrixAutoUpdate = false;
    return scene;
  }
  initializeNode() {
    this.hierarchy_controller.initializeNode();
  }
  cook() {
    if (this.pv.autoUpdate != this.object.autoUpdate) {
      this.object.autoUpdate = this.pv.autoUpdate;
    }
    this._update_background();
    this._update_fog();
    this._update_enviromment();
    this._update_material_override();
    this.cookController.end_cook();
  }
  _update_background() {
    if (this.pv.backgroundMode == BACKGROUND_MODES.indexOf(BackgroundMode.NONE)) {
      this.object.background = null;
    } else {
      if (this.pv.backgroundMode == BACKGROUND_MODES.indexOf(BackgroundMode.COLOR)) {
        this.object.background = this.pv.bgColor;
      } else {
        const node = this.p.bgTexture.found_node();
        if (node) {
          if (node.nodeContext() == NodeContext2.COP) {
            node.requestContainer().then((container) => {
              this.object.background = container.texture();
            });
          } else {
            this.states.error.set("bgTexture node is not a texture");
          }
        } else {
          this.states.error.set("bgTexture node not found");
        }
      }
    }
  }
  _update_fog() {
    if (this.pv.useFog) {
      if (this.pv.fogType == FOG_TYPES.indexOf(FogType.LINEAR)) {
        this.object.fog = this.fog;
        this.fog.color = this.pv.fogColor;
        this.fog.near = this.pv.fogNear;
        this.fog.far = this.pv.fogFar;
      } else {
        this.object.fog = this.fog_exp2;
        this.fog_exp2.color = this.pv.fogColor;
        this.fog_exp2.density = this.pv.fogDensity;
      }
    } else {
      const current_fog = this.object.fog;
      if (current_fog) {
        this.object.fog = null;
      }
    }
  }
  get fog() {
    return this._fog = this._fog || new Fog2(16777215, this.pv.fogNear, this.pv.fogFar);
  }
  get fog_exp2() {
    return this._fog_exp2 = this._fog_exp2 || new FogExp22(16777215, this.pv.fogDensity);
  }
  _update_enviromment() {
    if (this.pv.useEnvironment) {
      const node = this.p.environment.found_node();
      if (node) {
        if (node.nodeContext() == NodeContext2.COP) {
          node.requestContainer().then((container) => {
            this.object.environment = container.texture();
          });
        } else {
          this.states.error.set("bgTexture node is not a texture");
        }
      } else {
        this.states.error.set("bgTexture node not found");
      }
    } else {
      this.object.environment = null;
    }
  }
  _update_material_override() {
    if (this.pv.useOverrideMaterial) {
      const node = this.p.overrideMaterial.found_node();
      if (node) {
        if (node.nodeContext() == NodeContext2.MAT) {
          node.requestContainer().then((container) => {
            this.object.overrideMaterial = container.material();
          });
        } else {
          this.states.error.set("bgTexture node is not a material");
        }
      } else {
        this.states.error.set("bgTexture node not found");
      }
    } else {
      this.object.overrideMaterial = null;
    }
  }
}
