
#include "MW4Headers.hpp"

#include "AI_Types.hpp"




using namespace MW4AI;

Types* Types::m_Instance = 0;

Types::Types()
	: m_RefCount(0)
	, m_Resource("ai\\ai.types")
{
	Verify(m_Resource.DoesResourceExist());

	m_Resource.LoadData();
	m_NotationFile.Assimilate(new Stuff::NotationFile(&m_Resource));

	Verify(m_NotationFile.GetPointer() != 0);

	Stuff::NotationFile::PageIterator* page_iter = m_NotationFile->MakePageIterator();
	Stuff::Page* page;

	while((page = page_iter->ReadAndNext()) != NULL)
	{
		Check_Object(page);
		ReadPage(*page);
	}

	delete page_iter;
}

Types::~Types()
{
	while (m_Types.size() > 0)
	{
		delete (*(m_Types.begin()));
		m_Types.erase(m_Types.begin());
	}
}

	void GetNoteEntry(Stuff::Note& note, std::string& value)
	{
		const char* char_ptr;
		note.GetEntry(&char_ptr);

		value = char_ptr;
	}

	void GetNoteEntry(Stuff::Note& note, Stuff::Scalar& value)
	{
		note.GetEntry(&value);
	}

	void GetNoteEntry(Stuff::Note& note, int value)
	{
		note.GetEntry(&value);
	}

void Types::ReadPage(Stuff::Page& page)
{
	Stuff::Note* type = page.FindNote("type");

	if (type == 0)
	{
		return;
	}

	std::string type_name;
	GetNoteEntry(*type,type_name);

	Type* new_type = 0;

	if (type_name == "integer")
		new_type = new Type_Integer(page);
	else if (type_name == "string")
		new_type = new Type_String(page);
	else if (type_name == "real")
		new_type = new Type_Real(page);
	else
		return;

	m_Types.push_back(new_type);
}

void Types::IncrementRefCount()
{
	if (m_Instance == 0)
	{
		m_Instance = new Types();
	}

	++m_Instance->m_RefCount;
}

void Types::DecrementRefCount()
{
	Verify(m_Instance != 0);
	Verify(m_Instance->m_RefCount > 0);

	--(m_Instance->m_RefCount);

	if (m_Instance->m_RefCount == 0)
	{
		delete m_Instance;
		m_Instance = 0;
	}
}

Types* Types::Instance()
{
	return (m_Instance);
}

#define GET_IF_FOUND(string_name,data_member) \
	Stuff::Note* note_##data_member = page.FindNote(string_name);	\
	if (note_##data_member != 0) { GetNoteEntry(*note_##data_member,data_member); }

Type::Type(Stuff::Page& page)
{
	m_Name = page.GetName();

	GET_IF_FOUND("default_text",m_DefaultText);
	GET_IF_FOUND("display",m_Display);
	GET_IF_FOUND("values",m_Values);
}

Type_Integer::Type_Integer(Stuff::Page& page)
	: Type(page)
	, m_Min(0)
	, m_Max(100)
	, m_Default(50)
{
	GET_IF_FOUND("min",m_Min);
	GET_IF_FOUND("max",m_Max);
	GET_IF_FOUND("default",m_Default);
}

Type_Real::Type_Real(Stuff::Page& page)
	: Type(page)
	, m_Min(0)
	, m_Max(1)
	, m_Default(0.5f)
{
	GET_IF_FOUND("min",m_Min);
	GET_IF_FOUND("max",m_Max);
	GET_IF_FOUND("default",m_Default);
}

Type_String::Type_String(Stuff::Page& page)
	: Type(page)
{
}
