/*
   render/particleejectorscript.h
   This file is part of the Osirion project and is distributed under
   the terms of the GNU General Public License version 2
*/

#ifndef __INCLUDED_RENDER_PARTICLEEJECTORSCRIPT_H__
#define __INCLUDED_RENDER_PARTICLEEJECTORSCRIPT_H__

#include "math/axis.h"
#include "math/color.h"
#include "math/vector2f.h"
#include "math/vector3f.h"
#include "model/model.h"

namespace render {
	
class ParticleEjectorScript {
public:
	
	/**
	 * @brief definition for type of ejector
	 * */
	enum Type { Sprite = 0, Flare = 1, Trail = 2, Flame = 3 , Streak = 4 };
	
	ParticleEjectorScript();
	ParticleEjectorScript(const ParticleEjectorScript & other);
	
	~ParticleEjectorScript();

	/* ---- inspectors ----------------------------------------- */
	
	/**
	 * @brief the tytpe of ejector
	 * */
	inline const Type type() const
	{
		return script_type;
	}
	
	/**
	 * @brief ejector axis relative to the particle system
	 * */
	inline const math::Axis &axis() const
	{
		return script_axis;
	}
	
	inline const unsigned int interval() const
	{
		return script_interval;
	}
	
	inline const unsigned long timeout() const
	{
		return script_timeout;
	}
	
	/**
	 * @brief angle of the cone through which to randomly spread ejected particles
	 * */
	inline const float cone() const
	{
		return script_cone;
	}
	
	/**
	 * @brief offset defines the interpolation midpoint for alpha and radius ranges, default 0.5f
	 * */
	inline const float offset() const {
		return script_offset;
	}

	/**
	 * @brief lifespan of ejected particles, in milliseconds
	 * */
	inline const unsigned long lifespan() const {
		return script_lifespan;
	}
	
	/**
	 * @brief true if engine color is to be applied to ejected particles
	 * */
	inline const bool engine() const {
		return script_engine;
	}
	
	/**
	 * @brief true if entity primary color is to be applied to ejected particles
	 * */
	inline const bool entity() const
	{
		return script_entity;
	}
	
	/**
	 * @brief true for a thrust activated ejector
	 * */
	inline const bool thrust() const
	{
		return script_thrust;
	}

	/**
	 * @brief true for a thrust impulse ejector
	 * */
	inline const bool impulse() const
	{
		return script_impulse;
	}

	/**
	 * @brief true for a thrust impulse ejector
	 * */
	inline const bool explosion() const
	{
		return script_explosion;
	}
	
	/**
	 * @brief true if entity secondary color is to be applied to ejected particles
	 * */
	inline const bool entity_second() const
	{
		return script_entity_second;
	}
	
	/**
	 * @brief true if particles are drawn in model coordinates
	 * */
	inline const bool attached() const
	{
		return script_attached;
	}
	
	/**
	 * @brief true if particle color is interpolated between color() and color_second()
	 * */
	inline const bool color_interpolated() const
	{
		return script_color_interpolated;
	}
	
	/**
	 * @brief ejector particles and speed are scaled according to modelscale
	 * */
	inline const bool scaled() const
	{
		return script_scaled;
	}


	/**
	 * @brief name of the texture used to render ejected particles
	 * */
	inline const std::string &texture() const {
		return script_texture;
	}
	
	
	inline const model::Cull cull() const
	{
		return script_cull;
	}

	/**
	 * @brief color used to render ejected particles
	 * */
	inline const math::Color &color() const
	{
		return script_color;
	}
	
	/**
	 * @brief secondary color used to render ejected particles
	 * */
	inline const math::Color &color_second() const
	{
		return script_color_second;
	}
	
	/**
	 * @brief radius vector for ejected particles, start, middle, end
	 * The radius is interpolated depending on the age and lifespan of the particle
	 * */
	inline const math::Vector3f &radius_vec() const
	{
		return script_radius_vec;
	}

	/**
	 * @brief alpha vector for ejected particles, start, middle, end
	 * The alpha value is interpolated depending on the age and lifespan of the particle
	 * */
	inline const math::Vector3f & alpha_vec() const
	{
		return script_alpha_vec;
	}

