mTimer = GUI_Slider(
   0.10,
      "Effect Duration",
      0.1,10.0);

mLifetime = GUI_Slider(
   0.65,
      "Particle Lifetime",
      0.1,3.0);

mEmitSpeed = GUI_Slider(
   75.00,
      "Emitter Speed",
      0,200);

mOffsetX = GUI_Slider(
   6.80,
      "Offset X",
      -200,200);

mOffsetY = GUI_Slider(
   -14.00,
      "Offset Y",
      -200,200);

mMinPositionSpread = GUI_Slider(
   0.00,
      "Min Position Spread",
      0,100);

mMaxPositionSpread = GUI_Slider(
   10.30,
      "Max Position Spread",
      0,100);

mMaxSpeedX = GUI_Slider(
   51.50,
      "Max Speed X",
      0,500);

mMaxSpeedY = GUI_Slider(
   43.00,
      "Max Speed Y",
      0,500);

mGravity = GUI_Slider(
   172.00,
      "Gravity",
      0,500);

mAlpha = GUI_Graph(
	{
		1.00,750,
		1.00,250,
		0.00
	},
	0.00,
	1.00,
	{
		{1.00,time=0.00},
		{1.00,time=750.00},
		{0.00,time=1000.00}
	},
	"Alpha");

mTextureName = GUI_PickTexture("fx/world4/beetle_leave_1","Particle Texture");

mBlendMode = GUI_Select(
   kBlendNormal,
      "Blend Mode",
      {
         { description="Normal", value=kBlendNormal},
         { description="Additive", value=kBlendAdditiveAlpha}
      }
);

-- ------------------------------------------------------------
-- Globals

gActive = true;
gStop = 0;

PI = 3.1415926536;

-- ------------------------------------------------------------
-- Define our particle characteristics

pVelocity = Allocate(2) ; -- Allocate a Vec2 velocity member
pAge = Allocate(1) ; -- Allocate a TReal age member
pSpin = Allocate(1); -- Allocate a TReal spin member
pSpinSpeed = Allocate(1); -- Allocate a TReal spin member

-- Set the particle texture
SetTexture(mTextureName);

-- Set the blend mode
SetBlendMode(mBlendMode);

-- LAST, we set the total number of particles in the particle
-- system. This doesn't 'create' the particles, but rather
-- allocates a block of 'dead' particles that can be created
-- below.
SetNumParticles(mEmitSpeed * mLifetime);
--SetNumParticles(mMaxParticles);

-- ------------------------------------------------------------
-- Initialization rules.
-- 
-- The following rules define how particles are created.
--
-- Any parameter below in initialization or animation rules that 
-- is a scalar, Color(), or Vec2() can alternaly take a function 
-- that returns the same type--and most functions can take any type
-- and will return that same type. The exception is any function
-- that's expecting a scalar in certain parameter positions.

-- Define dLocus for FluidFX; in the game it's defined in 
-- swarm.cpp as a data source, and it gets the mouse position.
if not dLocus then
   dLocus= Vec2(0,0) ; 
end

-- Pick a position randomly, within a range of values.
-- dLocus is defined in swarm.cpp and added to the random
-- range
--pPosition:Init(fRange(Vec2(-50, -50), Vec2(50, 50)) + dLocus);
pPosition:Init(f2dRadius(fRange(mMinPositionSpread, mMaxPositionSpread)) +
  Vec2(mOffsetX, mOffsetY) + dLocus);

-- Pick a velocity within a range
--pVelocity:Init(fRange(Vec2(-250, -250), Vec2(250, 250)));
mDirection = f2dRotation(fRange(-PI * 5 / 6, -PI / 6));
mDirection[1] = mDirection[1] / 4;
--pVelocity:Init(mDirection * fRange(mMinSpeed, mMaxSpeed));

pVelocity:Init(fRange(Vec2(-mMaxSpeedX, 0), Vec2(mMaxSpeedX, -mMaxSpeedY)));

-- Start age as 0 milliseconds
pAge:Init(0);

-- Start initial rotation as a random angle
pSpin:Init( fRange( 0, 2*3.1415927 ) );

-- Start spin velocity random from -10 to 10
pSpinSpeed:Init( fRange( -3, 3 ) );

-- ------------------------------------------------------------
-- Particle Parameter Animation Functions
--
-- The following rules define how particles animate.
-- Each rule is applied on each frame of animation.

-- Add velocity scaled by time to position
pPosition:Anim( pPosition + fTimeScale(pVelocity) );

-- Add gravity scaled by time to velocity
pVelocity:Anim(pVelocity + fTimeScale(Vec2(0, mGravity)));

-- Fade (using age) from white to yellow to black. Assumes
-- the first parameter is a number of elapsed milliseconds,
-- though can work to linearly interpolate using first 
-- scalar parameter between any value types.
-- Spin by pSpinSpeed scaled by time
pSpin:Anim( pSpin + fTimeScale( pSpinSpeed ) );

-- Set the particle's "Up" vector to the current user variable
-- "pSpin"
pUp:Anim( f2dRotation( pSpin ) );

pColor:Anim(Color(1, 1, 1, fFade(pAge / mLifetime, toparams(mAlpha))));

-- Age the particle using age function
pAge:Anim( pAge + fAge() );

-- General Anim functions
-- Expire particles over 700 ms old
Anim( fExpire( fGreater(pAge,mLifetime * 1000) ) );

-- ------------------------------------------------------------
-- Create initial particles (optional)
-- CreateParticles( 1 );

-- ------------------------------------------------------------

-- A function to run as we're executing
-- seconds - how many seconds have elapsed

timeout = NewTimeout(mTimer);

function Update(seconds)
   if gActive or gStop > 0 then
      if not timeout(seconds) and gStop == 0 then
         CreateParticles(seconds * mEmitSpeed);
      else
         if GetParticleCount() == 0 then
            Done();
         end
      end
   end -- gActive
end
