#include "MW4Headers.hpp"

#include "MWTable.hpp"

#include <Adept\Resource.hpp>

//#############################################################################
//#########################     MWTableEntry   ################################
//#############################################################################

MWTableEntry::MWTableEntry(MemoryStream *stream) : 
	Plug(Plug::DefaultData)
{
	Check_Pointer(stream);
	
	*stream >> m_data;
	*stream >> m_entryResourceID;
//	*stream >> m_entryID;
	m_entryID = -1;
	*stream >> m_entryName;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 
void
	MWTableEntry::ConstructEntryStream(Note *note, MemoryStream *stream)
{
	Check_Object(note);
	Check_Pointer(stream);
	
	const char *resource_name;
	note->GetEntry(&resource_name);
	Resource entry_resource(resource_name);
	ResourceID entry_id = ResourceID::Null;

	if(entry_resource.DoesResourceExist())
	{
		entry_id = entry_resource.GetResourceID();
	}
	MString data = resource_name;

	*stream << data;
	*stream << entry_resource.GetResourceID();

	MString entry_name = note->GetName();
	*stream << entry_name;
}

//#############################################################################
//############################     MWTable   ##################################
//#############################################################################

MWTable::MWTable(Stuff::MemoryStream *stream) :
	Plug(Plug::DefaultData),
	m_table(NULL, true)
{
	Check_Pointer(stream);

	while(stream->GetBytesRemaining() > 0)
	{
		MWTableEntry *entry;
		entry = new MWTableEntry(stream);
		Check_Object(entry);

		m_table.AddValue(entry, entry->GetEntryName());
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 
void
	MWTable::ConstructTableStream(NotationFile *note_file, MemoryStream *stream)
{
	Check_Object(note_file);
	Check_Pointer(stream);
	
	Page *page = note_file->GetPage("Table");
	ChainIteratorOf<Note*> *note_iterator = page->MakeNoteIterator();
	Check_Object(note_iterator);
	note_iterator->First();
	Note *note;
	while((note = note_iterator->ReadAndNext()) != NULL)
	{
		Check_Object(note);
		MWTableEntry::ConstructEntryStream(note, stream);
	}	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 
MWTableEntry*
	MWTable::FindEntry(MString entry_name)
{
	//Ok we can't just use the find since we have to perserve case in some of the tables
	Check_Object(this);
	SortedChainIteratorOf<MWTableEntry *, MString> iterator(&m_table);
	MString table_string = iterator.GetValue();
	while(iterator.GetCurrent())
	{
		if(!_stricmp((const char *)entry_name, (const char *)table_string))
			return iterator.GetCurrent();
		iterator.Next();
		if(iterator.GetCurrent())
			table_string = iterator.GetValue();
	}
	return NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 
MWTableEntry*
	MWTable::FindEntryFromDataString(Stuff::MString data)
{
	Check_Object(this);
	SortedChainIteratorOf<MWTableEntry *, MString> iterator(&m_table);
	MWTableEntry *table_entry;
	while((table_entry = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(table_entry);
		if(!_stricmp((const char *)table_entry->GetData(), (const char *)data))
			return table_entry;
	}

	return NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 
int
	MWTable::FindIndexFromDataString(Stuff::MString data)
{
	Check_Object(this);
	SortedChainIteratorOf<MWTableEntry *, MString> iterator(&m_table);
	MWTableEntry *table_entry;
	int count = 0;
	while((table_entry = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(table_entry);
		if(!_stricmp((const char *)table_entry->GetData(), (const char *)data))
			return count;
		count++;
	}

	return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 
MWTable::~MWTable()
{
	Check_Object(this);

	m_table.DeletePlugs();
}