-------------------------------
-- The different types of tiles
-------------------------------
MapTileType =
{
   GROUND = 0,
   DIRTY = 1,
   PALM = 2,
   HOUSE = 3,
}

------------------
-- Creates the map
------------------
function newMap()
   local o = {}
   
   
   -------------------------
   -- Constructor of the map
   -------------------------
   function o:construct()
      
      -- Load the sprites
      self.sprites =
      {
         [MapTileType.GROUND] = newSprite("images/sprites.png", 0,   0, 38, 38),
         [MapTileType.DIRTY]  = newSprite("images/sprites.png", 38,  0, 38, 38),
         [MapTileType.PALM]   = newSprite("images/sprites.png", 76,  0, 38, 38),
         [MapTileType.HOUSE]  = newSprite("images/sprites.png", 114, 0, 38, 38),
      }
      
      -- Build the tile-map
      self.tileMap = {}
      for i = 0, boombastic.numTilesX - 1 do
         self.tileMap[i] = {}
         for j = 0, boombastic.numTilesY - 1 do
            if (i % 2 == 1 and j % 2 == 1) then
               if ((i + j) % 4 == 2) then
                  self.tileMap[i][j] = MapTileType.PALM
               else
                  self.tileMap[i][j] = MapTileType.HOUSE
               end
            else
               self.tileMap[i][j] = MapTileType.GROUND
            end
         end
      end
      
      return self
   end
   
   
   -----------------
   -- Resets the map
   -----------------
   function o:reset()
      for i = 0, boombastic.numTilesX - 1 do
         for j = 0, boombastic.numTilesY - 1 do
            if (self.tileMap[i][j] == MapTileType.DIRTY) then
               self.tileMap[i][j] = MapTileType.GROUND
            end
         end
      end
   end
   
   
   -------------------------------------------
   -- Checks whether or not the given tile
   -- is a block (i.e. a palm-tree or a house)
   -------------------------------------------
   function o:tileIsBlock(posX, posY)
      return (self.tileMap[posX][posY] == MapTileType.PALM
              or self.tileMap[posX][posY] == MapTileType.HOUSE)
   end
   
   
   ----------------------------------------------------------
   -- Makes the ground dirty. It is used when a bomb goes off
   ----------------------------------------------------------
   function o:makeDirty(posX, posY)
      if (self.tileMap[posX][posY] == MapTileType.GROUND) then
         self.tileMap[posX][posY] = MapTileType.DIRTY
      end
   end
   
   
   -----------------------------------------------------------------------------
   -- Gets the X coordinate of the nearest vertical path from the given position
   -----------------------------------------------------------------------------
   function o:getNearestVerticalPath(x, y)
      local pathPos = 2 * math.floor((x + 0.5 * boombastic.tileSize) / (2 * boombastic.tileSize))
      pathPos = math.max(0, math.min(boombastic.numTilesX - 1, pathPos))
      return ((pathPos + 0.5) * boombastic.tileSize)
   end
   
   
   -------------------------------------------------------------------------------
   -- Gets the Y coordinate of the nearest horizontal path from the given position
   -------------------------------------------------------------------------------
   function o:getNearestHorizontalPath(x, y)
      local pathPos = 2 * math.floor((y + 0.5 * boombastic.tileSize) / (2 * boombastic.tileSize))
      pathPos = math.max(0, math.min(boombastic.numTilesY - 1, pathPos))
      return ((pathPos + 0.5) * boombastic.tileSize)
   end
   
   
   ----------------
   -- Draws the map
   ----------------
   function o:draw()
      for i = 0, boombastic.numTilesX - 1 do
         for j = 0, boombastic.numTilesY - 1 do
            local sprite = self.sprites[self.tileMap[i][j]]
            sprite:draw(boombastic.origX + i * boombastic.tileSize,
                        boombastic.origY + j * boombastic.tileSize)
         end
      end
   end

   
   return o:construct()
end
