//	TitleScreen.cpp - The title screen state.
//  ----------------------------------------------------------------------------
//	This file is part of 'GameTemplate', template code for a game.
//	Copyright (C) 2011  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#include "TonesGlobalData.h"
#include "drawing/Drawer.h"
#include "PitchFactory.h"
#include "DebugHeaders.h"
#include "TonesSounder.h"
#include "TitleScreen.h"
#include "Random.h"

#include <algorithm>
#include <sstream>

using namespace std;

//------------------------------------------------------------------------------
GameStateCreator<TitleScreen> TitleScreen::creator;

//------------------------------------------------------------------------------
TitleScreen::TitleScreen(Application& app, SounderPtr& sound):
GameState(app, sound),
gameCore(dynamic_pointer_cast<TonesSounder>(sound)),
mouseOverSurvival(false),
mouseOverFreePlay(false),
mouseOverTimeAttack(false),
mouseOverExit(false),
mouseOverPure(false),
mouseOverZen(false),
mouseOverLow(false),
sounder(dynamic_pointer_cast<TonesSounder>(sound))
{
	globalData = dynamic_pointer_cast<TonesGlobalData>(getGlobalData());

	mousePos.x = 640;
	mousePos.y = 360;

	gameCore.setDontDrawPlayer(true);
	gameCore.setAllTonesAuto(true);
	gameCore.setGameCounter(globalData->getCounter());

	globalData->getCounter()->incrementCount(L"Lives", 3, false);

	sounder->setPitches(PitchFactory::getInstance().getPitches(5));
	gameCore.setNumRails(5);
	sounder->setLowMode(globalData->getLow());
}

//------------------------------------------------------------------------------
TitleScreen::~TitleScreen()
{
	
}

//------------------------------------------------------------------------------
void TitleScreen::update()
{
	gameCore.tick();
}

//------------------------------------------------------------------------------
void TitleScreen::draw(DrawerPtr& d, float timestepInterp)
{
	std::wstringstream tempstr;
	TwoFloats tempStart, tempEnd;

	//Draw the core of the game.
	gameCore.draw(d, timestepInterp);

	//Draw the buttons.
	if(mouseOverSurvival)
	{
		d->drawImage(L"survival",
					 TwoFloats(50.0f, 339.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.33f));

		tempstr << L"Hi: " << globalData->getChallengeHighScore() << "\n";
		tempstr << L"Last: " << globalData->getChallengeLastScore();

		d->drawText(tempstr.str(),
					L"Font0",
					TwoFloats(20.0f, 60.0f),
					768.0f,
					TextLayout::Left,
					1.0f,
					0.75f);
	}
	else
	{
		d->drawImage(L"survival",
					 TwoFloats(50.0f, 339.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.5f));
	}
	if(mouseOverTimeAttack)
	{
		d->drawImage(L"timeAttack",
					 TwoFloats(50.0f, 428.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.33f));

		tempstr << L"Hi: " << globalData->getTimeAttackHighScore() << "\n";
		tempstr << L"Last: " << globalData->getTimeAttackLastScore();

		d->drawText(tempstr.str(),
					L"Font0",
					TwoFloats(20.0f, 60.0f),
					768.0f,
					TextLayout::Left,
					1.0f,
					0.75f);
	}
	else
	{
		d->drawImage(L"timeAttack",
					 TwoFloats(50.0f, 428.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.5f));
	}
	if(mouseOverExit)
	{
		d->drawImage(L"exit",
					 TwoFloats(50.0f, 518.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.33f));
	}
	else
	{
		d->drawImage(L"exit",
					 TwoFloats(50.0f, 518.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.5f));
	}

	if(mouseOverPure)
	{
		d->drawImage(L"tickBack",
					 TwoFloats(1059.0f, 464.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.33f));
	}
	else
	{
		d->drawImage(L"tickBack",
					 TwoFloats(1059.0f, 464.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.5f));
	}
	d->drawImage(L"pure", TwoFloats(1128.0f, 507.0f-30.0f));
	if(globalData->getPure())
		d->drawImage(L"tick", TwoFloats(1059.0f, 464.0f));

	if(mouseOverZen)
	{
		d->drawImage(L"tickBack",
					 TwoFloats(1059.0f, 527.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.33f));
	}
	else
	{
		d->drawImage(L"tickBack",
					 TwoFloats(1059.0f, 527.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.5f));
	}
	d->drawImage(L"zen", TwoFloats(1128.0f, 570.0f-30.0f));
	if(globalData->getZen())
		d->drawImage(L"tick", TwoFloats(1059.0f, 527.0f));

	if(mouseOverLow)
	{
		d->drawImage(L"tickBack",
					 TwoFloats(1059.0f, 590.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.33f));
	}
	else
	{
		d->drawImage(L"tickBack",
					 TwoFloats(1059.0f, 590.0f),
					 TwoFloats(1.0f),
					 ThreeFloats(0.5f));
	}
	d->drawImage(L"low", TwoFloats(1128.0f, 633.0f-30.0f));
	if(globalData->getLow())
		d->drawImage(L"tick", TwoFloats(1059.0f, 590.0f));

	//Draw the mouse.
	d->drawImage(L"mouse", mousePos-13.0f, TwoFloats(1.0f), ThreeFloats(0.5f));

	//Draw the title.
	d->drawImage(L"title", TwoFloats(421.0f, 33.0f));
}

//------------------------------------------------------------------------------
void TitleScreen::keyDown(const std::wstring& action,
				 const std::wstring& keyPressed,
				 int keyModifier)
{
	if(action == L"Escape")
		quit();
	else if(keyPressed ==L"p")
		nextState(L"PitchSetEditor");
}

