//--------------------------------------------------------------------------------------
// Copyright (C) 2008 http://shift.delblanco.es
//--------------------------------------------------------------------------------------
// SHIFT Videogame 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 3 of the License, or 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.
//--------------------------------------------------------------------------------------
// Original version by Kevin Harris
//--------------------------------------------------------------------------------------
/// \file 3DParticle.h
/// Para manejar los sistemas de partículas de la escena.
/// Este módulo ofrece el tratamiento de los sistemas de partículas de la escena
//--------------------------------------------------------------------------------------
#pragma once
#ifndef __C3DPARTICLE_H__
#define __C3DPARTICLE_H__

//--------------------------------------------------------------------------------------
// Ficheros de cabecera
//--------------------------------------------------------------------------------------
#include <d3dx9.h>

//--------------------------------------------------------------------------------------
/// Estructura para mantener cada partícula
//--------------------------------------------------------------------------------------
struct Particle
{
    D3DXVECTOR3 m_vCurPos;    // Posición actual de la partícula
    D3DXVECTOR3 m_vCurVel;    // Velocidad actual de la partícula
    float       m_fInitTime;  // Tiempo de su creación

    Particle   *m_pNext;      // Siguiente partícula en la lista
};

//--------------------------------------------------------------------------------------
/// Estructura para vértices y FVF personalizados
//--------------------------------------------------------------------------------------
struct PointVertex
{
    D3DXVECTOR3 posit;
    D3DCOLOR    color;
	enum FVF {FVF_Flags = D3DFVF_XYZ | D3DFVF_DIFFUSE};
};

//--------------------------------------------------------------------------------------
/// Clase C3DParticles para manejar sistemas de partículas
//--------------------------------------------------------------------------------------
class C3DParticles
{

private:  // Campos miembro

    IDirect3DDevice9		*m_pDevice;					///< Puntero al dispositivo de DirectX

    DWORD					m_dwVBOffset;
    DWORD					m_dwFlush;
    DWORD					m_dwDiscard;
    Particle				*m_pActiveList;
    Particle				*m_pFreeList;
	DWORD					m_dwActiveCount;
	float					m_fCurrentTime;
	float					m_fLastUpdate;

    float					m_fMaxPointSize;
    bool					m_bDeviceSupportsPSIZE;

    LPDIRECT3DVERTEXBUFFER9 m_pVB;						///< Buffer de vértices
    LPDIRECT3DTEXTURE9      m_ptexParticle;				///< Textura de las partículas
    
    // Atributos del sistema de partículas
    DWORD					m_dwMaxParticles;
    DWORD       			m_dwNumToRelease;
    float       			m_fReleaseInterval;
    float       			m_fLifeCycle;
    float       			m_fSize;
    D3DXCOLOR   			m_clrColor;
    D3DXVECTOR3 			m_vPosition;
    D3DXVECTOR3 			m_vVelocity;
    D3DXVECTOR3 			m_vGravity;
    D3DXVECTOR3 			m_vWind;
    bool        			m_bAirResistence;
    float       			m_fVelocityVar;
    LPWSTR					m_chTexFile;

	// Flag para indicar si ha sido actualizado
	bool					m_bUpdate;

public: // Métodos públicos

    /// Constructor
    C3DParticles (void);
    /// Destructor
   ~C3DParticles (void);

    /// Inicializa el sistema de partículas
    HRESULT initialize ();
    /// Actualiza el sistema de partículas
    HRESULT update ();
    /// Renderiza el sistema de partículas
    HRESULT render ();
    /// Restaura el sistema de partículas
    HRESULT restore ();
    /// Libera el sistema de partículas
    HRESULT free ();
    /// Destruye el sistema de partículas
    void Release();

    // Getters y Setters del sistema de partículas
    void SetMaxParticles (DWORD dwMaxParticles)			{m_dwMaxParticles = dwMaxParticles;}
	DWORD GetMaxParticles ()							{return m_dwMaxParticles;}

    void SetNumToRelease (DWORD dwNumToRelease)			{m_dwNumToRelease = dwNumToRelease;}
	DWORD GetNumToRelease ()							{return m_dwNumToRelease;}

    void SetReleaseInterval (float fReleaseInterval)	{m_fReleaseInterval = fReleaseInterval;}
    float GetReleaseInterval ()							{return m_fReleaseInterval;}

    void SetLifeCycle (float fLifeCycle)				{m_fLifeCycle = fLifeCycle;}
	float GetLifeCycle ()								{return m_fLifeCycle;}

    void SetSize (float fSize)							{m_fSize = fSize;}
	float GetSize ()									{return m_fSize;}
	float GetMaxPointSize ()							{return m_fMaxPointSize;}

    void SetColor (D3DXCOLOR clrColor)					{m_clrColor = clrColor;}
	D3DXCOLOR GetColor ()								{return m_clrColor;}

    void SetPosition (D3DXVECTOR3 vPosition)			{m_vPosition = vPosition;}
	D3DXVECTOR3 GetPosition ()							{return m_vPosition;}

    void SetVelocity (D3DXVECTOR3 vVelocity)			{m_vVelocity = vVelocity;}
	D3DXVECTOR3 GetVelocity ()							{return m_vVelocity;}

    void SetGravity (D3DXVECTOR3 vGravity)				{m_vGravity = vGravity;}
	D3DXVECTOR3 GetGravity ()							{return m_vGravity;}

    void SetWind (D3DXVECTOR3 vWind)					{m_vWind = vWind;}
	D3DXVECTOR3 GetWind ()								{return m_vWind;}

    void SetAirResistence (bool bAirResistence)			{m_bAirResistence = bAirResistence;}
	bool GetAirResistence ()							{return m_bAirResistence;}

    void SetVelocityVar (float fVelocityVar)			{m_fVelocityVar = fVelocityVar;}
	float GetVelocityVar ()								{return m_fVelocityVar;}

    void SetTexture (LPWSTR chTexFile);
    LPDIRECT3DTEXTURE9 &GetTextureObject()				{return m_ptexParticle;}
    
	void RestartParticleSystem ();
};

#endif
