#include "OpenGLController.h"


#define GLFW_KEY_PLUS_GER GLFW_KEY_RIGHT_BRACKET
#define GLFW_KEY_MINUS_GER GLFW_KEY_SLASH

struct {
	double posX;
	double posY;
	bool leftHold;
	bool middleHold;
	bool rightHold;
	double speed = 1;
} mouse;


void windowResize(GLFWwindow * window, int width, int height)
{
	OpenGLController* controller = reinterpret_cast<OpenGLController*>(glfwGetWindowUserPointer(window));

	controller->resize(width, height);

	glViewport(0, 0, width, height);
}

void mouseButton(GLFWwindow *window, int button, int action, int mod)
{
	if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
	{
		mouse.leftHold = true;
		glfwGetCursorPos(window, &mouse.posX, &mouse.posY);
	}
	else if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE)
	{
		mouse.leftHold = false;
	}

	if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
	{
		mouse.rightHold = true;
		glfwGetCursorPos(window, &mouse.posX, &mouse.posY);
	}
	else if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_RELEASE)
	{
		mouse.rightHold = false;
	}
}

void mouseMove(GLFWwindow *window, double xpos, double ypos)
{
	OpenGLController* controller = reinterpret_cast<OpenGLController*>(glfwGetWindowUserPointer(window));

	if (mouse.leftHold)
	{
		controller->addRotX(static_cast<float>((ypos - mouse.posY) * 0.01 * mouse.speed));
		controller->addRotY(static_cast<float>((xpos - mouse.posX) * 0.01 * mouse.speed));

		mouse.posX = xpos;
		mouse.posY = ypos;
	}

	if (mouse.rightHold)
	{
		controller->addTransX(-(xpos - mouse.posX) * 0.01 * mouse.speed);
		controller->addTransY((ypos - mouse.posY) * 0.01 * mouse.speed);

		mouse.posX = xpos;
		mouse.posY = ypos;
	}
}

void mouseWheel(GLFWwindow *window, double xoffset, double yoffset)
{
	OpenGLController* controller = reinterpret_cast<OpenGLController*>(glfwGetWindowUserPointer(window));

	controller->addTransZ(-yoffset * 0.5 * mouse.speed);
}

void keyPress(GLFWwindow *window, int key, int scancode, int action, int mods)
{
	OpenGLController* controller = reinterpret_cast<OpenGLController*>(glfwGetWindowUserPointer(window));

	if (action == GLFW_PRESS || action == GLFW_REPEAT)
	{
		switch (key)
		{
		case GLFW_KEY_ESCAPE:
			glfwSetWindowShouldClose(window, GLFW_TRUE);
			break;
		case GLFW_KEY_MINUS_GER: case GLFW_KEY_KP_SUBTRACT:
			mouse.speed -= 0.1;
			if (mouse.speed < 0.1)
				mouse.speed = 0;
			break;
		case GLFW_KEY_PLUS_GER: case GLFW_KEY_KP_ADD:
			mouse.speed += 0.1;
			break;
		case GLFW_KEY_SPACE:
			controller->resetView();
			break;
		default:
			break;
		}
	}
}

void dragNdrop(GLFWwindow* window, int count, const char** paths)
{
	OpenGLController* controller = reinterpret_cast<OpenGLController*>(glfwGetWindowUserPointer(window));
	
	if (count < 1)
		return;

	controller->resetView();
	controller->loadMsh(paths[0]);
}
