import { Color } from '../../../core/math/color.js';
import { Vec3 } from '../../../core/math/vec3.js';
import { ShaderMaterial } from '../../../scene/materials/shader-material.js';
import { MeshInstance } from '../../../scene/mesh-instance.js';
import { Entity } from '../../../framework/entity.js';
import { CULLFACE_BACK } from '../../../platform/graphics/constants.js';
import { BLEND_NORMAL } from '../../../scene/constants.js';
import { COLOR_GRAY } from '../color.js';
import { Geometry } from '../../../scene/geometry/geometry.js';
import { unlitShader } from '../shaders.js';

const tmpG = new Geometry();
tmpG.positions = [];
tmpG.normals = [];
class Shape {
		constructor(device, name, args){
				this._position = new Vec3();
				this._rotation = new Vec3();
				this._scale = new Vec3(1, 1, 1);
				this._layers = [];
				this._material = new ShaderMaterial(unlitShader);
				this._disabled = false;
				this._visible = true;
				this._defaultColor = Color.WHITE;
				this._hoverColor = Color.BLACK;
				this._disabledColor = COLOR_GRAY;
				this._cull = CULLFACE_BACK;
				this.triData = [];
				this.meshInstances = [];
				this.device = device;
				this.axis = args.axis ?? 'x';
				if (args.position instanceof Vec3) {
						this._position.copy(args.position);
				}
				if (args.rotation instanceof Vec3) {
						this._rotation.copy(args.rotation);
				}
				if (args.scale instanceof Vec3) {
						this._scale.copy(args.scale);
				}
				this._disabled = args.disabled ?? false;
				this._visible = args.hidden ?? false;
				this._layers = args.layers ?? this._layers;
				if (args.defaultColor instanceof Color) {
						this._defaultColor = args.defaultColor;
				}
				if (args.hoverColor instanceof Color) {
						this._hoverColor = args.hoverColor;
				}
				if (args.disabledColor instanceof Color) {
						this._disabledColor = args.disabledColor;
				}
				this.entity = new Entity(`${name}:${this.axis}`);
				this.entity.setLocalPosition(this._position);
				this.entity.setLocalEulerAngles(this._rotation);
				this.entity.setLocalScale(this._scale);
		}
		set disabled(value) {
				this._disabled = value ?? false;
				this.hover(false);
		}
		get disabled() {
				return this._disabled;
		}
		set visible(value) {
				if (value === this._visible) {
						return;
				}
				for(let i = 0; i < this.meshInstances.length; i++){
						this.meshInstances[i].visible = value;
				}
				this._visible = value;
		}
		get visible() {
				return this._visible;
		}
		_createRenderComponent(entity, meshes) {
				const color = this._disabled ? this._disabledColor : this._defaultColor;
				this._material.setParameter('uColor', color.toArray());
				this._material.cull = this._cull;
				this._material.blendType = BLEND_NORMAL;
				this._material.update();
				const meshInstances = [];
				for(let i = 0; i < meshes.length; i++){
						const mi = new MeshInstance(meshes[i], this._material);
						mi.cull = false;
						meshInstances.push(mi);
						this.meshInstances.push(mi);
				}
				entity.addComponent('render', {
						meshInstances: meshInstances,
						layers: this._layers,
						castShadows: false
				});
		}
		_update() {
				this.entity.setLocalPosition(this._position);
				this.entity.setLocalEulerAngles(this._rotation);
				this.entity.setLocalScale(this._scale);
		}
		hover(state) {
				const color = this._disabled ? this._disabledColor : state ? this._hoverColor : this._defaultColor;
				this._material.setParameter('uColor', color.toArray());
		}
		destroy() {
				this.entity.destroy();
		}
}

export { Shape };
