//	AppSettingsExample.cpp - Example of how to implement the unimplemented
//							 AppSettings bits.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  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 "ColourHelpers.h"
#include "DebugHeaders.h"
#include "AppSettings.h"
#include "Application.h"
#include "Random.h"

#include "GamePlayState.h"

#include "EXCOSCSounder.h"

#include "drawing/GLImmediateDrawer.h"
#include "drawing/GLESDrawer.h"
#include "GlobalData.h"

#include <sstream>

using std::wstringstream;
using std::wstring;

//------------------------------------------------------------------------------
wstring AppSettings::applicationName = L"EXCOSC Base";
wstring AppSettings::applicationVersion = L"1.00";

//------------------------------------------------------------------------------
void AppSettings::initialise(CmdLineParams& cmdLine,
							 Application *app,
							 KeyManager& keyManager,
							 wstring& helpText)
{
	//Register your interest in any command line arguments.
	cmdLine.registerCallback(L"Listen Port", L"--listenPort", L"-lp", true, L"5678", this);
	cmdLine.registerCallback(L"Send Address", L"--sendAddress", L"-sa", true, L"127.0.0.1", this);
	cmdLine.registerCallback(L"Send Port", L"--sendPort", L"-sp", true, L"5679", this);

	//Setup the dimensions of the drawing area.
	setDrawingDimensions(1280, 720, AlterRatio);

	//Register all possible GameStates.
	app->registerGameState(L"GamePlayState", &GamePlayState::creator, true);

	//Setup some default key mappings.
	// - Player 1 movement.
	keyManager.addMapping(L"P1Up", L"w", true);
	keyManager.addMapping(L"P1Left", L"a", true);
	keyManager.addMapping(L"P1Right", L"d", true);
	keyManager.addMapping(L"P1Down", L"s", true);
	keyManager.addMapping(L"P1Fire", L"Space", true);

	keyManager.addMapping(L"P1Up", L"Joy0Up", true);
	keyManager.addMapping(L"P1Left", L"Joy0Left", true);
	keyManager.addMapping(L"P1Right", L"Joy0Right", true);
	keyManager.addMapping(L"P1Down", L"Joy0Down", true);
	keyManager.addMapping(L"P1TriggerRight", L"Joy0TriggerRight", true);
	keyManager.addMapping(L"P1TriggerLeft", L"Joy0TriggerLeft", true);
#ifdef OSX
	keyManager.addMapping(L"P1Fire", L"Joy0Button11", true);
#else
	keyManager.addMapping(L"P1Fire", L"Joy0Button0", true);
#endif
	keyManager.addMapping(L"P1SecondaryUp", L"Joy0Up2", true);
	keyManager.addMapping(L"P1SecondaryLeft", L"Joy0Left2", true);
	keyManager.addMapping(L"P1SecondaryRight", L"Joy0Right2", true);
	keyManager.addMapping(L"P1SecondaryDown", L"Joy0Down2", true);

	// - Player 2 movement.
	keyManager.addMapping(L"P2Up", L"CursorUp", true);
	keyManager.addMapping(L"P2Left", L"CursorLeft", true);
	keyManager.addMapping(L"P2Right", L"CursorRight", true);
	keyManager.addMapping(L"P2Down", L"CursorDown", true);
	keyManager.addMapping(L"P2Fire", L"Return", true);

	keyManager.addMapping(L"P2Up", L"Joy1Up", true);
	keyManager.addMapping(L"P2Left", L"Joy1Left", true);
	keyManager.addMapping(L"P2Right", L"Joy1Right", true);
	keyManager.addMapping(L"P2Down", L"Joy1Down", true);
	keyManager.addMapping(L"P2TriggerRight", L"Joy1TriggerRight", true);
	keyManager.addMapping(L"P2TriggerLeft", L"Joy1TriggerLeft", true);
#ifdef OSX
	keyManager.addMapping(L"P2Fire", L"Joy1Button11", true);
#else
	keyManager.addMapping(L"P2Fire", L"Joy1Button0", true);
#endif
	keyManager.addMapping(L"P2SecondaryUp", L"Joy1Up2", true);
	keyManager.addMapping(L"P2SecondaryLeft", L"Joy1Left2", true);
	keyManager.addMapping(L"P2SecondaryRight", L"Joy1Right2", true);
	keyManager.addMapping(L"P2SecondaryDown", L"Joy1Down2", true);

	// - General.
	keyManager.addMapping(L"Escape", L"Escape", true);

#ifdef OSX
	keyManager.addMapping(L"Escape", L"Joy0Button5", true);
	keyManager.addMapping(L"Escape", L"Joy1Button5", true);
#else
	keyManager.addMapping(L"Escape", L"Joy0Button6", true);
	keyManager.addMapping(L"Escape", L"Joy1Button6", true);
#endif
	keyManager.addMapping(L"Restart", L"r", true);
#ifdef OSX
	keyManager.addMapping(L"Restart", L"Joy0Button4", true);
	keyManager.addMapping(L"Restart", L"Joy1Button4", true);
#else
	keyManager.addMapping(L"Restart", L"Joy0Button7", true);
	keyManager.addMapping(L"Restart", L"Joy1Button7", true);
#endif

	//Fill out helpText.

	//Set the LoadingScreen colours.
	{
		int i;
		ThreeFloats cols[3];

		cols[0].x = Random::getGlobal().getRandomFloat();
		cols[0].y = 0.9f;
		cols[0].z = 0.66f;
		for(i=1;i<3;++i)
		{
			cols[i] = cols[0];
			cols[i].x = cols[i-1].x + 0.33f;
		}
		for(i=0;i<3;++i)
			cols[i] = ColourHelpers::hslToRgb(cols[i]);
		setLoadingColours(cols[0],
						  cols[1],
						  cols[2],
						  ThreeFloats(1.0f));
	}
}

//------------------------------------------------------------------------------
DrawerPtr AppSettings::getDrawer(const std::wstring& drawerType)
{
	if(drawerType == L"GLImmediateDrawer")
		return DrawerPtr(new GLImmediateDrawer());
	else
	{
		if(GLESDrawer::isSupported())
			return DrawerPtr(new GLESDrawer());
		else
		{
			DebugStatement(L"GLESDrawer not supported. Falling back to GLImmediateDrawer");
			return DrawerPtr(new GLImmediateDrawer());
		}
	}
}

//------------------------------------------------------------------------------
SounderPtr AppSettings::getSounder()
{
	return SounderPtr(new EXCOSCSounder());
}

//------------------------------------------------------------------------------
GlobalDataPtr AppSettings::getGlobalData()
{
	return GlobalDataPtr(new GlobalData());
}

