#pragma once
#include "GLFW\glfw3.h"
#include "GLM\glm.hpp"
#include "GLM\gtc\matrix_transform.hpp"
#include "math.h"
#include <iostream>

//modified by Han Zhang, 27/11/2018, adding arcball controller

class CameraController
{
private:
	GLFWwindow* mp_window;
	int m_window_width;
	int m_window_height;

	glm::vec3 m_camera_position; // Camera position
	glm::mat4 m_view_space;
	glm::mat4 m_projection_space;

	////for arc ball rotation
	//glm::mat4 m_arc_rotation;
	//glm::vec3 start_cursor;
	//glm::vec3 rayCast(glm::vec3 emit);
	//double arcBallRadius;
	//glm::mat4 tempRotate;
	//int mouse_status;
	//const glm::mat4 identity = glm::mat4(1.0f);
	
public:
	//static CameraController& getInstance()
	//{
	//	static CameraController instance;
	//	return instance;
	//}
	//void BindWindow(GLFWwindow* window);

	CameraController(GLFWwindow* window);
	~CameraController();

	glm::mat4 GetViewMatrix();
	glm::mat4 GetProjectionMatrix();
	//void setWindowWidthHeight(int w,int h);

	void ComputeMatricesFromInputs(); // Compute the view & projection space matrices via mouse and keyboard input
	//static void mousecb(GLFWwindow* window, double xpos, double ypos);
	//void MouseCallBackFunction(GLFWwindow* window, double xpos, double ypos);
	
	float m_horizontal_angle; // Initial camera horizontal angle : toward -Z
	float m_vertical_angle; // Initial camera vertical angle : none
	float m_initialFOV; // Initial Field of View
	float m_last_xpos, m_last_ypos; // Prior mouse position

	float m_keyboard_speed; // Default = 3 units / second
	float m_mouse_speed;

	//void setArcAngle(glm::vec3 start, glm::vec3 end);
};



//glm::mat4 view_space = glm::lookAt
//(
//	glm::vec3(4, 3, 3), // Camera is at (4, 3, 3) in World Space
//	glm::vec3(0, 0, 0), // Looks at the origin
//	glm::vec3(0, 1, 0) // Head is y-up (set to 0, -1, 0 to look upside-down)
//);

// Perspective camera
//glm::mat4 projection_space = glm::perspective
//(
//	45.0f, // 45 field of view
//	4.0f / 3.0f, // 4:3 ratio
//	0.1f, 100.0f // display range 0.1 ~ 100
//);

// Orthogonal camera
//glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f); // In world coordinates

//glm::mat4 mvp = projection_space * view_space * model_space; // Remember, matrix multiplication is the other way around