#include "CompostHeaders.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	Feature::IsValidFeature()
{
	switch(GetBlendMode())
	{
		case Paste:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
		break;
		case Added:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
		break;
		case Multiply:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
		break;
		case Blend555_1:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
			if(featureMask0==NULL)
			{
				return 2;
			}
			if(featureMask0->GetTextureMode()!=Feature_Texture::TextureMode::FTT_1)
			{
				return 6;
			}
			if(featureMask0->width == feature_width || featureMask0->height == feature_height)
			{
				return 11;
			}
			if(!IsPowerOf2(featureTexture->width) || !IsPowerOf2(featureTexture->height) )
			{
				return 14;
			}
			if( !IsStretched() && (!IsPowerOf2(featureMask0->width) || !IsPowerOf2(featureMask0->height)) )
			{
				return 15;
			}

		break;
		case Blend555_2:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
			if(featureMask0==NULL)
			{
				return 2;
			}
			if(featureMask0->GetTextureMode()!=Feature_Texture::TextureMode::FTT_1)
			{
				return 6;
			}
			if(featureMask0->width == feature_width || featureMask0->height == feature_height)
			{
				return 11;
			}
			if(featureMask1==NULL)
			{
				return 3;
			}
			if(featureMask1->GetTextureMode()!=Feature_Texture::TextureMode::FTT_1)
			{
				return 7;
			}
			if(featureMask1->width == feature_width || featureMask1->height == feature_height)
			{
				return 12;
			}
			if(!IsPowerOf2(featureTexture->width) || !IsPowerOf2(featureTexture->height) )
			{
				return 14;
			}
			if( !IsStretched() && (!IsPowerOf2(featureMask0->width) || !IsPowerOf2(featureMask0->height)) )
			{
				return 15;
			}
			if( !IsStretched() && (!IsPowerOf2(featureMask1->width) || !IsPowerOf2(featureMask1->height)) )
			{
				return 16;
			}
		break;
		case Blend4444:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_4444)
			{
				return 5;
			}
			if(!IsPowerOf2(featureTexture->width) || !IsPowerOf2(featureTexture->height) )
			{
				return 14;
			}
		break;
		case StretchMultiply:
			if(featureMask0==NULL)
			{
				return 2;
			}
			if(featureMask0->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 8;
			}
			if( !IsStretched() && (!IsPowerOf2(featureMask0->width) || !IsPowerOf2(featureMask0->height)) )
			{
				return 15;
			}
		break;
		case Blend555_1_1:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
			if(featureMask0==NULL)
			{
				return 2;
			}
			if(featureMask0->GetTextureMode()!=Feature_Texture::TextureMode::FTT_1_1)
			{
				return 9;
			}
			if(!IsPowerOf2(featureTexture->width) || !IsPowerOf2(featureTexture->height) )
			{
				return 14;
			}
			if( !IsStretched() && (!IsPowerOf2(featureMask0->width) || !IsPowerOf2(featureMask0->height)) )
			{
				return 15;
			}
		break;
		case Blend555_1_S:
			if(featureTexture==NULL)
			{
				return 1;
			}
			if(featureTexture->GetTextureMode()!=Feature_Texture::TextureMode::FTT_555)
			{
				return 4;
			}
			if(featureMask0==NULL)
			{
				return 2;
			}
			if(featureMask0->GetTextureMode()!=Feature_Texture::TextureMode::FTT_1_M)
			{
				return 10;
			}
			if(!IsPowerOf2(featureTexture->width) || !IsPowerOf2(featureTexture->height) )
			{
				return 14;
			}
			if( !IsStretched() && (!IsPowerOf2(featureMask0->width) || !IsPowerOf2(featureMask0->height)) )
			{
				return 15;
			}
		break;
	}
	return 0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeaturePool::FeaturePool()
{
	Verify(gos_GetCurrentHeap() == Heap);
	used = 0;
	max = 100;
	features.SetLength(max);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeaturePool::FeaturePool(
		Stuff::MemoryStream *stream
	)
{
	LoadIndex(stream);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FeaturePool::~FeaturePool()
{
	for(int i=0;i<used;i++)
	{
		Unregister_Pointer(features[i]);
		delete features[i];
	}
	features.SetLength(0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::LoadIndex(
		Stuff::MemoryStream *stream
	)
{
	Verify(gos_GetCurrentHeap() == Heap);
	int version;

	*stream >> version;

	if(version<6)
	{
		STOP(("The current fgd-file is a version lower than 6. Not supported anymore ! Content error !"));
	}

	*stream >> used;

	max = 100*(1 + (used/100));
	features.SetLength(max);

	for(int i=0;i<used;i++)
	{
		features[i] = LoadFeature(stream, version);
	}
}

void
	FeaturePool::LoadIndex(
				Stuff::NotationFile *note_file
	)
{
Check_Object(note_file);
	Page *page=note_file->GetPage("FeaturePool");
	int version;
	page->GetEntry("Version",&version);



NotationFile fet_note;
page->GetEntry("Features",&fet_note);

used=0;
NotationFile::PageIterator *page_list=fet_note.MakePageIterator();
Check_Object(page_list);
Page *fet_page;	
while((fet_page = page_list->ReadAndNext()) != NULL)
	{
	Check_Object(fet_page);
	used++;
	}

	max = 100*(1 + (used/100));
	features.SetLength(max);


page_list->First();
int i=0;
while((fet_page = page_list->ReadAndNext()) != NULL)
	{
		Check_Object(fet_page);
		features[i++] = LoadFeature(fet_page, version);
	}
Verify(i==used);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::SaveIndex(
		Stuff::MemoryStream *stream
	)
{
	*stream << static_cast<int>(Current_Compost_Version);
	*stream << used;

	MString *name = NULL;
	for(int i=0;i<used;i++)
	{
		name = features[i]->GetName();

		if(name==NULL)
		{
			*stream << 0;
			SaveFeature(stream, features[i]);
		}
		else
		{
			*stream << 1;
			*stream	<< *name;
			SaveFeature(stream, features[i]);
		}
	}
}

void
	FeaturePool::SaveIndex(
		Stuff::NotationFile *note_file
	)
{
	Check_Object(note_file);
	Page *page=note_file->SetPage("FeaturePool");

	page->SetEntry("Version",Current_Compost_Version);
	page->SetEntry("FeatureCount",used);
	NotationFile fet_note;

	for(int i=0;i<used;i++)
	{
		Verify(features[i]->GetName()!=NULL);
		SaveFeature(&fet_note, features[i]);
	}

	page->SetEntry("Features",&fet_note);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::Add(Feature *f)
{
	Verify(gos_GetCurrentHeap() == Heap);
	if(GetFeature(f->index))
	{
		return;
	}

	if(used<max)
	{
		features[used++] = f;
	}
	else
	{
		max += 100;
		features.SetLength(max);
		features[used++] = f;
	}

	Verify(f->featureTexture);
	TexturePool::Instance->Load(f->featureTexture);
	TexturePool::Instance->Load(f->featureMask0);
	TexturePool::Instance->Load(f->featureMask1);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::Insert(Feature *f, int at)
{
	Verify(gos_GetCurrentHeap() == Heap);
	Verify(at<=used);

	if(at==used)
	{
		Add(f);
	}
	else
	{
		used++;
		if(used>=max)
		{
			max += 100;
			features.SetLength(max);
		}

		int i;
		for(i=used;i>at;i--)
		{
			features[i] = features[i-1];
		}
		features[at] = f;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::Move(int from, int to)
{
	Feature *f = features[from];

	Remove(from);

	if(to<used-1)
	{
		Insert(f, to);
	}
	else
	{
		Add(f);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::Remove(int from)
{
	Verify(from>=0);
	Verify(from<used);

	int i;
	for(i=from;i<used-1;i++)
	{
		features[i] = features[i+1];
	}
	used--;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::Remove(Feature *f)
{
Remove(Find(f));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	FeaturePool::Find(Feature *f)
{
int i;
for(i=0;i<features.GetLength();i++)
{
if( features[i]==f) return i;
}

return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Feature*
	FeaturePool::GetFeature(int idx)
{
	Feature *feature=NULL;

	for(int i=0;i<used;i++)
	{
		if(idx==features[i]->GetIndex())
		{
			feature = features[i];
			return feature;
		}
	}
	return NULL;
}

Feature*
		FeaturePool::GetFeature(const char *feature_name)
{
		MString *name;

	for(int i=0;i<used;i++)
	{
		name=features[i]->GetName();
		Verify(name!=NULL);
		
		if(*name==feature_name)
			return features[i];
	}

return NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	FeaturePool::GetFeaturePosition(Feature* feature)
{
	for(int i=0;i<used;i++)
	{
		if(feature==features[i])
		{
			return i;
		}
	}
	return -1;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Feature*
	FeaturePool::IsUsed(Feature_Texture *ft)
{
	Feature *feature=NULL;

	for(int i=0;i<used;i++)
	{
		if(
			ft==features[i]->GetFeatureTexture() ||
			ft==features[i]->GetFeatureMask0() ||
			ft==features[i]->GetFeatureMask1()
		)
		{
			feature = features[i];
			return feature;
		}
	}
	return NULL;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
int
	FeaturePool::ShootRay(unsigned short x, unsigned short z)
{
	int i;
	int hit=0;

	for(i=0;i<used;i++)
	{
		if(	features[i]->feature_x_pos<=x && features[i]->feature_x_pos+features[i]->feature_width>=x &&
			features[i]->feature_z_pos<=z && features[i]->feature_z_pos+features[i]->feature_height>=z
		)
		{
			Verify(hit<MAX_NUMBER_LAYERS);
			rayCollect[hit++] = features[i];
		}
	}

	return hit;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	FeaturePool::ShootRectangle(
		unsigned short x, 
		unsigned short z,
		unsigned short width,
		unsigned short height
	)
{
	int i;
	int hit=0;

	rectangleCollect.SetLength(MAX_NUMBER_LAYERS);
	for(i=0;i<used;i++)
	{
		if(	features[i]->feature_x_pos > x+width)
		{
			continue;
		}
		if(	features[i]->feature_z_pos > z+height)
		{
			continue;
		}
		if(	features[i]->feature_x_pos+features[i]->feature_width < x)
		{
			continue;
		}
		if(	features[i]->feature_z_pos+features[i]->feature_height < z)
		{
			continue;
		}

		if(hit>=rectangleCollect.GetLength())
		{
			rectangleCollect.SetLength(MAX_NUMBER_LAYERS+rectangleCollect.GetLength());
		}
		rectangleCollect[hit++] = features[i];
	}
	rectangleCollect.SetLength(hit);

	return hit;
}
*/

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeaturePool::SaveFeature(
		Stuff::MemoryStream *stream,
		Feature* feature
	)
{
	*stream << feature->feature_width << feature->feature_height;
	*stream << feature->scaleXTexture << feature->scaleZTexture;
	*stream << feature->scaleXMask0 << feature->scaleZMask0;
	*stream << feature->scaleXMask1 << feature->scaleZMask1;

	if(feature->GetName()==NULL)
	{
		*stream << TexturePool::Instance->GetIndex(feature->featureTexture);
		*stream << TexturePool::Instance->GetIndex(feature->featureMask0);
		*stream << TexturePool::Instance->GetIndex(feature->featureMask1);
	}
	else
	{
		MString noName("");
		MString *name = feature->featureTexture->GetName();
		Verify(name!=NULL);
		*stream << *name;

		if(feature->featureMask0 && (name=feature->featureMask0->GetName())!=NULL)
		{
			*stream << *name;
		}
		else
		{
			*stream << noName;
		}

		if(feature->featureMask1 && (name=feature->featureMask1->GetName())!=NULL)
		{
			*stream << *name;
		}
		else
		{
			*stream << noName;
		}

		Tool_Feature *tool_fet = (Tool_Feature *)feature;

		if(tool_fet->HFTexture && (name=tool_fet->HFTexture->GetName())!=NULL)
		{
			*stream << *name;
		}
		else
		{
			*stream << noName;
		}
		*stream << tool_fet->material;
	}
	
	*stream << feature->flags << feature->index;
}

void
	FeaturePool::SaveFeature(
		Stuff::NotationFile *note_file,
		Feature* feature
	)
{
	Verify(feature->GetName()!=NULL);
	
	Tool_Feature *tool_fet=(Tool_Feature *)feature;
	Stuff::Page *page=note_file->SetPage(*(feature->GetName()));
	Check_Object(page);
	

	page->SetEntry("FeatureWidth",feature->feature_width);
	page->SetEntry("FeatureHeight",feature->feature_height);
	page->SetEntry("ScaleXTexture",feature->scaleXTexture);
	page->SetEntry("ScaleZTexture",feature->scaleZTexture);
	page->SetEntry("ScaleXMask0",feature->scaleXMask0);
	page->SetEntry("ScaleZMask0",feature->scaleZMask0);
	page->SetEntry("ScaleXMask1",feature->scaleXMask1);
	page->SetEntry("ScaleZMask1",feature->scaleZMask1);
	page->SetEntry("Material",MaterialEntries[tool_fet->material].MatName);
	page->SetEntry("Flags",feature->flags);
	
	if(tool_fet->HFTexture) page->SetEntry("HFTexture",*(tool_fet->HFTexture->GetName()));
	if(tool_fet->featureTexture) page->SetEntry("FeatureTexture",*(feature->featureTexture->GetName()));
	if(tool_fet->featureMask0) page->SetEntry("FeatureMask0",*(feature->featureMask0->GetName()));
	if(tool_fet->featureMask1) page->SetEntry("FeatureMask1",*(feature->featureMask1->GetName()));

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Feature*
	FeaturePool::LoadFeature(
		Stuff::MemoryStream *stream,
		int version
	)
{
	Verify(gos_GetCurrentHeap() == Heap);
	int type;
	Feature *feature = NULL;

	*stream >> type;

	switch(type)
	{
		case 0:
		{
			feature = new Feature();
		}
		break;
		case 1:
		{
			feature = new Tool_Feature();
			MString name;
			*stream >> name;
			name.ToLower();
			(static_cast<Tool_Feature*>(feature))->SetName(name);
		}
		break;
	}

	if(feature==NULL)
	{
		return feature;
	}

	*stream >> feature->feature_width >> feature->feature_height;

	if(version<3)
	{
		int temp;
		*stream >> temp;
		*stream >> temp;
	}
/*
//	HACK
	feature->texture_x_pos &= ~1;
	feature->texture_z_pos &= ~1;
//	HACK
*/
	*stream >> feature->scaleXTexture >> feature->scaleZTexture;
	*stream	>> feature->scaleXMask0	>> feature->scaleZMask0;
	*stream	>> feature->scaleXMask1	>> feature->scaleZMask1;

	feature->ReCalculateScale();

	if(version < 5)
	{
		int index;
		*stream >> index;
		feature->featureTexture = TexturePool::Instance->Get(index);
		
		if(type==1)
		{
			if(feature->featureTexture==NULL)
			{
				Tool_Feature *tool_fet=Cast_Pointer(Tool_Feature *, feature);
				STOP(("Featuretexture from feature \"%s\" is missing in Compost Texture Pool.", (const char *)(*tool_fet->GetName()) ));
			}
		}

		*stream >> index;
		feature->featureMask0 = TexturePool::Instance->Get(index);

		*stream >> index;
		feature->featureMask1 = TexturePool::Instance->Get(index);

		if(version>1 && type==1)
		{
			Tool_Feature *tool_fet=(Tool_Feature *)feature;
			*stream >> index;
			tool_fet->HFTexture	= TexturePool::Instance->Get(index);

			if(version>3)
			{
				*stream >> tool_fet->material;
			}
			else
			{
				tool_fet->material = 0;
			}

		}
	}
	else
	{
		if(type==0)
		{
			int index;
			*stream >> index;
			feature->featureTexture = TexturePool::Instance->Get(index);

			*stream >> index;
			feature->featureMask0 = TexturePool::Instance->Get(index);

			*stream >> index;
			feature->featureMask1 = TexturePool::Instance->Get(index);
		}
		else
		{
			MString name, name0, name1, tool_name;
			*stream >> name;
			Verify(!name==false);
			name.ToLower();
			feature->featureTexture = TexturePool::Instance->Get(name.GetHashValue());

			*stream >> name0;
			if(!name0==false)
			{
				name0.ToLower();
				feature->featureMask0 = TexturePool::Instance->Get(name0.GetHashValue());
			}
			else
			{
				feature->featureMask0 = NULL;
			}

			*stream >> name1;
			if(!name1==false)
			{
				name1.ToLower();
				feature->featureMask1 = TexturePool::Instance->Get(name1.GetHashValue());
			}
			else
			{
				feature->featureMask1 = NULL;
			}

			if(version>1)
			{
				Tool_Feature *tool_fet=(Tool_Feature *)feature;

				*stream >> tool_name;
				if(!tool_name==false)
				{
					tool_name.ToLower();
					tool_fet->HFTexture	= TexturePool::Instance->Get(tool_name.GetHashValue());
				}
				else
				{
					tool_fet->HFTexture	= NULL;
				}

				if(version>3)
				{
					*stream >> tool_fet->material;
				}
				else
				{
					tool_fet->material = 0;
				}
			}
		}
	}

	*stream >> feature->flags >> feature->index;


	if(feature->GetBlendMode()==Feature::Blend555_1)
	{
		Verify(feature->featureMask0!=NULL);
		if(!(feature->feature_width>feature->featureMask0->width) || !(feature->feature_height>feature->featureMask0->height) )
		{
			if(feature->featureMask0->GetTextureMode() == Feature_Texture::FTT_1)
			{
				SPEW(("micgaert", "Houston we have a problem in %s.", (type==1) ? (const char *)(*(static_cast<Tool_Feature*>(feature))->GetName()):"Unnamed feature"));

				DestroyTextureData(feature->featureMask0);
				feature->featureMask0->SetTextureMode(Feature_Texture::FTT_1_M);
				feature->featureMask0->SetLoadedOff();
				TexturePool::Instance->Load(feature->featureMask0);
				TexturePool::Instance->IsChanged(true);
			}

			feature->SetBlendMode(Feature::Blend555_1_S);
		} 
	}

	if(feature->GetBlendMode()==Feature::Blend555_1_S && feature->featureMask0->GetTextureMode() != Feature_Texture::FTT_1_M)
	{
		DestroyTextureData(feature->featureMask0);
		feature->featureMask0->SetTextureMode(Feature_Texture::FTT_1_M);
		feature->featureMask0->SetLoadedOff();
		TexturePool::Instance->Load(feature->featureMask0);
		TexturePool::Instance->IsChanged(true);

		SPEW(("micgaert", "Houston we have another problem in %s.", (type==1) ? (const char *)(*(static_cast<Tool_Feature*>(feature))->GetName()):"Unnamed feature"));
	}

	Register_Pointer(feature);
	return feature;
}










Feature*
	FeaturePool::LoadFeature(
		Stuff::Page *fet_page,
			int version
			)
{
	Verify(gos_GetCurrentHeap() == Heap);
	Tool_Feature *feature = new Tool_Feature();
	feature->SetName(fet_page->GetName());

	fet_page->GetEntry("FeatureWidth",&(feature->feature_width));
	fet_page->GetEntry("FeatureHeight",&(feature->feature_height));
	fet_page->GetEntry("ScaleXTexture",&(feature->scaleXTexture));
	fet_page->GetEntry("ScaleZTexture",&(feature->scaleZTexture));
	fet_page->GetEntry("ScaleXMask0",&(feature->scaleXMask0));
	fet_page->GetEntry("ScaleZMask0",&(feature->scaleZMask0));
	fet_page->GetEntry("ScaleXMask1",&(feature->scaleXMask1));
	fet_page->GetEntry("ScaleZMask1",&(feature->scaleZMask1));
	fet_page->GetEntry("Flags",&(feature->flags));

	

	const char *mat_name,*texture_name;
	fet_page->GetEntry("Material",&mat_name);

	for(int i=0;i<MaterialEntriesCount;i++)
		if(MaterialEntries[i].MatName==mat_name) feature->material=i;


	feature->ReCalculateScale();

	if(fet_page->GetEntry("HFTexture",&texture_name))
	feature->HFTexture=TexturePool::Instance->Get(texture_name);

	if(fet_page->GetEntry("FeatureTexture",&texture_name))
	feature->featureTexture=TexturePool::Instance->Get(texture_name);

	if(fet_page->GetEntry("FeatureMask0",&texture_name))
	feature->featureMask0=TexturePool::Instance->Get(texture_name);

	if(fet_page->GetEntry("FeatureMask1",&texture_name))
	feature->featureMask1=TexturePool::Instance->Get(texture_name);

	if(feature->featureTexture==NULL)
		{
			STOP(("Texture: %s is missing in Compost Texture Pool.", (const char *)(*feature->GetName()) ));
		}


	if(feature->GetBlendMode()==Feature::Blend555_1)
	{
		Verify(feature->featureMask0!=NULL);
		if(!(feature->feature_width>feature->featureMask0->width) || !(feature->feature_height>feature->featureMask0->height) )
		{
			if(feature->featureMask0->GetTextureMode() == Feature_Texture::FTT_1)
			{
				SPEW(("micgaert", "Houston we have a problem in %s.",  (const char *)(*(static_cast<Tool_Feature*>(feature))->GetName())));

				DestroyTextureData(feature->featureMask0);
				feature->featureMask0->SetTextureMode(Feature_Texture::FTT_1_M);
				feature->featureMask0->SetLoadedOff();
				TexturePool::Instance->Load(feature->featureMask0);
				TexturePool::Instance->IsChanged(true);
			}

			feature->SetBlendMode(Feature::Blend555_1_S);
		} 
	}

	if(feature->GetBlendMode()==Feature::Blend555_1_S && feature->featureMask0->GetTextureMode() != Feature_Texture::FTT_1_M)
	{
		DestroyTextureData(feature->featureMask0);
		feature->featureMask0->SetTextureMode(Feature_Texture::FTT_1_M);
		feature->featureMask0->SetLoadedOff();
		TexturePool::Instance->Load(feature->featureMask0);
		TexturePool::Instance->IsChanged(true);

		SPEW(("micgaert", "Houston we have another problem in %s.", (const char *)(*(static_cast<Tool_Feature*>(feature))->GetName())));
	}

	Register_Pointer(feature);
	return feature;

}
