
#include "MW4Headers.hpp"

#include "MaterialEffectHolder.hpp"

#include <Adept\Tool.hpp>

//#############################################################################
//###########################    MaterialEffectHolder   #######################
//#############################################################################

MaterialEffectHolder::ClassData*
	MaterialEffectHolder::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MaterialEffectHolder::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MaterialEffectHolderClassID,
			"MechWarrior4::MaterialEffectHolder",
			Plug::DefaultData
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MaterialEffectHolder::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MaterialEffectHolder::MaterialEffectHolder(
	ClassData *class_data,
	MemoryStream *stream
):
	Plug(class_data),
	effectChain(NULL, true)
{
	Check_Pointer(this);
	Check_Object(stream);

	LoadEffectsChain(stream);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MaterialEffectHolder::LoadEffectsChain(MemoryStream *stream)
{
	Check_Object(this);
	Check_Pointer(this);

	ResourceID temp_id;
	int material_type;

	while (stream->GetBytesRemaining() > 0)
	{
		*stream >> material_type;
		*stream >> temp_id;

		Stuff::PlugOf<Adept::ResourceID> *plug;
		plug = new Stuff::PlugOf<Adept::ResourceID>(temp_id);

		effectChain.AddValue(plug, material_type);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MaterialEffectHolder::ConstructStream(
		MemoryStream *stream,
		NotationFile *model_file
	)	
{
	Check_Object(model_file);
	Stuff::NameList *effects_list;
	Stuff::NameList::Entry *effects_entry;
	effects_list = model_file->MakeEntryList("EffectList", "Effect");
	Register_Object(effects_list);
	effects_entry = effects_list->GetFirstEntry();
	while (effects_entry != NULL)
	{
		Check_Object(effects_entry);
		const char *effect_data = effects_entry->GetChar();
		Check_Pointer(effects_entry);			

		MString entry_string;
		MString effect_file_name;

		entry_string = effect_data;
		effect_file_name = entry_string.GetNthToken(0, ",");

		Check_Object(Tool::Instance);
		Check_Object(ResourceManager::Instance);
		Resource effect_resource;
		Tool::Instance->ConstructDataList(&effect_resource, effect_file_name);
		Check_Object(&effect_resource);
		Verify(effect_resource.DoesResourceExist());
		MString material_name;
		material_name = entry_string.GetNthToken(1, ",");
		int material_num = MaterialEffectHolder::MaterialTypeTextToAscii(material_name);

		*stream << material_num;
		*stream << effect_resource.GetResourceID();
		effects_entry = effects_entry->GetNextEntry();
	}
	delete effects_list;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceID
	MaterialEffectHolder::GetEffectResource(int material)
{
	Check_Object(this);
	Verify(material>=0);
	Verify(material<MaterialCount);

	PlugOf<ResourceID> *effect_plug = effectChain.Find(material);
	if(effect_plug)
		return effect_plug->GetItem();
	
	return ResourceID::Null;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MaterialEffectHolder::~MaterialEffectHolder()
{
	SortedChainIteratorOf<PlugOf<ResourceID>*, int> iterator(&effectChain);
	iterator.DeletePlugs();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MaterialEffectHolder::MaterialTypeTextToAscii(const char *mode_name)
{
	if(!_stricmp(mode_name, "Dirt"))
		return DirtMaterial;
	else if(!_stricmp(mode_name, "Water"))
		return WaterMaterial;
	else if(!_stricmp(mode_name, "Rock"))
		return RockMaterial;
	else if(!_stricmp(mode_name, "Steel"))
		return SteelMaterial;
	else if(!_stricmp(mode_name, "Blacktop"))
		return BlacktopMaterial;
	else if(!_stricmp(mode_name, "Us"))
		return UsMaterial;
	else if(!_stricmp(mode_name, "Them"))
		return ThemMaterial;
	else if(!_stricmp(mode_name, "Vehicle"))
		return VehicleMaterial;
	else if(!_stricmp(mode_name, "Glass"))
		return GlassMaterial;
	else if(!_stricmp(mode_name, "Brick"))
		return BrickMaterial;
	else if(!_stricmp(mode_name, "Grass"))
		return GrassMaterial;
	else if(!_stricmp(mode_name, "Wood"))
		return WoodMaterial;
	else if(!_stricmp(mode_name, "Tree"))
		return TreeMaterial;
	else if(!_stricmp(mode_name, "Swamp"))
		return SwampMaterial;
	else if(!_stricmp(mode_name, "Concrete"))
		return ConcreteMaterial;
	else if(!_stricmp(mode_name, "Rough"))
		return RoughMaterial;
	else if(!_stricmp(mode_name, "Snow"))
		return SnowMaterial;
	else if(!_stricmp(mode_name, "Underbrush"))
		return UnderbrushMaterial;
	else if(!_stricmp(mode_name, "ShallowWater"))
		return ShallowWaterMaterial;
	else if(!_stricmp(mode_name, "MidWater"))
		return MidWaterMaterial;
	else if(!_stricmp(mode_name, "OceanicWater"))
		return OceanicWaterMaterial;
	else if(!_stricmp(mode_name, "Desert"))
		return DesertMaterial;
	else if(!_stricmp(mode_name, "FlatSwamp"))
		return FlatSwampMaterial;
// MSL 5.03 Lava
	else if (!_stricmp(mode_name,"LightMineral"))
		return LightMineralMaterial;
	else if (!_stricmp(mode_name,"DarkMineral"))
		return DarkMineralMaterial;
	else if (!_stricmp(mode_name,"Ash"))
		return AshMaterial;
	else if (!_stricmp(mode_name,"CrackedLava"))
		return CrackedLavaMaterial;
	else if (!_stricmp(mode_name,"OpenLava"))
		return OpenLavaMaterial;
	else 
		return ThickSwampMaterial;		
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MaterialEffectHolder::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}

