#ifndef GEOMLISTC_H
#define GEOMLISTC_H

//GeomListC Contains a collection of triangles that SHARE material and texture...

#include "PajaTypes.h"
#include "TCSetC.h"
#include "MtlLayerC.h"
#include "ColorC.h"
#include "Vector3C.h"
#include "FileIO.h"
#include <vector>

// FLAGS
// bit 0 = Has Normals
// bit 1 = Has Textures
// bit 2 = TriStrip (Otherwise it is a Triangle list)
// bit 3 = Indexed list
// bit 4 = Fixed Indexed List
// bit 5 = Has Colors
// bits 3 & 4 are exclusive... ("There can be only one!") =)

const PajaTypes::uint8		GEOMLIST_HAS_NORMALS		= 0x01;
const PajaTypes::uint8		GEOMLIST_HAS_TEXTURES		= 0x02;
const PajaTypes::uint8		GEOMLIST_TRISTRIP			= 0x04;
const PajaTypes::uint8		GEOMLIST_INDEXED_LIST		= 0x08;
const PajaTypes::uint8		GEOMLIST_FIXED_INDEXEDLIST	= 0x10;
const PajaTypes::uint8		GEOMLIST_HAS_COLORS			= 0x20;




/*

	//Rules 

	//1. If using indexed types (strips or whatever) 
		  - if texture then tcset must have enough indices (ie. the same amount as in geomlist indices)
		  - if color then cindices must have enough indices (ie. the same amount as in geomlist indices)
		  - if normal then nindices must have enough indices (ie. the same amount as in geomlist indices)
	
	//2. If NOT using indexed types (strips or whatever) 
		  - if texture then tcset must have enough vertices (ie. the same amount as in geomlist vertices)
		  - if color then cindices must have enough vertices (ie. the same amount as in geomlist vertices)
		  - if normal then nindices must have enough vertices (ie. the same amount as in geomlist vertices)
	
	//3. If using fixed list types (strips or whatever) 
		  - ONLY ONE SET OF INDICES IS USED SO BE SURE THAT IT IS VALID FOR ALL OTHERS


	// AND TO RECAP THE THING:   THERE MUST BE EQUAL AMOUNT OF INDICES...


	// If you have normals then you CANT have vertex colors..
	// the last type added remains valid...
	// ie. if u had normals and you add colors , the normals are not used and vice versa..		


*/
	
class GeomListC
{
public:
	GeomListC();
	virtual ~GeomListC();

	virtual GeomListC&				operator=( const GeomListC& rGeomList );

	// allocate space for geometry
	virtual void					reserve_indices( PajaTypes::uint16 ui16Size );
	virtual void					reserve_normal_indices( PajaTypes::uint16 ui16Size );
	virtual void					reserve_color_indices( PajaTypes::uint16 ui16Size );
	virtual void					reserve_vertices( PajaTypes::uint16 ui16Size );
	virtual void					reserve_normals( PajaTypes::uint16 ui16Size );
	virtual void					reserve_colors( PajaTypes::uint16 ui16Size );

	// set_xxx( index, value )
	virtual void					set_index( PajaTypes::uint16 ui16Idx, PajaTypes::uint16 ui16Index );		
	virtual void					set_normal_index( PajaTypes::uint16 ui16Idx, PajaTypes::uint16 ui16Index );		
	virtual void					set_color_index( PajaTypes::uint16 ui16Idx, PajaTypes::uint16 ui16Index );
	virtual void					set_vertex( PajaTypes::uint16 ui16Idx, PajaTypes::Vector3C& rVec );
	virtual void					set_normal( PajaTypes::uint16 ui16Idx, PajaTypes::Vector3C& rNorm );
	virtual void					set_color( PajaTypes::uint16 ui16Idx, PajaTypes::ColorC& rColor );

