/*
	Rogue Trader.
	Copyright (c) 2007, Darragh Coy.
	All rights reserved.
	Original work(s), source code & author(s) details available at: http://www.darraghcoy.com

	Redistribution and use in source and binary forms, with or without modification, are permitted 
	provided that the following conditions are met:

		* 	Redistributions of source code must retain the above copyright notice, this list of 
			conditions and the following disclaimer.
		* 	Redistributions in binary form must reproduce the above copyright notice, this list of 
			conditions and the following disclaimer in the documentation.
		* 	Neither the name of the author nor the names of contributors may be used to endorse or 
			promote products derived from this software without specific prior written permission.
		* 	The use of any third party libraries, modules or data files provided with the source 
			form of the program must follow and respect the individual licensing terms of these 
			components. You do not have permission to modify or circumvent the licensing terms for 
			provided third party components unless the third party licenses specifically allow this. 
			If you do not agree to the terms of provided third party components then you do not have 
			permission to use them in your derived work(s).
		* 	The terms of this license do not apply to separate (but related) distributions if supplied 
			by the author(s), only to the contents of this source distribution, derived works, and the 
			binaries produced by either modified or unmodified versions of the source code. The terms 
			of this license do not also apply to any third party libraries or components provided with 
			the source distribution. Such third party elements are licensed under their own separate 
			agreements.

	THIS SOFTWARE IS PROVIDED BY DARRAGH COY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
	ARE DISCLAIMED. IN NO EVENT SHALL DARRAGH COY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef PARTICLESCENE_H
#define PARTICLESCENE_H

//##############################################################################
// C Includes
//##############################################################################

#include <Windows.h>
#include <gl/gl.h>

//##############################################################################
// Forward references
//##############################################################################

class GLTextureManager;
class Camera;

//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################
//
//
// Class Name:   ParticleScene
// Purpose:      Class responsible for managing a scene full of particles. Creates
//               a pool of spare particles to save on creation / deletion overhead
//               and has several functions for creating particles. Also handles
//               all particle movement and drawing. One of the base classes of the
//               combined super class, GameScene. The particles themselves are
//               stored in a simple array for fast access, however there are
//               practical limits on the number of particles the scene can handle
//               because of this.
//
//
//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

class ParticleScene
{
 public:

        //----------------------------------------------------------------------
        // Functions
        //----------------------------------------------------------------------

        // Constructor

        ParticleScene();

        // Destructor

        ~ParticleScene();

        // Creates an explosion of particles at a particular point

        void createExplosion
        (
            float       x,      // position to make explostion at: x
            float       y,      // position to make explostion at: y
            float       z,      // position to make explostion at: z
            float       r1,     // 1st explosion color: r
            float       g1,     // 1st explosion color: r
            float       b1,     // 1st explosion color: r
            float       r2,     // 2nd explosion color: r
            float       g2,     // 2nd explosion color: r
            float       b2,     // 2nd explosion color: r
            float       size1,  // 1st explosion particle size
            float       size2,  // 2nd explosion particle size
            float       vel1,   // 1st explosion velocity
            float       vel2,   // 2nd explosion velocity
            float       time1,  // particle live time 1
            float       time2,  // particle live time 2
            unsigned    count   // number of particles to create in the explosion
        );

        // Like create explosion, but gives conntrol over the direction in which particles move

        void createStream
        (
            float       x,          // position to make explostion at: x
            float       y,          // position to make explostion at: y
            float       z,          // position to make explostion at: z
            float       r1,         // 1st explosion color: r
            float       g1,         // 1st explosion color: r
            float       b1,         // 1st explosion color: r
            float       r2,         // 2nd explosion color: r
            float       g2,         // 2nd explosion color: r
            float       b2,         // 2nd explosion color: r
            float       size1,      // 1st explosion particle size
            float       size2,      // 2nd explosion particle size
            float       vel1,       // 1st explosion velocity
            float       vel2,       // 2nd explosion velocity
            float       time1,      // particle live time 1
            float       time2,      // particle live time 2
            float       dir1_x,     // stream direction 1: x
            float       dir1_y,     // stream direction 1: y
            float       dir1_z,     // stream direction 1: z
            float       dir2_x,     // stream direction 2: x
            float       dir2_y,     // stream direction 2: y
            float       dir2_z,     // stream direction 2: z
            unsigned    count       // number of particles to create in the explosion
        );

        // Adds a particle into the scene if possible

        void createParticle
        (
            float x,        // particle position: x
            float y,        // particle position: y
            float z,        // particle position: z
            float r,        // particle color:  r
            float g,        // particle color:  g
            float b,        // particle color:  b
            float vel_x,    // particle movement speed: x
            float vel_y,    // particle movement speed: y
            float vel_z,    // particle movement speed: z
            float size,     // particle size
            float time      // particle live time
        );

//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

 protected:

        //----------------------------------------------------------------------
        // Structs
        //----------------------------------------------------------------------

        // Particle information structure:

        struct Particle
        {
            float pos_x;        // particle position: x
            float pos_y;        // particle position: y
            float pos_z;        // particle position: z

            float col_r;        // particle color: r
            float col_g;        // particle color: g
            float col_b;        // particle color: b

            float vel_x;        // speed the particle moves at: x
            float vel_y;        // speed the particle moves at: y
            float vel_z;        // speed the particle moves at: z

            float size;         // particle size
            float timeLeft;     // time left to live: in seconds
            float liveTime;     // total time the particle lives for in seconds
        };

        //----------------------------------------------------------------------
        // Functions
        //----------------------------------------------------------------------

        void moveParticles( float frameTime );    // move all particles in the ParticleScene
        void drawParticles( Camera * camera  );   // draw all particles in the ParticleScene

//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

 private:

        //----------------------------------------------------------------------
        // Constants
        //----------------------------------------------------------------------

        static const unsigned MAX_PARTICLES;  // maximum number of particles in a scene:

        //----------------------------------------------------------------------
        // Variables
        //----------------------------------------------------------------------

        // Number of active particles

        unsigned numParticles;

        // The particle array:

        Particle * particles;

}; // end of: class ParticleScene{}

//##############################################################################
// C++ Includes
//##############################################################################

#include "GLTextureManager.h"
#include "Camera.h"

#endif // end of: ifndef PARTICLESCENE_H
