import {BaseSopOperation} from './_Base';
import {CoreGroup} from '../../../core/geometry/Group';
import {InputCloneMode} from '../../../engine/poly/InputCloneMode';
import {DefaultOperationParams} from '../../../core/operations/_Base';
import {BufferAttribute, BufferGeometry, Box3} from 'three';
import {ObjectType} from '../../../core/geometry/Constant';
const tmpBox = new Box3();
interface BboxScatterSopParams extends DefaultOperationParams {
	stepSize: number;
}

export class BboxScatterSopOperation extends BaseSopOperation {
	static override readonly DEFAULT_PARAMS: BboxScatterSopParams = {
		stepSize: 1,
	};
	static override readonly INPUT_CLONED_STATE = InputCloneMode.NEVER;
	static override type(): Readonly<'bboxScatter'> {
		return 'bboxScatter';
	}
	override cook(inputCoreGroups: CoreGroup[], params: BboxScatterSopParams) {
		const inputCoreGroup = inputCoreGroups[0];
		const stepSize = params.stepSize;
		inputCoreGroup.boundingBox(tmpBox);
		const min = tmpBox.min;
		const max = tmpBox.max;

		const positions: number[] = [];
		for (let x = min.x; x <= max.x; x += stepSize) {
			for (let y = min.y; y <= max.y; y += stepSize) {
				for (let z = min.z; z <= max.z; z += stepSize) {
					positions.push(x);
					positions.push(y);
					positions.push(z);
				}
			}
		}

		const geometry = new BufferGeometry();
		geometry.setAttribute('position', new BufferAttribute(new Float32Array(positions), 3));

		const object = BaseSopOperation.createObject(geometry, ObjectType.POINTS);
		if (this._node) {
			object.name = this._node.name();
		}

		return this.createCoreGroupFromObjects([object]);
	}
}
