/// @file compressormanager.hpp
/// Compression/Decompression manager classes
///
/// @remarks
/// These classes holds a collection of Compressor derived classes
///  and is used for runtime selection of which algorithm to test.
///
/// @author mouser
/// @author Jibz
/// @date   2003.07.29
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// recursive header protection
#ifndef CompressorManagerH
#define CompressorManagerH
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// application includes
#include "../compressors/compressor.hpp"
// system includes
#include <string>
#include <vector>
#include <assert.h>
//---------------------------------------------------------------------------




//---------------------------------------------------------------------------
/// The CompressorManager classes holds a collection of Compressor derived classes
///  and is used for runtime selection of which algorithm to test.
///
/// @ingroup Core
///
class CompressorManager : public OctaneClass
{
protected:
	/// Vector holding the registered base compressor types
	std::vector<OctaneCompressor*> compressorvector_basetypes;
	/// Vector holding the registered compressors.
	std::vector<OctaneCompressor*> compressorvector_instantiated;
public:
	/// Constructor
	CompressorManager();
	/// Destructor.
	~CompressorManager();
public:
	/// accessor for instantiated compressor vector size
	int GetBaseCompressorCount() {return compressorvector_basetypes.size();};
	/// accessor for instantiated compressor vector size
	int GetInstantiatedCompressorCount() {return compressorvector_instantiated.size();};
	/// accessor for instantiated compressor vector
	OctaneCompressor* GetBaseCompressorp(int index) {assert(index<GetBaseCompressorCount()); return compressorvector_basetypes[index];};
	/// accessor for instantiated compressor vector
	OctaneCompressor* GetInstantiatedCompressorp(int index) {assert(index<GetInstantiatedCompressorCount()); return compressorvector_instantiated[index];};
public:
	/// Find a base compressor for subsequent operations.
	/// @return true on success.
	OctaneCompressor* FindBaseCompressorClass(const std::string &compressorname);
	/// Find the pointer to the instantiated compressor referred to by idstring
	/// idstring can be [$name|$num|G$guid]
	/// @return NULL if not found
	OctaneCompressor *FindInstantiatedCompressorpFromStringId(std::string idstring);
	/// Find the pointer to the instantiated compressor referred to by a guid
	/// @return NULL if not found
	OctaneCompressor *FindInstantiatedCompressorpFromGuid(unsigned short int guidindex);
	/// Register a new compressor.
	void RegisterBaseCompressor(OctaneCompressor* compressorp);
	/// Unregister a new compressor.
	void UnRegisterBaseCompressor(OctaneCompressor* compressorp);
public:
	/// Initialize the compressdecompress manager before using it
	void Initialize();
	/// Deinitialize the compressdecompress manager when done with it
	void DeInitialize();
public:
	/// Create a new compressor based on file info and load state
	/// @return NULL on failure
	OctaneCompressor *CreateCompressorFromSavedStream(bitreader &from);
	/// Add an instantiated compressor to our instantiated list
	/// @return true on success
	bool AddCompressor (OctaneCompressor *compressorp);
	/// Delete an instantiated compressor to our instantiated list
	/// @return true on success
	bool DeleteCompressor (OctaneCompressor *compressorp);
};
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
/// global single instance of the CompressorManager; all compressors will register with this global instance.
extern CompressorManager *global_compressormanagerp;
//---------------------------------------------------------------------------





//---------------------------------------------------------------------------
/// This is a sneaky little class which allows us to create self-registering compressors.
/// The point of CompressorManager_SingletonInsurer is simply to
///  insure that a singleton CompressorManager is initialized prior
///  to any derived Compressor instantiations.  It is instantiated by all objects prior on their construction.
class CompressorManager_SingletonInsurer
{
public:
	/// the constructor creates our global singleton if appropriate,
	///  and then registers the passed compressor.  So called should just
	///  create and destroy a CompressorManager_SingletonInsurer in their constructor
	///  (using a local variable is fine)
	CompressorManager_SingletonInsurer(OctaneCompressor *compressorp) {if (global_compressormanagerp==NULL) global_compressormanagerp= new CompressorManager();global_compressormanagerp->RegisterBaseCompressor(compressorp);};
};
//---------------------------------------------------------------------------





//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

