#ifndef OOBU_MESHREFC_H
#define OOBU_MESHREFC_H


#include "OsLib.h"
#include "MathLib.h"
#include "Mesh3DC.h"
#include <vector>
#include <string>
#include "EditableI.h"

/*

note about the undo system and meshref:

Whenever a meshref is modified a clone of the original is made using the
clone() method. Later when user decides to undo, restore() method is called.
The parameter for the restore method is the original (unmodifed) meshref.

*/


enum MeshRefFlagsE {
	MESHREF_SELECTED	= 0x0001,	// ref is selected
	MESHREF_HIDDEN		= 0x0002,	// ref is hidden
	MESHREF_LOD			= 0x0004,	// this is LOD ref
	MESHREF_COMPOSITE	= 0x0008,	// this is composite ref
	MESHREF_GROUP		= 0x0010,	// this is group ref
//	MESHREF_TRANSFORMED	= 0x0020,	// ref has transformation cached
};


enum MeshRefTypesE {
	MESHREF_TYPE_NORMAL = 0,
	MESHREF_TYPE_ADDRESSBOX,
};

/*
//
// analogous to geomlist
// holds a transformed geomlist
//
class TransformListC
{
public:
	TransformListC( OsTypes::uint32 ui32VertCount );
	virtual ~TransformListC();

	OsTypes::uint32		get_vert_count();
	OsTypes::float32*	get_data();

protected:
	OsTypes::float32*	m_pVertices;
	OsTypes::uint32		m_ui32VertCount;
};

//
// analogous to mesh
// holds many transformed geomlists
//
class TransformCacheC
{
public:
	TransformCacheC();
	virtual ~TransformCacheC();

	TransformListC*	add_list( OsTypes::uint32 ui32VertCount );
	TransformListC*	get_list();
	OsTypes::uint32	get_list_count();

protected:
	std::vector<TransformListC*>	m_rLists;
};
*/


class MeshRefC : public EditableI
{
public:
	MeshRefC();
	MeshRefC( const MeshRefC& rMeshRef );
	virtual ~MeshRefC();

	virtual OsTypes::int32				get_type();
	
	// used in cut'n'paste
	virtual EditableI*					duplicate();
	virtual void						copy( EditableI* pRef );

	// used in undo
	virtual EditableI*					clone();
	virtual void						restore( EditableI* pRef );

	virtual void						set_mesh( Mesh3DC* pMesh );
	virtual Mesh3DC*					get_mesh();

	virtual void						set_position( const MathLib::Vector3dC& rPos );
	virtual const MathLib::Vector3dC&	get_position() const;

	virtual void						set_scale( const MathLib::Vector3dC& rScale );
	virtual const MathLib::Vector3dC&	get_scale() const;

	virtual void						set_rotation( const MathLib::QuatC& rRot );
	virtual const MathLib::QuatC&		get_rotation() const;

	virtual OsTypes::int32				get_flags() const;
	virtual void						set_flags( OsTypes::int32 i32Flags );
	virtual void						add_flags( OsTypes::int32 i32Flags );
	virtual void						del_flags( OsTypes::int32 i32Flags );
	virtual void						toggle_flags( OsTypes::int32 i32Flags );

	virtual void						set_bounds( MathLib::Vector3dC& rMin, MathLib::Vector3dC& rMax );
	virtual bool						get_bounds( MathLib::Vector3dC& rMin, MathLib::Vector3dC& rMax );

	virtual OsTypes::int32				get_gizmo_count();
	virtual MathLib::Vector3dC			get_gizmo_pos( OsTypes::int32 i32Index );

//	virtual void						update_transform_cache( OsTypes::int32 i32LODLevel = MESH_LOD_LEVEL_1 );
//	virtual TransformCacheC*			get_transform_cache();

private:

	MeshRefC( const MeshRefC& rMeshRef, EditableI* pOriginal );
//	void								make_transform_cache( TransformCacheC** pCache, OsTypes::int32 i32LODLevel );
//	void								update_transform_cache( TransformCacheC** pCache, OsTypes::int32 i32LODLevel );

	Mesh3DC*			m_pMesh;
	MathLib::Vector3dC	m_rPosition;
	MathLib::Vector3dC	m_rScale;
	MathLib::QuatC		m_rRotation;
	OsTypes::int32		m_i32Flags;

	OsTypes::Boolean	m_bBBoxEmpty;
	MathLib::Vector3dC	m_rMin;
	MathLib::Vector3dC	m_rMax;

//	TransformCacheC*	m_pTransCache0;		// for each LOD level
//	TransformCacheC*	m_pTransCache1;
//	TransformCacheC*	m_pTransCache2;

//	MeshRefC*			m_pOriginal;
};


#endif