#include "DrawingsGL.h"
#include "OverlayBase.h"
#include "SimpleConsoleOverlay.h"
#include "ControllerBase.h"

#include "OGLFT.h"

#include <GL/gl.h>
#include <GL/glu.h>

namespace Engine {

static Variable Var_ConsoleTransparency ("consoletransparency", "0.2");

bool SimpleConsoleOverlay::OnKeyDown (const SDL_keysym &keysym) {
	if (keysym.sym == SDLK_F8) {
		if (mActive) {
			// We have to call SetActive() to actually
			// activate the unicode processing of SDL
			EngineGetController()->EnableTextinput(false);
		}
		else {
			EngineGetController()->EnableTextinput(true);
		}

		return true;
	}

	if (!mActive)
		return false;

	// check for input that requires actions
	switch (keysym.sym) {
		case SDLK_ESCAPE:
			EngineGetController()->EnableTextinput(false);
			return true;
			break;
		case SDLK_BACKSPACE:
			if (mCurrentInput.size() > 0)
				mCurrentInput = mCurrentInput.substr (0, mCurrentInput.size() - 1 );
			return true;
			break;
		case SDLK_RETURN:
			if (mCurrentInput.size() == 0) {
				mLastLines.push_back ("");
				return true;
			}

			mLastLines.push_back (mCurrentInput);

			// run the command and print out the error if there was one
			if (!RunCommand (mCurrentInput)) {
				mLastLines.push_back ("Error: " + CommandGetErrorString());
			}
			mCurrentInput = "";
			return true;

			break;
		default:
			break;
	}

	// if we got input of a character that we can write add it to the current
	// input
	if (keysym.unicode) {	
		if ((keysym.unicode & 0xFF80) == 0) {
			mCurrentInput += keysym.unicode & 0x7F;
			return true;
		} else {
			LogWarning ("Input key not supported!");
			return false;
		}
	}

	return true;
}

void SimpleConsoleOverlay::Draw () {
	SelectFont ("console.ttf");

	// we switch to orthographic projection and draw the contents of the 2d 
	// overlay on top of the previous drawings
	glMatrixMode (GL_PROJECTION);
	glPushMatrix ();
		glLoadIdentity ();

		// first we have to get the size of the current viewport to set up the
		// orthographic projection correctly
		GLint viewport[4];
		glGetIntegerv(GL_VIEWPORT, viewport);
		gluOrtho2D (viewport[0], viewport[2], viewport[3], viewport[1]);

		glMatrixMode (GL_MODELVIEW);
		glPushMatrix ();
			glLoadIdentity ();

			// then we do the drawings
			if (mDrawLogBar)
				DrawLogBar ();
			if (mActive)
				DrawConsole ();
			
		glPopMatrix ();

		glMatrixMode (GL_PROJECTION);
	glPopMatrix ();

	glMatrixMode (GL_MODELVIEW);

};

void SimpleConsoleOverlay::DrawLogBar () {
	// first we have to get the size of the current viewport to set up the
	// orthographic projection correctly
	GLint viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);

	// we want to enable transparency
	glDisable(GL_DEPTH_TEST);
	glEnable (GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);

	float left = 0;
	float right = static_cast<float> (GetWindowWidth());
	float top = 0;
//	float bottom = static_cast<float> (GetWindowHeight());

	// draw the background
	glColor4f (0.2, 0.2, 0.2, 0.3);
	glBegin (GL_QUADS);
	glVertex2f (left, top);
	glVertex2f (left, top + 16);
	glVertex2f (right, top + 16);
	glVertex2f (right, top);
	glEnd ();

	glDisable (GL_BLEND);

	// draw the log
	std::ostringstream topbar_stream;
	topbar_stream << "Log: " << GetLastLogEntry().mMessage;
	DrawGLString ( 10, 10, topbar_stream.str().c_str ());

	// draw the FPS counter
	topbar_stream.str ("");
	topbar_stream << "FPS: " << GetFrameRate();
	DrawGLString (right - 64 , 10, topbar_stream.str().c_str ());

	glEnable (GL_DEPTH_TEST);
}

void SimpleConsoleOverlay::DrawConsole () {
	// first we have to get the size of the current viewport to set up the
	// orthographic projection correctly
	GLint viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);

	// we want to enable transparency
	glDisable(GL_DEPTH_TEST);
//	glEnable (GL_BLEND);
//	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//	glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);

	// calculate the screen coordinates which defines the size of the
	// console
	mLeft = (viewport[2] - viewport[0]) * 0.5 - (viewport[2] - viewport[0]) * 0.45 ;
	mRight = (viewport[2] - viewport[0]) * 0.5 + (viewport[2] - viewport[0]) * 0.45;
	mTop = -1; // Do not draw the mTop line
	mBottom = (viewport[3] - viewport[1]) * 0.7;

	// draw the background
	glColor4f (0.2, 0.2, 0.2, Var_ConsoleTransparency.GetFloatValue());
	glBegin (GL_QUADS);
	glVertex2f (mLeft, mTop);
	glVertex2f (mLeft, mBottom);
	glVertex2f (mRight, mBottom);
	glVertex2f (mRight, mTop);
	glEnd ();

	// draw borders
	glColor3f (0.9, 0.9, 0.9);
	glBegin (GL_LINE_STRIP);
	glVertex2f (mLeft, mTop);
	glVertex2f (mLeft, mBottom);
	glVertex2f (mRight, mBottom);
	glVertex2f (mRight, mTop);
	glVertex2f (mLeft, mTop);
	glEnd ();

	glDisable (GL_BLEND);

	// now draw the contents
	DrawLastLines ();
	DrawCurrentInput ();

	glEnable (GL_DEPTH_TEST);
}

const std::vector<std::string> SimpleConsoleOverlay::GetLastLines (const unsigned int n) {
	assert (0);
	std::vector<std::string> result;
	return result;
}

void SimpleConsoleOverlay::DrawLastLines () {
	unsigned int i;
	for (i = 0; i < mLastLines.size(); i++)
		DrawGLString (mLeft + 8, mTop + 12 + 12 *i, mLastLines[i].c_str());
}

void SimpleConsoleOverlay::DrawCurrentInput () {
	// We add a '_' to the current input as a simple cursor
	static std::string current_input;
	current_input = mCurrentInput + "_";
 
	// We add a '>' at the beginning of the input line to highlight it
	DrawGLString (mLeft, mTop + 12 + 12 * (mLastLines.size()), ">");
	DrawGLString (mLeft + 8, mTop + 12 + 12 * (mLastLines.size()), current_input.c_str());
}



}
