/*
 * Copyright 2013, kaj dijkstra, 
 * Author, Kaj Dijkstra.
 * All rights reserved.
 *
 */

 import {math, vector2, vector3, matrix4} from './math.js';
 
/**
 * Camera Object
**/
class camera{
	
	constructor( engine ){
		
		this.yaw = 0;
		this.pitch = 30;
		this.roll = 0;
		
		this.distance = 5.35;
		//this.distance = .05;
		this.fov = 55;
		
		this.eye = new vector3(0,0,0);
		this.target = new vector3(0,0,0);
		this.up = new vector3(0, 1, 0);
		
		this.view;
		this.projection;
		this.worldViewProjection;
		
		this.target;
		this.frustumCorners;
		this.center = new vector3(0, 1, 0);

		this.rotationSpeed = .1;

		this.lastPriority = 0;
		this.mode = "orbit";//freeLook, orbit
		this.fieldOfView = 65;
		
		this.far = 1000;
		this.near = 0.004;
	}
	
	setViewport( viewport ){
		
		this.viewport = viewport;
		this.gl = viewport.gl;
	}
	
		
	/**
	 * Set camera position
	 * @param {(vector3)} position you want to set
	**/
	setPosition (a) {
		this.center = a;
	};


	/**
	 * get position of camera
	 * @return {(vector3)} camera position
	**/
	getPosition () {
		return this.center;
	};


	/**
	 * Move camera
	 * @param {(vector3)} 
	**/
	move (a) {
		this.center = kepler.vector3.add(a, this.center);
	};


	/**
	 * Set camera direction
	 * @param {(vector3)} 
	**/
	setDirection ( normalizedVector ) {
		this.target = normalizedVector;
	};


	/**
	 * get camera direction
	 * @param {(vector3)} 
	**/
	getDirection () {
		return this.target;
	};


	/**
	 * get camera up vector
	 * @param {(vector3)} 
	**/
	getUp () {
		return this.up;
	};


	/**
	 * get camera right (Depricated)
	 * @param {(vector3)} 
	**/
	getRight () {

	};

	/**
	 * Rotate camera (Depricated)
	 * @param {(vector3)} 
	**/
	rotate (x,y,z) {
		
	};


	/**
	 * set camera Orientation (Depricated)
	 * @param {(vector3)} 
	**/
	setOrientation  () {

	};


	/**
	 * Calculate new up vector to prevent camera flipping on 90 or something degrees.
	**/
	checkup () {
		var that = this;
		if(that.pitch<=0)
			that.pitch += 360;
		if(((that.pitch+90)/180)%2<=1)
			that.up = new vector3(0,1,0);
		else
			that.up = new vector3(0,-1,0);
	};

	/**
	 * update camera orbit position.
	**/
	UpdateOrbit (yaw, pitch) {


		this.yaw += yaw * this.rotationSpeed;
		this.pitch += pitch * this.rotationSpeed;

		this.checkup();
	};

	/**
	 * Orbit camera.
	**/
	orbit() {

		this.yaw += .2;
		
		var timeNow = new Date().getTime();
		
		if (kepler.lastTime != 0) {
			var elapsed = timeNow - kepler.lastTime;
		}
		
		var mix = Math.max(0, Math.min(1, elapsed/120));

		var smooth = vector2.interpolate(	this.viewport.events.clientMouse,
											this.viewport.events.oldMousPos,
												mix );
												
		this.viewport.events.mouseVerschil = [this.viewport.events.clientMouse[0] - this.viewport.events.oldMousPos[0], this.viewport.events.clientMouse[1] - this.viewport.events.oldMousPos[1]];

		this.viewport.events.oldMousPos = this.viewport.events.clientMouse;

		if( this.viewport.events.mouseDown[1] || this.viewport.events.mouseDown[2] ) {
			if( this.viewport.events.mouseVerschil[0]!=0 || this.viewport.events.mouseVerschil[1]!=0 ) {
				this.UpdateOrbit( -this.viewport.events.mouseVerschil[0] , this.viewport.events.mouseVerschil[1] );
			}
		}
		
		if(this.yaw > 360)
			this.yaw -=360;
			
		if(this.yaw < 0)
			this.yaw +=360;
			
		if(this.pitch > 360)
			this.pitch -=360;
			
		if(this.pitch < 0)
			this.pitch +=360;
			
		
		var beginVector = new vector3( 0, 0, -this.distance ); 

		var yawMatrix =   matrix4.rotationY( math.degToRad(this.yaw) );
		var pitchMatrix = matrix4.rotationX( math.degToRad(this.pitch) );
		
		var transMatrix = matrix4.mul(pitchMatrix, yawMatrix);
		
		this.target = this.center;
		this.eye = vector3.add( matrix4.transformDirection(transMatrix, beginVector), this.target);

		
		this.projection = matrix4.perspective(math.degToRad(this.fov), this.viewport.width / this.viewport.height, this.near, this.far);
		this.view = matrix4.lookAt(this.eye, this.target, this.up);
		
		this.worldViewProjection = matrix4.mul(this.view, this.projection);
		
	};


	updateMatrix() {
		
		
		this.projection = matrix4.perspective(math.degToRad(this.fov), this.engine.system.width / this.engine.system.height, this.near, this.far);
		this.view = matrix4.lookAt(this.eye, this.target, this.up);
		
		//console.log(this.eye, this.target, this.up, matrix4.lookAt(this.eye, this.target, this.up))
		
		this.worldViewProjection = matrix4.mul(this.view, this.projection);
	}
	/**
	 * Update camera matrices
	**/
	update() {
		this.orbit();
	}

}

export {camera as default};