//------------------------------------------------------------------------------
void TitleScreen::mouseDown(int button, const TwoFloats& pos)
{
	stringstream tempstr;

	const TwoFloats survivalTL(50, 339);
	const TwoFloats timeAttackTL(50, 428);
	const TwoFloats exitTL(50, 518);

	const TwoFloats pureTL(1059, 464);
	const TwoFloats zenTL(1059, 527);
	const TwoFloats lowTL(1059, 590);

	const TwoFloats survivalBR(50+295, 339+60);
	const TwoFloats timeAttackBR(50+455, 428+72);
	const TwoFloats exitBR(50+238, 518+58);

	const TwoFloats pureBR(1059+162, 464+54);
	const TwoFloats zenBR(1059+162, 527+54);
	const TwoFloats lowBR(1059+162, 590+54);

	mouseOverSurvival = false;
	mouseOverFreePlay = false;
	mouseOverTimeAttack = false;
	mouseOverExit = false;

	mouseOverPure = false;
	mouseOverZen = false;
	mouseOverLow = false;

	mousePos = pos;

	if((mousePos > pureTL) && (mousePos < pureBR))
		globalData->setPure(!globalData->getPure());
	else if((mousePos > zenTL) && (mousePos < zenBR))
		globalData->setZen(!globalData->getZen());
	else if((mousePos > lowTL) && (mousePos < lowBR))
	{
		globalData->setLow(!globalData->getLow());
		sounder->setLowMode(globalData->getLow());
	}
	else if((mousePos > survivalTL) && (mousePos < survivalBR))
		nextState(L"Challenge");
	else if((mousePos > timeAttackTL) && (mousePos < timeAttackBR))
		nextState(L"TimeAttack");
	else if((mousePos > exitTL) && (mousePos < exitBR))
		quit();
}

//------------------------------------------------------------------------------
void TitleScreen::mouseMove(const TwoFloats& pos)
{
	const TwoFloats survivalTL(50, 339);
	const TwoFloats timeAttackTL(50, 428);
	const TwoFloats exitTL(50, 518);

	const TwoFloats pureTL(1059, 464);
	const TwoFloats zenTL(1059, 527);
	const TwoFloats lowTL(1059, 590);

	const TwoFloats survivalBR(50+295, 339+60);
	const TwoFloats timeAttackBR(50+455, 428+72);
	const TwoFloats exitBR(50+238, 518+58);

	const TwoFloats pureBR(1059+162, 464+54);
	const TwoFloats zenBR(1059+162, 527+54);
	const TwoFloats lowBR(1059+162, 590+54);

	mouseOverSurvival = false;
	mouseOverFreePlay = false;
	mouseOverTimeAttack = false;
	mouseOverExit = false;

	mousePos = pos;

	mouseOverPure = false;
	mouseOverZen = false;
	mouseOverLow = false;

	if((mousePos > pureTL) && (mousePos < pureBR))
		mouseOverPure = true;
	else if((mousePos > zenTL) && (mousePos < zenBR))
		mouseOverZen = true;
	else if((mousePos > lowTL) && (mousePos < lowBR))
		mouseOverLow = true;
	else if((mousePos > survivalTL) && (mousePos < survivalBR))
		mouseOverSurvival = true;
	else if((mousePos > timeAttackTL) && (mousePos < timeAttackBR))
		mouseOverTimeAttack = true;
	else if((mousePos > exitTL) && (mousePos < exitBR))
		mouseOverExit = true;
}

//------------------------------------------------------------------------------
/*void TitleScreen::collisionDetection()
{
	int i, j;
	float dist;
	TwoFloats dot1Pos;
	vector<int> dotsToDelete;

	for(i=0;i<(int)dots.size();++i)
	{
		dot1Pos = dots[i]->getPosition();

		if(dot1Pos.x < 8)
			continue;

		for(j=(i+1);j<(int)dots.size();++j)
		{
			dist = dots[j]->getPosition().getDistance(dot1Pos);

			if(dist < 15)
			{
				if(find(dotsToDelete.begin(), dotsToDelete.end(), i) == dotsToDelete.end())
					dotsToDelete.push_back(i);
				if(find(dotsToDelete.begin(), dotsToDelete.end(), j) == dotsToDelete.end())
					dotsToDelete.push_back(j);

				crashes.push_back(NiallNew Crash(dot1Pos.x, dot1Pos.y, dots[j]->getColour()));
				dots[j]->setCollided();

				break;
			}
		}
	}

	//Make sure the indices of the dots we're deleting are in ascending order
	//or we'll end up deleting the wrong ones.
	sort(dotsToDelete.begin(), dotsToDelete.end());
	for(i=((int)dotsToDelete.size()-1);i>=0;--i)
	{
		delete dots[dotsToDelete[i]];
		dots.erase(dots.begin()+dotsToDelete[i]);
	}
}

//------------------------------------------------------------------------------
void TitleScreen::collisionAvoidance()
{
	float tempf;
	TwoFloats temp2f;
	unsigned int i, j;
	TwoFloats dot1Pos, dot2Pos;

	for(i=0;i<dots.size();++i)
	{
		dot1Pos = dots[i]->getPosition();
		for(j=0;j<dots.size();++j)
		{
			dot2Pos = dots[j]->getPosition();
			if(i != j)
			{
				if(dot2Pos.x < dot1Pos.x)
				{
					if(dot1Pos.getDistance(dot2Pos) < 128.0f)
					{
						tempf = Random::getGlobal().getRandomFloat() > 0.5f ? 1.0f : -1.0f;

						temp2f = dot1Pos;
						temp2f.y += tempf;
						dots[i]->attract(temp2f);
					}
				}
			}
		}
	}
}*/
