//	SDL1.2KeyManager.cpp - SDL1.2-specific KeyManager.
//  ----------------------------------------------------------------------------
//	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 "SDL1.2KeyManager.h"

#include <sstream>

using namespace std;

//------------------------------------------------------------------------------
SDL1_2KeyManager::SDL1_2KeyManager()
{

}

//------------------------------------------------------------------------------
SDL1_2KeyManager::~SDL1_2KeyManager()
{

}

//------------------------------------------------------------------------------
void SDL1_2KeyManager::getActions(SDL_keysym& keysym,
								  vector<std::wstring>& actions) const
{
	wstring keyString;

	//First prefix the string with any modifiers.
	if(keysym.mod&KMOD_CTRL)
		keyString = L"Ctrl-";
	if(keysym.mod&KMOD_SHIFT)
		keyString = L"Shift-";
	if(keysym.mod&KMOD_ALT)
		keyString = L"Alt-";
	if(keysym.mod&KMOD_META)
		keyString = L"Meta-";

	//Now write the actual key identifier.
	switch(keysym.sym)
	{
		case SDLK_BACKSPACE:
			keyString.append(L"Backspace");
			break;
		case SDLK_TAB:
			keyString.append(L"Tab");
			break;
		case SDLK_CLEAR:
			keyString.append(L"Clear");
			break;
		case SDLK_RETURN:
			keyString.append(L"Return");
			break;
		case SDLK_PAUSE:
			keyString.append(L"Pause");
			break;
		case SDLK_ESCAPE:
			keyString.append(L"Escape");
			break;
		case SDLK_SPACE:
			keyString.append(L"Space");
			break;
		case SDLK_EXCLAIM:
			keyString.append(L"!");
			break;
		case SDLK_QUOTEDBL:
			keyString.append(L"\"");
			break;
		case SDLK_HASH:
			keyString.append(L"#");
			break;
		case SDLK_DOLLAR:
			keyString.append(L"$");
			break;
		case SDLK_AMPERSAND:
			keyString.append(L"&");
			break;
		case SDLK_QUOTE:
			keyString.append(L"'");
			break;
		case SDLK_LEFTPAREN:
			keyString.append(L"(");
			break;
		case SDLK_RIGHTPAREN:
			keyString.append(L")");
			break;
		case SDLK_ASTERISK:
			keyString.append(L"*");
			break;
		case SDLK_PLUS:
			keyString.append(L"+");
			break;
		case SDLK_COMMA:
			keyString.append(L",");
			break;
		case SDLK_MINUS:
			keyString.append(L"-");
			break;
		case SDLK_PERIOD:
			keyString.append(L".");
			break;
		case SDLK_SLASH:
			keyString.append(L"/");
			break;
		case SDLK_0:
			keyString.append(L"0");
			break;
		case SDLK_1:
			keyString.append(L"1");
			break;
		case SDLK_2:
			keyString.append(L"2");
			break;
		case SDLK_3:
			keyString.append(L"3");
			break;
		case SDLK_4:
			keyString.append(L"4");
			break;
		case SDLK_5:
			keyString.append(L"5");
			break;
		case SDLK_6:
			keyString.append(L"6");
			break;
		case SDLK_7:
			keyString.append(L"7");
			break;
		case SDLK_8:
			keyString.append(L"8");
			break;
		case SDLK_9:
			keyString.append(L"9");
			break;
		case SDLK_COLON:
			keyString.append(L":");
			break;
		case SDLK_SEMICOLON:
			keyString.append(L";");
			break;
		case SDLK_LESS:
			keyString.append(L"<");
			break;
		case SDLK_EQUALS:
			keyString.append(L"=");
			break;
		case SDLK_GREATER:
			keyString.append(L">");
			break;
		case SDLK_QUESTION:
			keyString.append(L"?");
			break;
		case SDLK_AT:
			keyString.append(L"@");
			break;
		case SDLK_LEFTBRACKET:
			keyString.append(L"[");
			break;
		case SDLK_BACKSLASH:
			keyString.append(L"\\");
			break;
		case SDLK_RIGHTBRACKET:
			keyString.append(L"]");
			break;
		case SDLK_CARET:
			keyString.append(L"^");
			break;
		case SDLK_UNDERSCORE:
			keyString.append(L"_");
			break;
		case SDLK_BACKQUOTE:
			keyString.append(L"`");
			break;
		case SDLK_a:
			keyString.append(L"a");
			break;
		case SDLK_b:
			keyString.append(L"b");
			break;
		case SDLK_c:
			keyString.append(L"c");
			break;
		case SDLK_d:
			keyString.append(L"d");
			break;
		case SDLK_e:
			keyString.append(L"e");
			break;
		case SDLK_f:
			keyString.append(L"f");
			break;
		case SDLK_g:
			keyString.append(L"g");
			break;
		case SDLK_h:
			keyString.append(L"h");
			break;
		case SDLK_i:
			keyString.append(L"i");
			break;
		case SDLK_j:
			keyString.append(L"j");
			break;
		case SDLK_k:
			keyString.append(L"k");
			break;
		case SDLK_l:
			keyString.append(L"l");
			break;
		case SDLK_m:
			keyString.append(L"m");
			break;
		case SDLK_n:
			keyString.append(L"n");
			break;
		case SDLK_o:
			keyString.append(L"o");
			break;
		case SDLK_p:
			keyString.append(L"p");
			break;
		case SDLK_q:
			keyString.append(L"q");
			break;
		case SDLK_r:
			keyString.append(L"r");
			break;
		case SDLK_s:
			keyString.append(L"s");
			break;
		case SDLK_t:
			keyString.append(L"t");
			break;
		case SDLK_u:
			keyString.append(L"u");
			break;
		case SDLK_v:
			keyString.append(L"v");
			break;
		case SDLK_w:
			keyString.append(L"w");
			break;
		case SDLK_x:
			keyString.append(L"x");
			break;
		case SDLK_y:
			keyString.append(L"y");
			break;
		case SDLK_z:
			keyString.append(L"z");
			break;
		case SDLK_DELETE:
			keyString.append(L"Delete");
			break;
		case SDLK_KP0:
			keyString.append(L"NumPad0");
			break;
		case SDLK_KP1:
			keyString.append(L"NumPad1");
			break;
		case SDLK_KP2:
			keyString.append(L"NumPad2");
			break;
		case SDLK_KP3:
			keyString.append(L"NumPad3");
			break;
		case SDLK_KP4:
			keyString.append(L"NumPad4");
			break;
		case SDLK_KP5:
			keyString.append(L"NumPad5");
			break;
		case SDLK_KP6:
			keyString.append(L"NumPad6");
			break;
		case SDLK_KP7:
			keyString.append(L"NumPad7");
			break;
		case SDLK_KP8:
			keyString.append(L"NumPad8");
			break;
		case SDLK_KP9:
			keyString.append(L"NumPad9");
			break;
		case SDLK_KP_PERIOD:
			keyString.append(L"NumPad.");
			break;
		case SDLK_KP_DIVIDE:
			keyString.append(L"NumPad/");
			break;
		case SDLK_KP_MULTIPLY:
			keyString.append(L"NumPad*");
			break;
		case SDLK_KP_MINUS:
			keyString.append(L"NumPad-");
			break;
		case SDLK_KP_PLUS:
			keyString.append(L"NumPad+");
			break;
		case SDLK_KP_ENTER:
			keyString.append(L"NumPadEnter");
			break;
		case SDLK_KP_EQUALS:
			keyString.append(L"NumPad=");
			break;
		case SDLK_UP:
			keyString.append(L"CursorUp");
			break;
		case SDLK_DOWN:
			keyString.append(L"CursorDown");
			break;
		case SDLK_LEFT:
			keyString.append(L"CursorLeft");
			break;
		case SDLK_RIGHT:
			keyString.append(L"CursorRight");
			break;
		case SDLK_INSERT:
			keyString.append(L"Insert");
			break;
		case SDLK_HOME:
			keyString.append(L"Home");
			break;
		case SDLK_END:
			keyString.append(L"End");
			break;
		case SDLK_PAGEUP:
			keyString.append(L"PageUp");
			break;
		case SDLK_PAGEDOWN:
			keyString.append(L"PageDown");
			break;
		case SDLK_F1:
			keyString.append(L"F1");
			break;
		case SDLK_F2:
			keyString.append(L"F2");
			break;
		case SDLK_F3:
			keyString.append(L"F3");
			break;
		case SDLK_F4:
			keyString.append(L"F4");
			break;
		case SDLK_F5:
			keyString.append(L"F5");
			break;
		case SDLK_F6:
			keyString.append(L"F6");
			break;
		case SDLK_F7:
			keyString.append(L"F7");
			break;
		case SDLK_F8:
			keyString.append(L"F8");
			break;
		case SDLK_F9:
			keyString.append(L"F9");
			break;
		case SDLK_F10:
			keyString.append(L"F10");
			break;
		case SDLK_F11:
			keyString.append(L"F11");
			break;
		case SDLK_F12:
			keyString.append(L"F12");
			break;
		case SDLK_F13:
			keyString.append(L"F13");
			break;
		case SDLK_F14:
			keyString.append(L"F14");
			break;
		case SDLK_F15:
			keyString.append(L"F15");
			break;
		case SDLK_HELP:
			keyString.append(L"Help");
			break;
		case SDLK_PRINT:
			keyString.append(L"PrintScreen");
			break;
		default: //To avoid gcc warnings.
			break;
	}

	KeyManager::getActions(keyString, actions);
}

