#include "menu.h"

namespace ngObjects 
{
	Menu::Menu(int w, int h)
	{
		windowW = w;
		windowH = h;
	}
	void Menu::activate()
	{
		currentState = NGRAPH_MAIN_MENU;
		running = true;
		currentOpacity = 0.0;
		currentState = NGRAPH_MAIN_MENU;
		highlight = NGRAPH_SEARCH;
		quadratic = gluNewQuadric();
		pixmapFontData = new FTGLPixmapFont("menu.ttf");
		pixmapFontData->FaceSize(26);
	}

	int Menu::processEvent(SDL_Event &e)
	{
		switch(e.type) 
		{
			case SDL_KEYDOWN:
				if (e.key.keysym.sym == SDLK_ESCAPE)
				{
					if (currentState == NGRAPH_MAIN_MENU)
						fadeOut = true;  // Exit if we are at the main menu
					else if (currentState == NGRAPH_SEARCH)
					{
						highlight = NGRAPH_SEARCH;
						currentState = NGRAPH_MAIN_MENU; // Go back to the main menu if we are in a sub menu
					}
					else if (currentState == NGRAPH_SHORTEST_PATH)
						currentState = NGRAPH_MAIN_MENU;
				}
				else if (e.key.keysym.sym == SDLK_DOWN)
				{
					// Move highlight down if we are not at last item
					if (highlight != NGRAPH_SHORTEST_PATH && currentState == NGRAPH_MAIN_MENU)
							highlight--;
				}
				else if (e.key.keysym.sym == SDLK_UP)
				{
					// Move highlight up if we are not at last item
					if (highlight != NGRAPH_SEARCH && currentState == NGRAPH_MAIN_MENU)
							highlight++;
				}
				else if (e.key.keysym.sym == SDLK_RETURN)
				{
					if (currentState == NGRAPH_SEARCH && enteredKey != 0)
					{
						fadeOut = true;
						return NGRAPH_SEARCH;
					}
					else if (currentState == NGRAPH_SHORTEST_PATH && enteredKey != 0)
					{
						fadeOut = true;
						return NGRAPH_SHORTEST_PATH;
					}

					if (currentState == NGRAPH_MAIN_MENU)
						currentState = highlight;
					
					if (currentState == NGRAPH_SEARCH) // simple bugfix
						highlight = NGRAPH_SHORTEST_PATH; // Move the highlighter down for entering text
					else if (currentState == NGRAPH_MIN_TREE)
					{
						fadeOut = true;
						return NGRAPH_MIN_TREE;
					}
				}
				else if (e.key.keysym.sym == SDLK_q && currentState == NGRAPH_MAIN_MENU)
					return NGRAPH_QUIT;
				else
				{
					char *thekey = SDL_GetKeyName(e.key.keysym.sym);
					if (thekey[0] >= 65 && thekey[0] <= 122 && strlen(thekey) == 1)
						enteredKey = thekey;
				}
		}
		return 1;
	}

	void Menu::render()
	{
		// Switch to 2D mode and clear all matrix settings
		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		gluOrtho2D(0, windowW, 0, windowH);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		// Disabled Lights and DepthTest cause 2D hates them
		glDisable(GL_LIGHTING);
		glDisable(GL_DEPTH_TEST);
		// Enabled Alpha blending to make everything transparent
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);  

		glPushMatrix();
			// Gray out background
			glColor4f(0.5f, 0.5f, 0.5f, currentOpacity);
			glBegin(GL_QUADS);
			glVertex2f(windowW, windowH); // Top right Main Square
			glVertex2f(0, windowH); // Top left Main Square
			glVertex2f(0, 0); // Bottom left Main Square
			glVertex2f(windowW, 0); // Bottom left Main Square
			glEnd();

			// Draw Misc. menu text
			if (currentOpacity >= 0.8)
			{
				float x1, y1, z1, x2, y2, z2;
				glColor4f(1.0, 1.0, 1.0, 1.0);
				glRasterPos2f(0.0, 0.0);
				pixmapFontData->FaceSize(16);
				if (currentState == NGRAPH_MAIN_MENU)
				{
					pixmapFontData->Render("nGraph Main Menu");
					pixmapFontData->BBox("Press Q to quit", x1,y1,z1,x2,y2,z2);
					glRasterPos2f(windowW - x2, windowH - y2);
					pixmapFontData->Render("Press Q to quit");
				}
				else
				{
					pixmapFontData->Render("press enter to select");
					pixmapFontData->BBox("Press esc to go back", x1,y1,z1,x2,y2,z2);
					glRasterPos2f(windowW - x2, windowH - y2);
					pixmapFontData->Render("Press esc to go back");
				}
			}

			// Center selection highlighter on screen
			glTranslatef((windowW / 2) - (150 / 2), windowH / 2, 0.0);
			glPushMatrix();
				// Position highlighter based of mennu selection
				if (highlight == NGRAPH_SHORTEST_PATH)
					glTranslatef(0.0, -30.0, 0.0);
				glColor4f(0.996f, 0.619f, 0.254f, currentOpacity);
				glPushMatrix();
					glTranslatef(0.0, 16.0, 0.0);
					gluPartialDisk(quadratic, 0.0, 16.0, 32, 32, 0.0, -180); // left side
					glTranslatef(170.0, 0.0, 0.0);
					gluPartialDisk(quadratic, 0.0, 16.0, 32, 32, 0.0, 180); // right side
				glPopMatrix();
				glBegin(GL_QUADS);
				glVertex2f(170, 32); // Top right Main Square
				glVertex2f(0, 32); // Top left Main Square
				glVertex2f(0, 0); // Bottom left Main Square
				glVertex2f(170, 0); // Bottom left Main Square
				glEnd();
			glPopMatrix();

			// Draw menu text
			if (currentOpacity >= 0.8)
			{
				glColor4f(1.0, 1.0, 1.0, 1.0);
				if (currentState == NGRAPH_MAIN_MENU)
				{
					glRasterPos2f(-4.0, 7.0);
					pixmapFontData->FaceSize(24);
					pixmapFontData->Render(" Search Graph");
					glRasterPos2f(-4.0, -25.0);
					pixmapFontData->Render("Shortest Path");
				}
				else if (currentState == NGRAPH_SEARCH)
				{
					glRasterPos2f(-17.0, 7.0);
					pixmapFontData->FaceSize(24);
					pixmapFontData->Render("enter search item");
					glRasterPos2f(75.0, -25.0);
					if (enteredKey)
						pixmapFontData->Render(enteredKey);
				}
				else if (currentState == NGRAPH_SHORTEST_PATH)
				{
					glRasterPos2f(-17.0, 7.0);
					pixmapFontData->FaceSize(24);
					pixmapFontData->Render("enter destination");
					glRasterPos2f(75.0, -25.0);
					if (enteredKey)
						pixmapFontData->Render(enteredKey);
				}
			}
		glPopMatrix();

		glDisable(GL_BLEND);
		glEnable(GL_DEPTH_TEST);

		// Enter into our projection matrix mode
		glMatrixMode(GL_PROJECTION);                            

		// Pop off the last matrix pushed on when in projection mode (Get rid of ortho mode)
		glPopMatrix();                                            

		// Go back to our model view matrix like normal
		glMatrixMode(GL_MODELVIEW);  
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_LIGHTING);

		// Update state vars and take care of fade in fade out
		if (fadeOut)
		{
			if (currentOpacity >= 0.0)
				currentOpacity -= 0.05;
			else
			{
				fadeOut = false;
				running = false;
			}
		}
		else
		{
			if (currentOpacity < 0.8)
				currentOpacity += 0.05;
		}
	}
}
