---------------------------------
-- Creates the grid of explosions
---------------------------------
function newExplosions()
   local o = {}
   
   
   ----------------------------------------
   -- Constructor of the grid of explosions
   ----------------------------------------
   function o:construct()
   
      -- Load the sprite
      self.sprite = newSprite("images/sprites.png", 76, 38, 38, 38)
      self.sprite:setCenter(0.5, 0.5)
      
      -- Load the sound
      self.explosionSound = newSound("sounds/explosion.wav")
      
      -- Build the grid of explosions
      self.map = {}
      for i = 0, boombastic.numTilesX - 1 do
         self.map[i] = {}
         for j = 0, boombastic.numTilesY - 1 do
            self.map[i][j] = nil
         end
      end
      
      return self
   end
   
   
   --------------------------------
   -- Resets the grid of explosions
   --------------------------------
   function o:reset()
      for i = 0, boombastic.numTilesX - 1 do
         for j = 0, boombastic.numTilesY - 1 do
            self.map[i][j] = nil
         end
      end
   end
   
   
   -------------------------------------------
   -- Makes an explosion at the given position
   -------------------------------------------
   function o:addExplosion(tileX, tileY, power)
   
      -- Create the central explosion
      if (not self.map[tileX][tileY]) then
         local explosion = {}
         explosion.currentTime = 0.0
         self.map[tileX][tileY] = explosion
      end
      
      -- Create the explosions in the 4 directions
      local dirs = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }
      for i = 1, 4 do
         for j = 1, power do
            local px = tileX + j * dirs[i][1]
            local py = tileY + j * dirs[i][2]
            
            if (not tileIsInMap(px, py)
                  or boombastic.map:tileIsBlock(px, py)) then
               break
            end
            
            explosion = {}
            explosion.currentTime = -j * 0.1
            self.map[px][py] = explosion
            
            if (boombastic.rocks:tileIsRock(px, py)
                  or boombastic.bombs:tileIsBomb(px, py)) then
               break
            end
         end
      end
      
      -- Create the particle-explosion
      local x, y = convertTileToPixels(tileX, tileY)
      boombastic.particleSystems:addFireExplosion(x, y)
      
      -- Play the explosion sound
      self.explosionSound:play()
   end
   
   
   -------------------------------------------------------
   -- Checks whether or not the given tile is an explosion
   -------------------------------------------------------
   function o:tileIsExplosion(tileX, tileY)
      return (self.map[tileX][tileY] ~= nil)
   end
   
   
   -------------------------------------
   -- Updates the explosions of the grid
   -------------------------------------
   function o:update(dt)
      for i = 0, boombastic.numTilesX - 1 do
         for j = 0, boombastic.numTilesY - 1 do
            if (self.map[i][j]) then
               local explosion = self.map[i][j]
               local duration = boombastic.explosionDuration
               
               -- Animate the explosion
               explosion.currentTime = explosion.currentTime + dt
               explosion.angle = 2 * explosion.currentTime * 360
               
               if (explosion.currentTime < 0.0) then
                  explosion.show = false
               
               elseif (explosion.currentTime <= duration) then
                  local percent = explosion.currentTime / duration
                  percent = 1.0 - (2 * math.abs(percent - 0.5))
                  percent = 0.3 + 0.7 * percent
                  
                  explosion.alpha = percent * 255
                  explosion.scale = percent
                  explosion.show = true
               
               else
                  self.map[i][j] = nil
               end
               
               -- Destroy the elements (rocks, bombs...) under the explosion
               explosion = self.map[i][j]
               if (explosion and explosion.currentTime > 0 and explosion.currentTime < duration / 2) then
                  boombastic.rocks:destroyRock(i, j)
                  boombastic.bombs:explodeBomb(i, j)
                  local tanks = getTanksAtTile(i, j)
                  for k, tank in ipairs(tanks) do
                     tank:kill()
                  end
               end
            end
         end
      end
   end
   
   
   -------------------------------
   -- Draws the grid of explosions
   -------------------------------
   function o:draw()
      for i = 0, boombastic.numTilesX - 1 do
         for j = 0, boombastic.numTilesY - 1 do
            local explosion = self.map[i][j]
            if (explosion and explosion.show) then
               local x, y = convertTileToPixels(i, j)
               self.sprite:draw(boombastic.origX + x, boombastic.origY + y,
                                explosion.angle, explosion.scale, explosion.scale, explosion.alpha)
            end
         end
      end
   end
   

   return o:construct()
end