//------------------------------------------------------------------------------
void SDL1_2KeyManager::getActions(SDL_JoyAxisEvent& event,
								  vector<std::wstring>& actions) const
{
	wstringstream keyString;

	keyString << L"Joy" << event.which;

	//x-axis.
	if(event.axis == 0)
	{
		if(event.value < 128) //128 so there's a bit of a dead zone.
			keyString << L"Left";
		else if(event.value > 128)
			keyString << L"Right";
		else
			keyString << L"Centre";
	}
	//y-axis.
	else if(event.axis == 1)
	{
		if(event.value < 128)
			keyString << L"Up";
		else if(event.value > 128)
			keyString << L"Down";
		else
			keyString << L"Centre";
	}
	//Triggers.
	else if(event.axis == 2)
	{
		if(event.value < 128)
			keyString << L"TriggerLeft";
		else if(event.value > 128)
			keyString << L"TriggerRight";
		else
			keyString << L"TriggerCentre";
	}
	//x-axis 2.
	else if(event.axis == 3)
	{
		if(event.value < 128)
			keyString << L"Left2";
		else if(event.value > 128)
			keyString << L"Right2";
		else
			keyString << L"Centre2";
	}
	//y-axis 2.
	else if(event.axis == 4)
	{
		if(event.value < 128)
			keyString << L"Up2";
		else if(event.value > 128)
			keyString << L"Down2";
		else
			keyString << L"Centre2";
	}

	KeyManager::getActions(keyString.str(), actions);
}

