#include "cBuildMainMenu.hpp"

/*** ANSI C Header Files ***/
#include <stdlib.h>     /* strtol */

using MainMenu::cBuildMainMenu;
using MainMenu::cMainMenu;
using UtilityEngine::cUtility;

using tinyxml2::XMLDocument;
using tinyxml2::XMLNode;
using tinyxml2::XMLVisitor;
using tinyxml2::XMLElement;

cBuildMainMenu::cBuildMainMenu()
	: m_ttf(""), m_dir(""), m_lang(""), m_langSettings(""), mp_mainMenu(new cMainMenu())
{}

cBuildMainMenu::~cBuildMainMenu()
{}

///Functions
cMainMenu* cBuildMainMenu::ReadXML()
{
	cString file = "xml/SDLPongCPP.xml";
	XMLDocument doc;

	if ( doc.LoadFile(file.c_str()) == false ) {
		//cUtility::Inst().Message("Could not load file." + file + " Error='" + doc.GetErrorStr1 + "'.");
	} else {
		XMLNode* node = doc.FirstChildElement( "SDLPongCPP" );

		if (node == nullptr) {
			cUtility::Inst().Message("No <SDLPongCPP tag found.");
		} else {
			XMLElement* settingsElement = node->FirstChildElement( "Settings" );
			if (settingsElement == nullptr) {
				cUtility::Inst().Message("No <Settings> tag found.");
			} else {
				m_langSettings = GetAttribute(settingsElement, "lang");
			}
			XMLElement* mainmenuElement = node->FirstChildElement( "MainMenu" );
			while (m_langSettings != m_lang) {
				if (mainmenuElement == nullptr) {
					cUtility::Inst().Message("No <MainMenu> tag found.");
				} else {
					m_lang = GetAttribute(mainmenuElement, "lang");
					/* if the language is the same as the one specified in the settings we read the menu settings */
					if (m_lang == m_langSettings) {
						const char* colour = GetAttribute(mainmenuElement, "colour");
						mp_mainMenu->setColour(IntToSDLColour(HexToInt(colour)));

						const char* selectcolour = GetAttribute(mainmenuElement, "selectcolour");
						mp_mainMenu->setSelectColour(IntToSDLColour(HexToInt(selectcolour)));

						const char* titlecolour = GetAttribute(mainmenuElement, "titlecolour");
						mp_mainMenu->setTitleColour(IntToSDLColour(HexToInt(titlecolour)));

						m_ttf = GetAttribute(mainmenuElement, "ttf");

						const char* soundeffect = GetAttribute(mainmenuElement, "soundeffect");
				
						m_dir = GetAttribute(mainmenuElement, "dir");

						if (m_ttf != "")
							mp_mainMenu->setFont(m_dir + "ttf/", m_ttf);

						mp_mainMenu->setSound(m_dir + "snd/", cString(soundeffect));

						GetOptions( mainmenuElement, "Title" );
						GetOptions( mainmenuElement, "SinglePlayer" );
						GetOptions( mainmenuElement, "HeadToHead" );
						GetOptions( mainmenuElement, "Quit" );
					} else {
						mainmenuElement = mainmenuElement->NextSiblingElement();
					}
				}/* end else */
			}/* end while */
		}
	}
	return mp_mainMenu;
}

void cBuildMainMenu::GetOptions( const XMLElement* element, const cString name )
{
	const XMLElement* titleElement = element->FirstChildElement( name.c_str() );
	if (titleElement == nullptr) {
		cUtility::Inst().Message("Error no tag <" + name + "> found.");
	} else {
		const char* x = GetAttribute(titleElement, "x");
		const char* y = GetAttribute(titleElement, "y");
		const char* size = GetAttribute(titleElement, "size");
		const char* text = titleElement->GetText();
	
		if (name == "Title")
			mp_mainMenu->setTitleText(text, atoi(size), atoi(x), atoi(y));
		if (name == "SinglePlayer")
			mp_mainMenu->setSingleText(text, atoi(size), atoi(x), atoi(y));
		if (name == "HeadToHead")
			mp_mainMenu->setHeadText(text, atoi(size), atoi(x), atoi(y));
		if (name == "Quit")
			mp_mainMenu->setQuitText(text, atoi(size), atoi(x), atoi(y));
	}
}

const char* cBuildMainMenu::GetAttribute( const XMLElement* element, const cString attribute ) const
{
	const char* rtn = element->Attribute(attribute.c_str());
	if (rtn == nullptr) {
		cUtility::Inst().Message("Error no attribute: " + attribute + " found in tag <" + element->Value() + ">");
		rtn = "";
	}
	return rtn;
}

const unsigned long int cBuildMainMenu::HexToInt( const cString str ) const
{
	return strtol(str.c_str(), NULL, 10);
}

const SDL_Colour cBuildMainMenu::IntToSDLColour( const unsigned long int colour ) const
{ 
	SDL_Colour rtn = {255, 255, 255};

	rtn.r = Uint8(colour >> 16);
	rtn.g = Uint8(colour >> 8);
	rtn.b = Uint8(colour);

	return rtn;
}