import { RenderPass }	from "../framework/RenderPass.js";

import Shader			from "../framework/WebGpu.js";

import Matrix4			from "../framework/Matrix4.js";


export class OceanRenderPass extends RenderPass {

	async create( ) {

		this.shader					= new Shader( this.device );

		this.shader.topology		= "line-list";

		this.shader.setCanvas( this.pipeline.canvas );

		this._configureCanvasContext();

		await this.shader.setup( "shaders/ocean_render.wgsl" );

		this.shader.setAttribute( "position", this.pipeline.memory.positions );

		this.shader.setAttribute( "uv", this.pipeline.memory.uvs );

		this.shader.setIndices( this.pipeline.memory.lineIndices );

	}


	async bindBuffers( ) {

		const memory				= this.pipeline.memory;

		const oceanBlock			= this.pipeline.getBlockByName( "ocean" );

		const colPass				= oceanBlock.getPass( "ColFFT" );

		const heightBuffer			= colPass.shader.getBuffer( "heightField" );

		const viewMatrixData		= this.pipeline.camera.getViewMatrix();

		const projectionMatrixData	= Matrix4.createProjectionMatrix( this.pipeline.camera, this.pipeline.canvas );

		const viewProjectionMatrix	= Matrix4.multiply( projectionMatrixData, viewMatrixData );

		const cameraWorldMatrix		= Matrix4.invert( viewMatrixData );

		const cameraPosition		= Matrix4.getColumn( cameraWorldMatrix, 3 );

		await this.shader.setBuffer( "heightField", heightBuffer );

		this.shader.setVariable( "renderParams", memory.renderParams );

		this.shader.setVariable( "viewProjection", viewProjectionMatrix );

		this.shader.setVariable( "cameraPosition", cameraPosition );

		this.shader.createBindGroups();

	}


	async execute( ) {

		await this.shader.renderToCanvas( this.shader.indexCount, 1 );

	}


	_configureCanvasContext( ) {

		if ( this.pipeline.canvasConfigured ) {
			return;
		}

		const context	= this.pipeline.canvas.getContext( "webgpu" );

		const format	= navigator.gpu.getPreferredCanvasFormat();

		context.configure( {
			device: this.device,
			format: format,
			alphaMode: "opaque"
		} );

		this.pipeline.canvasConfigured = true;

		}

}
