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

export default class Camera {

	eye 		= new Vector3();
	target 		= new Vector3();
	up 			= new Vector3( 0, 1, 0 );

	yaw 		= 0;
	pitch 		= 0;
	fovRadians 	= Math.PI / 4;
	near 		= 0.1;
	far 		= 3000.0;
	distance 	= 10;
	viewMatrix = new Float32Array( 16 );

	constructor( eye = [0, 0, 5], target = [0, 0, 0], up = [0, 1, 0] ) {

		this.eye 		= new Vector3( ...eye );
		this.target 	= new Vector3( ...target );
		this.up 		= new Vector3( ...up );

		this.distance 	= Vector3.subtract( this.eye, this.target ).length();

		this.viewMatrix = Matrix4.lookAt( this.eye, this.target, this.up );

	}

	update() {

		const x = this.distance * Math.cos( this.pitch ) * Math.sin( this.yaw );
		const y = this.distance * Math.sin( this.pitch );
		const z = this.distance * Math.cos( this.pitch ) * Math.cos( this.yaw );

		this.eye = new Vector3(
			x + this.target.x,
			y + this.target.y,
			z + this.target.z
		);

		this.viewMatrix = Matrix4.lookAt( this.eye, this.target, this.up );

	}

	getViewMatrix() {

		return this.viewMatrix;

	}

	rotate( deltaYaw, deltaPitch ) {

		this.yaw += deltaYaw;
		this.pitch -= deltaPitch;

		const maxPitch = Math.PI / 2 - 0.01;

		if ( this.pitch > maxPitch ) this.pitch = maxPitch;
		if ( this.pitch < -maxPitch ) this.pitch = -maxPitch;

		this.update();

	}

	zoom( delta ) {

		this.distance += delta * 1;

		if ( this.distance < 0.1 ) this.distance = 0.1;

		this.update();

	}

	setTarget( target ) {

		this.target = new Vector3( ...target );

		this.update();

	}
}
