/* Copyright (C) 2007  Mikko Sysikaski <mikko.sysikaski@gmail.com>
 * This program is free software distributed under GNU General Public License
 * version 3 or (at your option) any later version.
 * No warranty of any kind is provided. See the accompanying file COPYING for details.
 */

#include "ingamemenu.h"
#include "renderer.h"
#include "gameapp.h"
#include "glscreen.h"
#include "lcd.h"
#include "physics.h"
#include "besttimes.h"
#include <GL/gl.h>

namespace {
const char* run[] = {"continue", "reset", "exit"};
const char* stop[] = {"reset", "exit"};
const char* winRun[] = {"continue", "next", "reset", "exit"};
const char* winStop[] = {"next", "reset", "exit"};
}
InGameMenu::StrVect InGameMenu::s_run(run, run+3);
InGameMenu::StrVect InGameMenu::s_stop(stop, stop+2);
InGameMenu::StrVect InGameMenu::s_winRun(winRun, winRun+4);
InGameMenu::StrVect InGameMenu::s_winStop(winStop, winStop+3);

static const float GAPSIZE = 1.4f;

void InGameMenu::draw()
{
	GameApp::getInstance().getRenderer().render();

	Mutex2D mutex;
	
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glLoadIdentity();
	glScalef(0.15, 0.15, 1);

	glPushMatrix();
	drawMenu();
	glPopMatrix();
	if (m_times) {
		glPushMatrix();
		drawTimes();
		glPopMatrix();
	}

	GameApp::getInstance().getPhysics().updateCounter();

	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	SDL_GL_SwapBuffers();
}

void InGameMenu::drawMenu()
{
	int size = items.size();
	if (!m_running)
		size += 2;
	if (m_winning)
		++size;
	float height = GAPSIZE*size+0.5f*GAPSIZE;
	glTranslatef(-4, 0.5f*height, 0);
	glColor4f(0.2, 0.4, 1, 0.7);
	const float W=2.5f;
	glBegin(GL_QUADS);
	glVertex2f(-W, 0);
	glVertex2f(-W, -height);
	glVertex2f(W, -height);
	glVertex2f(W, 0);
	glEnd();

	if (!m_running) {
		glLineWidth(2);
		glPointSize(2);
		glTranslatef(0, -GAPSIZE, 0);
		if (m_winning) {
			glColor4f(0, 0.8, 0, 0.9);
			int time = GameApp::getInstance().getPhysics().getCounter().getTime();
			LCD::print("board", LCD::MIDDLE);
			glTranslatef(0, -GAPSIZE, 0);
			LCD::print("pwned", LCD::MIDDLE);
			glTranslatef(0, -GAPSIZE, 0);
			char buf[1024];
			snprintf(buf, sizeof(buf), "in %.02f", time*0.001f);
			LCD::print(buf, LCD::MIDDLE);
		} else {
			glColor4f(1, 0, 0, 0.9);
			LCD::print("board", LCD::MIDDLE);
			glTranslatef(0, -GAPSIZE, 0);
			LCD::print("failed", LCD::MIDDLE);
		}
		glLineWidth(1);
		glPointSize(1);
	}

	glColor4f(0.9, 0.9, 1, 0.9);
	for(StrVect::iterator i=items.begin(); i!=items.end(); ++i) {
		glTranslatef(0, -GAPSIZE, 0);
		if (i == items.begin()+activeItem) {
			glColor4f(0.9, 0.9, 0.2, 0.6);
			glLineWidth(3);
			LCD::print(i->c_str(), LCD::MIDDLE);
			glLineWidth(1);
			glColor4f(0.9, 0.9, 1, 0.9);
		}
		LCD::print(i->c_str(), LCD::MIDDLE);
	}
}

void InGameMenu::drawTimes()
{
	int amount = m_times->amount();
	const float H = amount*GAPSIZE + 0.5f*GAPSIZE;
	glTranslatef(4, H*0.5f, 0);
	const float W = 1.5f;
	glColor4f(0, 0.9, 0, 0.7);
	glBegin(GL_QUADS);
	glVertex2f(-W, 0);
	glVertex2f(-W, -H);
	glVertex2f(W, -H);
	glVertex2f(W, 0);
	glEnd();
	glTranslatef(W*1.2f, 0, 0);

	glColor4f(0.7, 0.7, 0.7, 0.9);
	glLineWidth(2);
	glPointSize(2);
	const int* times = m_times->getTimes();
	char buf[64];
	for(int i=0; i<amount; ++i) {
		glTranslatef(0, -GAPSIZE, 0);
		snprintf(buf, sizeof(buf), "%.02f", 0.001f*times[i]);
		if (i == m_listPlace) {
			glLineWidth(4);
			glPointSize(4);
			glColor4f(1, 1, 0.1, 1);
			LCD::print(buf, LCD::RIGHT);
			glLineWidth(2);
			glColor4f(0.7, 0.7, 0.7, 0.9);
		}
		LCD::print(buf, LCD::RIGHT);
	}
	glLineWidth(1);
	glPointSize(1);
}
