#include "cGUI.hpp"

/*** Custom Header Files ***/
#include "../VideoEngine/cVideo.hpp"

#include "../UtilityEngine/cUtility.hpp"
#include "GUIHelpers/Enums.hpp"
#include "cButton.hpp"

#include "GUIHelpers/cXMLoader.hpp"

using GUIEngine::cGUI;

using UtilityEngine::cUtility;

/*static*/ cGUI* cGUI::sp_inst = nullptr;

//private
cGUI::cGUI()
	: m_debugLevel(0), mp_font(nullptr), m_inited(false)
{
	setTextColour();
	setPadding();
}

cGUI::~cGUI()
{
	delete mp_font;
	mp_font = nullptr;

	for (int i = 0; i < m_children.size(); ++i) {
		delete m_children[i];
		m_children[i] = nullptr;
	}
	m_children.clear();
}

//public:
///Functions
/*static*/ cGUI& cGUI::Inst()
{
	if (sp_inst == nullptr)
	    sp_inst = new cGUI();
	return *sp_inst;
}

/*static*/ void cGUI::Delete()
{
	delete sp_inst;
	sp_inst = nullptr;
}

const bool cGUI::Initialize( const cString& filename, const cString& dir /*= ""*/, const unsigned long int size /*= 16*/ )
{
	bool rtn = IsInit();

	GUIHelpers::cXMLoader xml;
	xml.Load(filename, dir);
	//GUIHelpers::cXMLoader::Inst().Load(filename, dir);
// 	if (rtn == false) {
// 		setFont( filename, dir, size );
// 		cUtility::Inst().Message("GUI initialized.");
// 	}

	return rtn;
}

void cGUI::Event(const MathEngine::iVector2& location, const eGUIEventType& type)
{
	location;
	type;
// 	std::vector<GUIHelpers::cObject*>::iterator it;
// 
// 	for (it = m_objects.begin(); it < m_objects.end(); it++) {
// 		switch ((*it)->getType()) {
// 		case GUIHelpers::eType::CBUTTON:
// 			cButton* tmp = (cButton*)(*it);
// 			if (tmp->InSide(location) == true)
// 				cUtility::Inst().Message("Button Inside!");
// 			break;
// 		}
// 	}
}

const MathEngine::iVector2 cGUI::DisplayArea() const
{
	MathEngine::iVector2 rtn = { 0, 0 };
	rtn.x = VideoEngine::cVideo::Inst().getWidth();
	rtn.y = VideoEngine::cVideo::Inst().getHeight();

	return rtn;
}

void cGUI::AddObject( GUIEngine::cWindow* obj )
{
	m_children.push_back(obj);
}

std::vector<GUIEngine::cWindow*>& cGUI::GetObjects()
{
	return m_children;
}

void cGUI::Display()
{
	//m_obj->Display();
	std::vector<GUIEngine::cWindow*>::iterator it;

	for (it = m_children.begin(); it < m_children.end(); it++) {
		(*it)->Display();
	}
}

///Sets
void cGUI::setDebugLevel(const unsigned long int debugLevel)
{
	m_debugLevel = debugLevel;
}

void cGUI::setFont( TextTypeEngine::cFont* font )
{
	delete mp_font;
	mp_font = nullptr;

	mp_font = font;
}

void cGUI::setFont( const cString& filename, const cString& dir /*= ""*/, const unsigned long int size /*= 16*/)
{
	delete mp_font;
	mp_font = nullptr;

	mp_font = new TextTypeEngine::cFont( dir, filename, size );
}

void cGUI::setTextColour( const GUIHelpers::RGBA& colour )
{
	//cWindow::sCOLOUR = colour;
}

void cGUI::setTextColour( const unsigned long int red /*= 0*/, const unsigned long int green /*= 0*/, const unsigned long int blue /*= 0*/ )
{
	GUIHelpers::RGBA colour = {Uint8(red), Uint8(green), Uint8(blue)};
	setTextColour(colour);
}

void cGUI::setPadding( const GUIHelpers::Padding& padding )
{
	//cWindow::sPADDING = padding;
}

void cGUI::setPadding( const unsigned int top /*= 5*/, const unsigned int right /*= 5*/, const unsigned int bottom /*= 5*/, const unsigned int left /*= 5*/ )
{
	setPadding(GUIHelpers::Padding(top, right, bottom, left));
}

void cGUI::setAlign( const GUIHelpers::eAlign& align /*= GUIHelpers::eAlign::CENTER*/ )
{
	//cWindow::sALIGN = align;
}

///Gets
const unsigned long int cGUI::getDebugLevel() const
{
	return m_debugLevel;
}

TextTypeEngine::cFont* cGUI::getFont()
{
	return mp_font;
}

const GUIHelpers::RGBA& cGUI::getTextColour() const
{
	return {};//cWindow::sCOLOUR;
}

void cGUI::getTextColour( unsigned long int& red, unsigned long int& green, unsigned long int& blue ) const
{
// 	red = cWindow::sCOLOUR.r;
// 	green = cWindow::sCOLOUR.g;
// 	blue = cWindow::sCOLOUR.b;
}

const GUIHelpers::Padding& cGUI::getPadding() const
{
	/*return cWindow::sPADDING;*/
	return{};
}

void cGUI::getPadding( unsigned int& top, unsigned int& right, unsigned int& bottom, unsigned int& left ) const
{
// 	top = cWindow::sPADDING.x;
// 	right = cWindow::sPADDING.y;
// 	bottom = cWindow::sPADDING.z;
// 	left = cWindow::sPADDING.w;
}

const GUIHelpers::eAlign& cGUI::getAlign() const
{
	/*return cWindow::sALIGN;*/
	return GUIHelpers::eAlign::CENTER;
}

const bool cGUI::IsInit() const
{
	bool rtn = m_inited;

	if (rtn == true)
		cUtility::Inst().Message("GUI is initialized.");
	else
		cUtility::Inst().Message("GUI is not initialized.");

	return rtn;
}