#include "CGameWindow.hpp"

CGameWindow::CGameWindow(std::string title, std::string iconPath, unsigned int width, unsigned int height, bool resizable, bool fullscreen) :
	CWindow(title, iconPath, width, height, false, false, SDL_WINDOW_OPENGL),
	m_grabCursor(false),
	m_relativeCursor(false),
	m_msaa(0) {
}

CGameWindow::CGameWindow(std::string title, SDL_Window* window) :
	CWindow(title, window, SDL_WINDOW_OPENGL, 0),
	m_grabCursor(false),
	m_relativeCursor(false),
	m_msaa(0) {
}

CGameWindow::~CGameWindow(void) {
}

SDL_GLContext CGameWindow::getOpenGLContext(void) {
	if (getWindow() == nullptr) {
		throw CLogicException("The window must be initialized before using this method !");
	}
	else {
		SDL_GLContext out = SDL_GL_CreateContext(getWindow());
		if (out == nullptr) {
			throw CLibException(std::string("Unable to create OpenGL context: ") + SDL_GetError());
		}
		return out;
	}
}

bool CGameWindow::isCursorGrabbed(void) const {
	return m_grabCursor;
}

void CGameWindow::setCursorGrabbed(bool newMouseGrab) {
	m_grabCursor = newMouseGrab;

	if (m_relativeCursor && !m_grabCursor) {
		setCursorRelative(false);
	}

	if (getWindow() != nullptr) {
		if (m_grabCursor) {
			SDL_SetWindowGrab(getWindow(), SDL_TRUE);
		}
		else {
			SDL_SetWindowGrab(getWindow(), SDL_FALSE);
		}
	}
}

bool CGameWindow::isCursorRelative(void) const {
	return m_relativeCursor;
}

void CGameWindow::setCursorRelative(bool newMouseRelative) {
	m_relativeCursor = newMouseRelative;

	if (m_relativeCursor && !m_grabCursor) {
		setCursorGrabbed(true);
	}

	if (getWindow() != nullptr) {
		if (m_relativeCursor) {
			SDL_SetRelativeMouseMode(SDL_TRUE);
		}
		else {
			SDL_SetRelativeMouseMode(SDL_FALSE);
		}
	}
}

unsigned char CGameWindow::getAntiAliasing(void) const {
	return m_msaa;
}

void CGameWindow::setAntiAliasing(unsigned char newMsaa) {
	if (getWindow() != nullptr) {
		throw CLogicException("The window must be uninitialized before using this method !");
	}
	else {
		if (newMsaa == 2 || newMsaa == 4 || newMsaa == 8 || newMsaa == 16) {
			m_msaa = newMsaa;
		}
		else {
			m_msaa = 0;
		}
	}
}

void CGameWindow::preinitialization(void) {
	// We want OpenGL version 3.3.
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

	// Anti-aliasing Configuration.
	if (m_msaa == 0) {
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
	}
	else {
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_msaa);
	}

	// Double Buffer.
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	// Depht Buffer.
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

}

void CGameWindow::postinitialization(void) {

	// Set the cursorGrab property.
	if (m_grabCursor) {
		SDL_SetWindowGrab(getWindow(), SDL_TRUE);
	}
	else {
		SDL_SetWindowGrab(getWindow(), SDL_FALSE);
	}

	// Set the cursorRelative property.
	if (m_relativeCursor) {
		SDL_SetRelativeMouseMode(SDL_TRUE);
	}
	else {
		SDL_SetRelativeMouseMode(SDL_FALSE);
	}
}