ShaderParticleSystem = {}
ShaderParticleSystem.STATE_OFF = 0
ShaderParticleSystem.STATE_TURNING_ON = 1
ShaderParticleSystem.STATE_ON = 2
ShaderParticleSystem.STATE_TURNING_OFF = 3
function ShaderParticleSystem.load(xmlFile, baseName, vehicle)
  local particle = {}
  if not hasXMLProperty(xmlFile, baseName) then
    return nil
  end
  particle.state = ShaderParticleSystem.STATE_OFF
  particle.planes = {}
  local node = Utils.indexToObject(vehicle.components, getXMLString(xmlFile, baseName .. "#node"))
  local psFile = Utils.getFilename(getXMLString(xmlFile, baseName .. "#file"), vehicle.baseDirectory)
  local rootNode = loadI3DFile(psFile, true, true, false)
  if rootNode == 0 then
    print("Error: failed to load particle plane " .. psFile)
    return
  end
  for i = getNumOfChildren(rootNode) - 1, 0, -1 do
    local child = getChildAt(rootNode, i)
    link(node, child)
    setShaderParameter(child, "fadeProgress", -1, 1, 0, 0, false)
    table.insert(particle.planes, child)
  end
  delete(rootNode)
  particle.planeFadeTime = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#fadeTime"), 1) * 1000
  particle.fadeX = {-1, 1}
  particle.fadeY = {-1, 1}
  particle.fadeCur = {-1, 1}
  particle.fadeDir = {1, 1}
  return particle
end
function ShaderParticleSystem.updateParticle(particle, dt)
  if particle.state == ShaderParticleSystem.STATE_TURNING_ON or particle.state == ShaderParticleSystem.STATE_TURNING_OFF then
    local valueX = particle.fadeCur[1] + math.abs(particle.fadeX[1] - particle.fadeX[2]) * (dt / particle.planeFadeTime) * particle.fadeDir[1]
    local valueY = particle.fadeCur[2] + math.abs(particle.fadeY[1] - particle.fadeY[2]) * (dt / particle.planeFadeTime) * particle.fadeDir[2]
    particle.fadeCur[1] = Utils.clamp(valueX, particle.fadeX[1], particle.fadeX[2])
    particle.fadeCur[2] = Utils.clamp(valueY, particle.fadeY[1], particle.fadeY[2])
    if particle.state == ShaderParticleSystem.STATE_TURNING_ON and particle.fadeCur[1] == particle.fadeX[2] and particle.fadeCur[2] == particle.fadeY[2] then
      particle.state = ShaderParticleSystem.STATE_ON
    end
    if particle.state == ShaderParticleSystem.STATE_TURNING_OFF and particle.fadeCur[1] == particle.fadeX[2] and particle.fadeCur[2] == particle.fadeY[1] then
      particle.state = ShaderParticleSystem.STATE_OFF
    end
    for _, plane in pairs(particle.planes) do
      setShaderParameter(plane, "fadeProgress", particle.fadeCur[1], particle.fadeCur[2], 0, 0, false)
    end
  end
end
function ShaderParticleSystem.deactiveParticle(particle)
  particle.fadeCur = {-1, 1}
  for _, plane in pairs(particle.planes) do
    setShaderParameter(plane, "fadeProgress", particle.fadeCur[1], particle.fadeCur[2], 0, 0, false)
  end
  particle.state = ShaderParticleSystem.STATE_OFF
end
function ShaderParticleSystem.getIsParticleAnimationRunning(particle)
  return particle.state == ShaderParticleSystem.STATE_TURNING_ON or particle.state == ShaderParticleSystem.STATE_TURNING_OFF
end
function ShaderParticleSystem.setIsTurnedOn(particle, isTurnedOn)
  if isTurnedOn then
    particle.state = ShaderParticleSystem.STATE_TURNING_ON
    particle.fadeDir = {1, 1}
    particle.fadeCur = {-1, 1}
  else
    particle.state = ShaderParticleSystem.STATE_TURNING_OFF
    particle.fadeDir = {1, -1}
    particle.fadeCur = {1, 1}
  end
end

