#include "RenderWindow.h"

#include "Utilities/Log.h"

using namespace std;

namespace BlueCore
{

static RenderWindow* gRenderWindow = 0;

//------------------------------------------------------------------------------
RenderWindow::RenderWindow() :
	_Initialized(false),
	_Closed(false)
{
	glfwInit();
	gRenderWindow = this;
	clog << ">>> RenderWindow constructed..."<< endlog;
}

//------------------------------------------------------------------------------
RenderWindow::~RenderWindow()
{
	destroy();
	glfwTerminate();
	gRenderWindow = 0;
	clog << ">>> RenderWindow destructed..."<< endlog;
}

//------------------------------------------------------------------------------
void RenderWindow::WindowRefreshCallback()
{
	gRenderWindow->WindowRefreshSignal();
}

//------------------------------------------------------------------------------
int RenderWindow::WindowCloseCallback()
{
	clog << ">>> RenderWindow closed..."<< endlog;
	gRenderWindow->closeWindow();
	return GL_FALSE;
}

//------------------------------------------------------------------------------
void RenderWindow::closeWindow()
{
	_Closed = true;
}

//------------------------------------------------------------------------------
void RenderWindow::WindowSizeCallback(int width, int height)
{
	gRenderWindow->resizeWindow(width, height);
}

//------------------------------------------------------------------------------
void RenderWindow::resizeWindow(int width, int height)
{
	_Resized = true;

	if ( !_Initialized)
		return;

	clog << ">>> RenderWindow resized: "<< width << "x"<< height << endlog;

	_Width = width;
	_Height = height;

	WindowResizeSignal(width, height);
}

//------------------------------------------------------------------------------
int RenderWindow::getWidth()
{
	return _Width;
}

//------------------------------------------------------------------------------
int RenderWindow::getHeight()
{
	return _Height;
}

//------------------------------------------------------------------------------
bool RenderWindow::create(int width, int height, int pixelbits, int depthbits,
		int stencilbits, bool fullscreen)
{
	int channelbits = 8;
	if (pixelbits == 16)
		channelbits = 4;

	if (glfwOpenWindow(width, height, channelbits, channelbits, channelbits,
			channelbits, depthbits, stencilbits, fullscreen ? GLFW_FULLSCREEN
					: GLFW_WINDOW) == GL_FALSE)
		return false;

	glfwSetWindowSizeCallback(WindowSizeCallback);
	glfwSetWindowCloseCallback(WindowCloseCallback);
	glfwSetWindowRefreshCallback(WindowRefreshCallback);

	glfwSetMousePosCallback(MousePosCallback);
	glfwSetMouseButtonCallback(MouseButtonCallback);
	glfwSetMouseWheelCallback(MouseWheelCallback);
	glfwSetKeyCallback(KeyCallback);
	glfwSetCharCallback(CharCallback);

	clog << ">>> RenderWindow created"<< endlog;

	_Initialized = true;

	glfwGetWindowSize( &_Width, &_Height);
	resizeWindow(_Width, _Height);

	return true;
}

//------------------------------------------------------------------------------
void RenderWindow::destroy()
{
	if (_Initialized)
	{
		glfwCloseWindow();
		clog << ">>> RenderWindow destroyed"<< endlog;
		_Initialized = false;
	}
}

//------------------------------------------------------------------------------
bool RenderWindow::isOpen()
{
	if (_Initialized == false)
		return false;

	if (_Closed)
		return false;

	return (glfwGetWindowParam(GLFW_OPENED) == GL_TRUE);
}

//------------------------------------------------------------------------------
void RenderWindow::MousePosCallback(int x, int y)
{
	gRenderWindow->MouseMoveSignal(x, y);
}

//------------------------------------------------------------------------------
void RenderWindow::MouseButtonCallback(int button, int action)
{
	gRenderWindow->MouseButtonSignal(button, action);
}

//------------------------------------------------------------------------------
void RenderWindow::MouseWheelCallback(int pos)
{
	gRenderWindow->MouseWheelSignal(pos);
}

//------------------------------------------------------------------------------
void RenderWindow::KeyCallback(int key, int action)
{
	gRenderWindow->KeySignal(key, action);
}

//------------------------------------------------------------------------------
void RenderWindow::CharCallback(int character, int action)
{
	gRenderWindow->CharSignal(character);
}

} // namespace BlueCore