	virtual PajaTypes::uint16		get_index_count() const;
	virtual PajaTypes::uint16		get_normal_index_count() const;
	virtual PajaTypes::uint16		get_color_index_count() const;
	virtual PajaTypes::uint16		get_vertex_count() const;
	virtual PajaTypes::uint16		get_normal_count() const;
	virtual PajaTypes::uint16		get_color_count() const;

	virtual PajaTypes::uint16		get_index( PajaTypes::uint16 ui16Index );
	virtual PajaTypes::uint16		get_normal_index( PajaTypes::uint16 ui16Index );
	virtual PajaTypes::uint16		get_color_index( PajaTypes::uint16 ui16Index );
	virtual PajaTypes::Vector3C		get_vertex( PajaTypes::uint16 ui16Index );
	virtual PajaTypes::Vector3C		get_normal( PajaTypes::uint16 ui16Index );
	virtual PajaTypes::ColorC		get_color( PajaTypes::uint16 ui16Index );

	virtual PajaTypes::uint16*		get_index_pointer();
	virtual PajaTypes::uint16*		get_normal_index_pointer();
	virtual PajaTypes::uint16*		get_color_index_pointer();
	virtual PajaTypes::float32*		get_vertex_pointer();
	virtual PajaTypes::float32*		get_normal_pointer();
	virtual PajaTypes::uint8*		get_color_pointer();

	virtual TCSetC*					add_texture_channel();	//Creates a new TC, returns a ref to the new one..parameter defines the texture stage...
	virtual MtlLayerC*				add_layer();			//Creates a mapping layer, returns a ref to the new one..parameter defines the texture stage...
	
	virtual TCSetC*					get_texture_channel( PajaTypes::uint16 ui16Index );	//returns a TC..  parameter defines channel number
	virtual MtlLayerC*				get_layer( PajaTypes::uint16 ui16Index );				//returns a layer.. paramerer defines layer number

	virtual PajaTypes::uint16		get_texture_channel_count() const;
	virtual PajaTypes::uint16		get_layer_count() const;

	virtual PajaTypes::uint8		get_flags();
	virtual void					add_flags( PajaTypes::uint8 ui8Flags );
	virtual void					del_flags( PajaTypes::uint8 ui8Flags );

	virtual bool					get_bounds( PajaTypes::Vector3C& min, PajaTypes::Vector3C& max );
	virtual void					update_bounds();

	virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );


protected:
private:

	virtual PajaTypes::uint32	write_compressed( FileIO::SaveC* pSave, PajaTypes::uint8* pBuffer, PajaTypes::uint32 ui32BufferSize, PajaTypes::uint8* pCompressed, long* pWorkMem );
	virtual PajaTypes::uint32	read_compressed( FileIO::LoadC* pLoad, PajaTypes::uint8* pBuffer, PajaTypes::uint32 ui32BufferSize );

	bool					m_bBBoxValid;
	bool					m_bBBoxEmpty;
	PajaTypes::Vector3C		m_rMin, m_rMax;
	PajaTypes::uint8		m_ui8Flags;	

	//Geom..
	PajaTypes::uint16		m_ui16IndexCount;
	PajaTypes::uint16		m_ui16NormalIndexCount;
	PajaTypes::uint16		m_ui16ColorIndexCount;
	PajaTypes::uint16		m_ui16VertexCount;
	PajaTypes::uint16		m_ui16NormalCount;
	PajaTypes::uint16		m_ui16ColorCount;

	PajaTypes::uint16*		m_pIndices;
	PajaTypes::uint16*		m_pNormalIndices;
	PajaTypes::uint16*		m_pColorIndices;
	PajaTypes::float32*		m_pVertices;
	PajaTypes::float32*		m_pNormals;
	PajaTypes::uint8*		m_pColors;

	std::vector<TCSetC*>	m_rTexCoordSets;
	std::vector<MtlLayerC*>	m_rMtlLayers;
};

#endif // GEOMLISTC_H