import {TypedNode} from '../_Base';
import {Texture} from 'three';
import {NodeParamsConfig} from '../utils/params/ParamsConfig';
import {NodeContext} from '../../poly/NodeContext';
import {FlagsControllerBO} from '../utils/FlagsController';
import {DataTexture} from 'three';
import {LuminanceFormat, HalfFloatType} from 'three';

var size = 32;
var data = new Uint16Array(size);
for (var i = 0; i < size; i++) {
	data[i] = 0x70e2; // Half float 10000
}
const EMPTY_DATA_TEXTURE = new DataTexture(data, size, 1, LuminanceFormat, HalfFloatType);

/**
 *
 *
 * TypedCopNode is the base class for all nodes that process textures. This inherits from [TypedNode](/docs/api/TypedNode).
 *
 */

export class TypedCopNode<K extends NodeParamsConfig> extends TypedNode<NodeContext.COP, K> {
	public override readonly flags: FlagsControllerBO = new FlagsControllerBO(this);

	static override context(): NodeContext {
		return NodeContext.COP;
	}

	override initializeBaseNode() {
		this.io.outputs.setHasOneOutput();
	}

	private ___textureSync: Texture | undefined;
	__textureSync__(): Texture | undefined {
		return this.___textureSync;
	}

	setTexture(texture: Texture) {
		this.___textureSync = texture;
		texture.name = this.path();

		// the behavior below was an attempt at copying all properties
		// of a new texture to the current texture,
		// in the hope that it would make it easy for materials using it to update.
		// But that only partially worked, and created more confusion
		// as the materials updated only once or twice.
		// So now it is the material's responsibility to update the texture
		// when this file is dirty.
		// const currentTexture = this.containerController.container().texture();
		// if (currentTexture) {
		// 	// this method to change the texture of a cop/image
		// 	// and have the material update could potentially work.
		// 	// But at the moment, when loading a 2nd texture,
		// 	// This overrides the properties of the 1st texture.
		// 	// So that when we try and reload that 1st texture, it has become the 2nd.
		// 	// And even with more texture, the behavior still seems to keep the 2nd texture
		// 	if (currentTexture.uuid != texture.uuid) {
		// 		const newPropNames = Object.keys(texture) as Array<keyof Texture>;
		// 		for (let newPropName of newPropNames) {
		// 			(currentTexture as any)[newPropName] = texture[newPropName];
		// 		}
		// 		// document.body.append((currentTexture as any).image);
		// 		// document.body.style.overflow = 'auto';
		// 		currentTexture.needsUpdate = true;
		// 	}
		// 	this._setContainer(currentTexture);
		// } else {
		this._setContainer(texture);
		// }
		// this._copy_texture(texture);
	}
	protected _clearTexture() {
		this._setContainer(EMPTY_DATA_TEXTURE);
	}
	// this methods leads to webgl errors quite deep in threejs renderer
	// private _copytexture(texture: Texture, target: Texture) {
	// 	const newPropNames = Object.keys(texture) as Array<keyof Texture>;
	// 	for (let newPropName of newPropNames) {
	// 		(target as any)[newPropName] = texture[newPropName];
	// 		console.log('prop', newPropName);
	// 	}
	// 	target.needsUpdate = true;
	// }
}

export type BaseCopNodeType = TypedCopNode<any>;
export class BaseCopNodeClass extends TypedCopNode<any> {}