//------------------------------------------------------------------------------
void SDL1_2KeyManager::getActions(SDL_JoyButtonEvent& event,
								  vector<std::wstring>& actions) const
{
	wstringstream keyString;

	keyString << L"Joy" << event.which << L"Button" << event.button;

	KeyManager::getActions(keyString.str(), actions);
}

//------------------------------------------------------------------------------
void SDL1_2KeyManager::getActions(SDL_JoyHatEvent& event,
								  vector<std::wstring>& actions) const
{
	wstringstream keyString;

	keyString << L"Joy" << event.which << L"Hat" << event.hat;

	if(event.value&SDL_HAT_CENTERED)
		keyString << L"Centre";
	else
	{
		if(event.value&SDL_HAT_UP)
			keyString << L"Up";
		else if(event.value&SDL_HAT_DOWN)
			keyString << L"Down";
		if(event.value&SDL_HAT_LEFT)
			keyString << L"Left";
		else if(event.value&SDL_HAT_RIGHT)
			keyString << L"Right";
	}

	KeyManager::getActions(keyString.str(), actions);
}

//------------------------------------------------------------------------------
int SDL1_2KeyManager::getModVal(SDLMod& mod) const
{
	int retval = 0;

	if(mod&KMOD_CTRL)
		retval = 1;
	if(mod&KMOD_SHIFT)
		retval = 2;
	if(mod&KMOD_ALT)
		retval = 3;
	if(mod&KMOD_META)
		retval = 4;

	return retval;
}

//------------------------------------------------------------------------------
wstring SDL1_2KeyManager::getJoyButtonText(SDL_JoyButtonEvent& event) const
{
	wstringstream keyString;

	keyString << L"Joy" << event.which << L"Button" << event.button;

	return keyString.str();
}

//------------------------------------------------------------------------------
wstring SDL1_2KeyManager::getJoyHatText(SDL_JoyHatEvent& event) const
{
	wstringstream keyString;

	keyString << L"Joy" << event.which << L"Hat" << event.hat;

	if(event.value&SDL_HAT_CENTERED)
		keyString << L"Centre";
	else
	{
		if(event.value&SDL_HAT_UP)
			keyString << L"Up";
		else if(event.value&SDL_HAT_DOWN)
			keyString << L"Down";
		if(event.value&SDL_HAT_LEFT)
			keyString << L"Left";
		else if(event.value&SDL_HAT_RIGHT)
			keyString << L"Right";
	}

	return keyString.str();
}