	/**
	 * @brief minimum and maximum speed of ejected particles, in gameunits per second
	 * */
	inline const math::Vector2f & speed_vec() const
	{
		return script_speed_vec;
	}
	
	/**
	 * @brief minimum and maximum tail speed of ejected particles, in gameunits per second
	 * */
	inline const math::Vector2f & tailspeed_vec() const
	{
		return script_tailspeed_vec;
	}
	
	/**
	 * @brief acceleration of ejected particles, in gameunits per second squared
	 * */
	inline const float acceleration() const
	{
		return script_acceleration;
	}
	
	/** 
	 * @brief spawn radius
	 * radius within wich particles are spawn
	 * */
	inline const float spawn_radius() const
	{
		return script_spawn_radius;
	}
	
	/* ---- mutators ------------------------------------------- */
	
	/**
	 * @brief return a reference to the ejector axis
	 * */
	inline math::Axis &get_axis()
	{
		return script_axis;
	}
	
	/** 
	 * @brief return a reference to the radius vector
	 * */
	inline math::Vector3f &get_radius_vec()
	{
		return script_radius_vec;
	}
	
	/** 
	 * @brief return a reference to the alpha vector
	 * */
	inline math::Vector3f &get_alpha_vec()
	{
		return script_alpha_vec;
	}
	
	/** 
	 * @brief return a reference to the speed vector
	 * */
	inline math::Vector2f &get_speed_vec()
	{
		return script_speed_vec;
	}
	
	/** 
	 * @brief return a reference to the tail speed vector
	 * */
	inline math::Vector2f &get_tailspeed_vec()
	{
		return script_tailspeed_vec;
	}	
	
	/** 
	 * @brief return a reference to primary particle color
	 * */
	inline math::Color &get_color()
	{
		return script_color;
	}
	
	/** 
	 * @brief return a reference to secondary particle color
	 * */
	inline math::Color &get_color_second()
	{
		return script_color_second;
	}
	
	/**
	 * @brief set the ejector type
	 * */
	inline void set_type(const Type type)
	{
		script_type = type;
	}
	
	/**
	 * @brief set the radius within which particles are spawned
	 * */
	void set_spawn_radius(const float spawn_radius)
	{
		script_spawn_radius = spawn_radius;
	}
	
	/**
	 * @brief set the speed of ejected particles, in gameunits per second
	 * */
	inline void set_speed_vec(const math::Vector2f &speed_vec)
	{
		script_speed_vec.assign(speed_vec);
	}
	
	/**
	 * @brief set the acceleration of ejected particles, in gameunits per second squared
	 * */
	inline void set_acceleration(const float acceleration)
	{
		script_acceleration = acceleration;
	}
	
	/**
	 * @brief set ejector cone, in degrees
	 * */
	inline void set_cone(const float cone)
	{
		script_cone = cone;
	}
	
	/**
	 * @brief set ejector interval, in milliseconds
	 * */
	inline void set_interval(const unsigned long interval)
	{
		script_interval = interval;
	}

	/**
	 * @brief set the time after which no more particles are ejected, in milliseconds
	 * */
	inline void set_timeout(const unsigned long timeout)
	{
		script_timeout = timeout;
	}
	
	/**
	 * @brief set particle lifespan, in milliseconds
	 * */
	inline void set_lifespan(const unsigned long lifespan)
	{
		script_lifespan = lifespan;
	}
	
	/**
	 * @brief set polygon cull rule
	 * */
	inline void set_cull(const model::Cull cull)
	{
		script_cull = cull;
	}
	
	/**
	 * @brief set texture name
	 * */
	inline void set_texture(const std::string &texture)
	{
		script_texture.assign(texture);
	}
	
	/**
	 * @brief temporal interpolation midpoint, default 0.5f
	 * */
	inline void set_offset(const float offset)
	{
		script_offset = offset;
	}
	
	/**
	 * @brief set the radius vector
	 * */
	inline void set_radius_vec(const math::Vector3f radius_vec)
	{
		script_radius_vec.assign(radius_vec);
	}
	
	/**
	 * @brief set the alpha vector
	 * */
	inline void set_alpha_vec(const math::Vector3f alpha_vec)
	{
		script_alpha_vec.assign(alpha_vec);
	}
	
