-------------------------------
-- Create a new particle-system
-------------------------------
function newParticleSystem(sprite)
   local o = {}
   
   
   -------------------------------------
   -- Constructor of the particle-system
   -------------------------------------
   function o:construct(sprite)
      self.x = 0
      self.y = 0
      self.minSpeed = 40
      self.maxSpeed = 40
      self.startSize = 1.0
      self.endSize = 1.0
      self.emissionRate = 0
      self.Lifetime = 0.1
      self.particleLife = 1.0
      self.running = false
      self.currentTime = 0.0
      self.particles = {}
      
      self.sprite = sprite
      self.sprite:setCenter(0.5, 0.5)
      self.sprite:setBlendMode(BlendMode.ADDITIVE)
      
      return self
   end
   
   
   ----------------------------------------------------------
   -- Sets the position of the emitter of the particle-system
   ----------------------------------------------------------
   function o:setPosition(x, y)
      self.x = x
      self.y = y
   end
   
   
   ----------------------------------------------------------
   -- Sets the lifetime of the emitter of the particle-system
   ----------------------------------------------------------
   function o:setLifetime(lifetime)
      self.lifetime = lifetime
   end
   
   
   ---------------------------------------------------------
   -- Sets the lifetime of a particle of the particle-system
   ---------------------------------------------------------
   function o:setParticleLife(particleLife)
      self.particleLife = particleLife
   end
   
   
   ---------------------------------------------------
   -- Sets the rate of emission of the particle-system
   ---------------------------------------------------
   function o:setEmissionRate(emissionRate)
      self.emissionRate = emissionRate
   end
   
   
   ------------------------------------------------
   -- Sets the speed of the particles of the system
   ------------------------------------------------
   function o:setSpeed(minSpeed, maxSpeed)
      self.minSpeed = minSpeed
      self.maxSpeed = maxSpeed
   end
   
   
   -----------------------------------------------
   -- Sets the size of the particles of the system
   -----------------------------------------------
   function o:setSize(startSize, endSize)
      self.startSize = startSize
      self.endSize = endSize
   end
   
   
   -----------------------------------------------------
   -- Checks wether the particle-system is still running
   -----------------------------------------------------
   function o:isRunning()
      return self.running
   end
   
   
   ----------------------------------------------------
   -- Starts the emission of particles, from the system
   ----------------------------------------------------
   function o:start()
      self.currentTime = 0.0
      self.running = true
   end
   
   
   ------------------------------
   -- Updates the particle-system
   ------------------------------
   function o:update(dt)
      
      if (self.running) then
         
         -- Emit new particles
         if (self.currentTime < self.lifetime) then
            self.currentTime = self.currentTime + dt
            local numNewParticles = math.ceil(dt * self.emissionRate)
            
            for i = 1, numNewParticles do
               local particle = {}
               local angle = 2 * math.pi * math.random()
               particle.currentTime = 0.0
               particle.x = self.x
               particle.y = self.y
               particle.dirX = math.cos(angle)
               particle.dirY = math.sin(angle)
               particle.speed = math.random(self.minSpeed, self.maxSpeed)
               particle.size = self.startSize
               particle.alpha = 255
               table.insert(self.particles, particle)
            end
         end
         
         -- Update the particles of the system
         i = 1
         while (i <= #self.particles) do
            local particle = self.particles[i]
            particle.currentTime = particle.currentTime + dt
            
            -- Remove a dead particle
            if (particle.currentTime >= self.particleLife) then
               table.remove(self.particles, i)
            
            -- Update the particle
            else
               local percent = particle.currentTime / self.particleLife
               particle.x = particle.x + particle.dirX * particle.speed * dt
               particle.y = particle.y + particle.dirY * particle.speed * dt
               particle.size = self.startSize + percent * (self.endSize - self.startSize)
               particle.alpha = 255 * (1.0 - percent)
               i = i + 1
            end
         end
         
         self.running = (self.currentTime < self.lifetime) or (#self.particles > 0)
      end
   end
   
   
   ------------------------------------
   -- Draws the particles of the system
   ------------------------------------
   function o:draw()
      for k, particle in ipairs(self.particles) do
         self.sprite:draw(particle.x, particle.y, 0, particle.size, particle.size, particle.alpha)
      end
   end
   
   
   return o:construct(sprite, maxParticles)
end
