//
// Asura_Fragment_System.h
//
// Created by Richard Rice - 29/11/2002
// 
// Copyright (C) 2002 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_FRAGMENT_SYSTEM_H__
#define __ASURA_FRAGMENT_SYSTEM_H__

#include "Core/Asura_Maths.h"
#include "Core/Asura_Hash.h"

#define ASURA_MAX_FRAGMENT_TYPES 100

class Asura_FragmentType;
class Asura_Fragment;
class Asura_HashTree;
class Asura_Shape_Instance;


class Asura_Fragment_System
{
public :
	static void Initialise();
	static void Shutdown();

	static void Reset();

#ifdef ASURA_TOOLS
	static void LoadFragments();//Scans through all the Asura_Meshes and makes sure the fragment files are loaded for them
    static bool LoadSingleFragment( Asura_Hash_ID uFragmentHash );
#endif

	//returns true if this is a new fragment type
	static bool NewFragmentType(Asura_Hash_ID uHash,Asura_FragmentType*& pxFragmentType);
	static Asura_FragmentType* GetFragmentType(Asura_Hash_ID uHash);

	static int GetNumberOfFragmentTypes(){return s_iNumberOfFragmentTypes;}
	static Asura_FragmentType* GetFragmentTypeByIndex(int iIndex);


	//Gets the is of the shape that represents the destroyed version of the shape , if any	
	static Asura_Hash_ID GetDestroyedShapeHash(Asura_Hash_ID uFragmentHash);

	//Generate a bunch of fragments based on the fragment type
	//xPosition and xOrient are positions in world space of thing being blown up
	//pxBoundingBox (optional) is bounding box relative to position and orientation
	//pxVelocity (optional) is initial velocity for fragments in world space
	static void GenerateFragments(Asura_Hash_ID uFragmentHash,const Asura_Vector_3& xPosition,const Asura_Matrix_3x3& xOrient,const Asura_Bounding_Box* pxBoundingBox,const Asura_Vector_3* pxVelocity = NULL,float fEnergy = 1.0f);

	static void GenerateFragments(const Asura_Shape_Instance* pxShapeInstance,const Asura_Vector_3* pxVelocity = NULL,float fEnergy = 1.0f);


private :
	static Asura_HashTree* s_pxFragmentTree;
	static int s_iNumberOfFragmentTypes;
	static Asura_FragmentType* s_apxFragmentTypes[ASURA_MAX_FRAGMENT_TYPES];

	


};


class Asura_FragmentType
{
public :
	Asura_FragmentType(Asura_Hash_ID uHash);
	~Asura_FragmentType();

	//Gets the is of the shape that represents the destroyed version of the shape , if any	
	Asura_Hash_ID GetDestroyedShapeHash();
	void GenerateFragments(const Asura_Vector_3& xPosition,const Asura_Matrix_3x3& xOrient,const Asura_Bounding_Box* pxBoundingBox,const Asura_Vector_3* pxVelocity = NULL,float fEnergy = 1.0f);


	Asura_Hash_ID m_uFragmentHash; //id of this fragment type

	//the fragments that belong to this type
	int m_iNumberOfFragments;
	Asura_Fragment* m_pxFragments;

	bool m_bAnimatedFragment;//if true then fragement hash ID is id of skin and animation to use
};

#define ASURA_FRAGMENTFLAG_USEPOSITION 0x00000001 //If false then this is some generic fragment bit that should be put randomly in the bounding box
#define ASURA_FRAGMENTFLAG_DESTROYEDSHAPE 0x00000002 //This fragment represents the destroyed version of the shape , and should stick around

class Asura_Fragment
{
public :
	Asura_Fragment();
	
	Asura_Hash_ID m_uShapeHash; 
	Asura_Vector_3 m_xPosition;
	unsigned m_uFlags;
	int m_iQuantity;//number of this fragment to produce
};



#endif //__ASURA_FRAGMENT_SYSTEM_H__