	/**
	 * @brief set particle entity primary color
	 * */
	inline void set_entity(const bool use_color_entity)
	{
		script_entity = use_color_entity;
	}
	
	/**
	 * @brief set particle entity secondary color
	 * */
	inline void set_entity_second(const bool use_color_entity_second)
	{
		script_entity_second = use_color_entity_second;
	}
	
	/**
	 * @brief set particle engine color
	 * */
	inline void set_engine(const bool use_color_engine)
	{
		script_engine = use_color_engine;
	}
	
	/**
	 * @brief enable or disable thrust activated ejector
	 * */
	inline void set_thrust(const bool use_thrust)
	{
		script_thrust = use_thrust;
	}
	
	/**
	 * @brief enable or disable impulse activated ejector
	 * */
	inline void set_impulse(const bool use_impulse)
	{
		script_impulse = use_impulse;
	}

	/**
	 * @brief enable or disable explosion activated ejector
	 * */
	inline void set_explosion(const bool use_explosion)
	{
		script_explosion = use_explosion;
	}
	
	/**
	 * @brief ejector particles are drawn in entity coordinates
	 * */
	inline void set_attached(const bool attached)
	{
		script_attached = attached;
	}
	
	/**
	 * @brief set to true to interpolate particle color between color() and color_second()
	 * */
	inline void set_color_interpolated(const bool color_interpolated)
	{
		script_color_interpolated = color_interpolated;
	}
	
	inline void set_scaled(const bool scaled)
	{
		script_scaled = scaled;
	}
	
	/** 
	 * @brief set the particle color at the begin of lifespan
	 * */
	inline void set_color(const math::Color &color)
	{
		script_color.assign(color);
	}
	
	/** 
	 * @brief set the particle color at the end of lifespane
	 * */
	inline void set_color_second(const math::Color &color_second)
	{
		script_color_second.assign(color_second);
	}
	
private:
	/// type of ejector
	Type		script_type;
	/// ejector axis, relative to the particle system axis
	math::Axis	script_axis;
	/// interval between to ejects, in milliseconds
	unsigned long	script_interval;
	/// time after which no more particles are ejected, in milliseconds
	unsigned long	script_timeout;
	/// lifespan of a particle, in milliseconds
	unsigned long	script_lifespan;
	/// ejector cone, in  default 360 degrees
	float		script_cone;
	/// offset defines the 'middle' point for radius and alpha, range 0.0f-1.0f, default 0.5f.
	float		script_offset;
	/// particle alpha vector: 0.0 - middle - 1.0
	math::Vector3f	script_alpha_vec;
	/// particle radius vector: 0.0 - middle - 1.0
	math::Vector3f	script_radius_vec;
	
	/// minimum and maximum speed of ejected particles, in gameunits per second
	math::Vector2f	script_speed_vec;
	/// minimum and maximum speed of ejected tail particles, in gameunits per second
	math::Vector2f	script_tailspeed_vec;
	/// acceleration of ejected particles, in gameunits per second squared
	float		script_acceleration;
	/// spawn radius
	float 		script_spawn_radius;

	/// color of ejected particles at start of lifespan
	math::Color	script_color;
	
	/// color of ejected particles at end of lifespan
	math::Color	script_color_second;
	
	/// true of the particle color has to be interpolated betwoon color and color_second
	bool script_color_interpolated;
	
	/// particles have entity primary color
	bool		script_entity;
	/// particles have entity secondary color
	bool		script_entity_second;
	/// particles jave engine color
	bool		script_engine;
	/// thrust activated ejector
	bool		script_thrust;
	/// impulse activated ejector
	bool		script_impulse;
	/// explosion activated ejector
	bool		script_explosion;
	/// ejector is attached to entity coordinates
	bool		script_attached;
	/// ejector particles and speed are scaled according to modelscale
	bool		script_scaled;
	
	/// texture to render particles with
	std::string	script_texture;
	/// texture cull 
	model::Cull	script_cull;
};
	
}  // namespace render

#endif // __INCLUDED_RENDER_PARTICLEEJECTORSCRIPT_H__