/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "core/cached_graphic_resource_factory.h"
		#include "core/resource_geometry_generator.h"
		#include "picture/pict_io.h"

		using namespace GS;
		using namespace GS::Core;


//------------------------------------------------------------------------------
static bool			DoLoadResource(const char *name, Geometry &g)
{
	if	(GeometryGenerator::IsGenerated(name))
		return GeometryGenerator::Generate(name, g);
	return NML::LoadFromFile(g, name);
}
static bool			DoLoadResource(const char *name, Picture &p)
{	return PictureIO::Get().Load(p, name);	}
template <class T> bool DoLoadResource(const char *name, T &t)
{	return NML::LoadFromFile(t, name);	}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
template <class T> T *LoadResourceCommonSeq(const char *name, SharedList <T *> &list)
{
	if	(!name)
		return NULL;

	ListForeachPtr(T *, t, list)
		if	(t->name == name)
			return t;

	AutoPtr <T> t(new T);
	if	(t.IsNull())
		return NULL;

	t->name = name;
	if	(!DoLoadResource(name, *t))
		return NULL;

	list.Add(t);

	return t.Detach();
};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Picture				*CachedResourceFactory::LoadPicture(const char *name)
{	return LoadResourceCommonSeq(name, pictures);	}
Geometry			*CachedResourceFactory::LoadGeometry(const char *name)
{	return LoadResourceCommonSeq(name, geometries);	}
Material			*CachedResourceFactory::LoadMaterial(const char *name)
{	return LoadResourceCommonSeq(name, materials);	}
Shader				*CachedResourceFactory::LoadShader(const char *name)
{	return LoadResourceCommonSeq(name, shaders);	}
ParticleModel		*CachedResourceFactory::LoadParticleModel(const char *name)
{	return LoadResourceCommonSeq(name, particle_models);	}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
uint				CachedResourceFactory::GetCachedResourceCount()
{
	uint count = 0;
	count += geometries.GetCount();
	count += materials.GetCount();
	count += shaders.GetCount();
	count += particle_models.GetCount();
	count += pictures.GetCount();
	return count;
}
uint				CachedResourceFactory::PurgeCache()
{
	uint purged = 0;
	forever
	{
		uint pass_purged = 0;
		purged += PurgeSharedList(geometries);
		purged += PurgeSharedList(materials);
		purged += PurgeSharedList(shaders);
		purged += PurgeSharedList(particle_models);
		purged += PurgeSharedList(pictures);
		if	(pass_purged == 0)
			break;

		purged += pass_purged;
	}
	return purged;
}
//------------------------------------------------------------------------------
