/*  TA3D, a remake of Total Annihilation
    Copyright (C) 2005  Roland BROCHARD

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA*/

/*-----------------------------------------------------------------------------------\
|                                      particles.h                                   |
|  Ce fichier contient les structures, classes et fonctions nécessaires aux effets   |
| graphiques utilisants des particules comme la poussière, les effets de feu,        |
| d'explosion, de fumée ... Ce fichier est conçu pour fonctionner avec la librairie  |
| Allegro et l'addon AllegroGL pour l'utilisation d'OpenGl avec Allegro.             |
|                                                                                    |
\-----------------------------------------------------------------------------------*/

#ifndef __CLASSE_PARTICLES
#define __CLASSE_PARTICLES

struct PARTICLE					// Structure définissant une particule
{
	VECTOR		Pos;			// Position
	VECTOR		V;				// Vitesse
	float		size;			// Taille
	float		dsize;			// Variation de la taille au cours du temps
	float		col[4];			// Couleur
	float		dcol[4];		// Variation de couleur
	int			gltex;			// Texture associée
	float		mass;			// Masse apparente de la particule si celle-ci est soumise à la force de gravitation(signe seulement)
	float		life;			// Temps d'existence restant à la particule
	float		smoking;		// Produit de la fumée?
	float		angle;			// Angle
	float		v_rot;			// Vitesse de rotation
	short		px;				// Coordonnées du bloc de référence pour la visibilité
	short		py;
};

class PARTICLE_ENGINE			// Moteur à particules
{
public:
	int			nb_part;		// Nombre de particules
	int			size;			// Quantité maximale de particules stockables dans le tableau
	PARTICLE	*part;			// Tableau de particules
	GLuint		parttex;		// Textures des particules
	BITMAP		*partbmp;		// Textures des particules
	bool		dsmoke;
	int			ntex;

	VECTOR		*point;			// Tableau de points pour dessiner les particules
	GLfloat		*texcoord;		// Tableau pour les coordonnées de texture
	GLuint		*index;			// Tableau d'indices
	GLfloat		*color;			// Tableau pour les couleurs

	void init(bool load=true)
	{
		dsmoke=load;
		ntex=0;
		partbmp=NULL;
		if(load) {
			partbmp=create_bitmap_ex(32,256,256);
			BITMAP *bmp=LoadMaskedTexBmp("smoke.tga","smokea.tga");
			stretch_blit(bmp,partbmp,0,0,bmp->w,bmp->h,0,0,64,64);
			ntex=1;
			destroy_bitmap(bmp);
			allegro_gl_use_alpha_channel(true);
			allegro_gl_set_texture_format(GL_RGBA8);
			parttex=allegro_gl_make_texture(partbmp);
			allegro_gl_use_alpha_channel(false);
			glBindTexture(GL_TEXTURE_2D, parttex);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
			}
		size=0;
		nb_part=0;
		part=NULL;

		point=NULL;
		texcoord=NULL;
		index=NULL;
		color=NULL;
	}

	int PARTICLE_ENGINE::addtex(char *file,char *filealpha);

	PARTICLE_ENGINE()
	{
		init(false);
	}

	void destroy()
	{
		if(partbmp)
			destroy_bitmap(partbmp);
		partbmp=NULL;
		ntex=0;
		if(dsmoke)
			glDeleteTextures(1,&parttex);
		if(part)
			free(part);
		dsmoke=false;
		size=0;
		nb_part=0;
		part=NULL;

		if(point)
			free(point);
		if(texcoord)
			free(texcoord);
		if(index)
			free(index);
		if(color)
			free(color);
		point=NULL;
		texcoord=NULL;
		index=NULL;
		color=NULL;
	}

	~PARTICLE_ENGINE()
	{
		destroy();
	}

	void more_memory();			// Alloue de la mémoire supplémentaire

	void emit_part(POINTF pos,VECTOR Dir,int tex,int nb,float speed,float life=10.0f,float psize=10.0f,bool white=false);

	void emit_lava(POINTF pos,VECTOR Dir,int tex,int nb,float speed,float life=10.0f);

	void make_smoke(POINTF pos,int tex,int nb,float speed,float mass=-1.0f);

	void make_fire(POINTF pos,int tex,int nb,float speed);

	void move(float dt,float g=9.81f);

	void draw(CAMERA *cam,int map_w,int map_h,int bloc_w,int bloc_h,byte **bmap);
};

extern PARTICLE_ENGINE	particle_engine;

#endif
