//
//  TiledMap.hpp
//  Meteor
//
//  Created by Cesar Parent on 10/09/2015.
//  Copyright © 2015 Cesar Parent. All rights reserved.
//

#ifndef TiledMap_hpp
#define TiledMap_hpp

#include "../Nodes/Layer.h"
#include "TiledMapLayer.h"
#include "Tile.h"
#include <string>
#include <unordered_map>

namespace tinyxml2 {
    class XMLDocument;
    class XMLElement;
}

/*!
 * @defgroup        tiledmap Tiled Maps
 * @brief           A set of classes that allow loading and displaying XML Tiled Maps.
 */

NS_BEGIN

/*!
 * @class           TiledMap
 * @ingroup         tiledmap
 * @brief           A special layer that displays XML-based tiledmaps.
 * @details         A tiled map is composed of layers, themselves holding tiles
 */
class TiledMap : public Layer {
public:
    
    /*!
     * @name        Creating Tiled Map objects.
     * @{
     */
    
    /*!
     * @brief       Creates a Tiled Map by loading a Tiled `.tmx` file.
     * @note        As of Meteor `1.0-a01`, only orthogonal-mode maps are supported. Objects
     *              layers are skipped.
     * @param       tmxFile     The name of a `.tmx` tiled map file.
     */
    TiledMap(const std::string& tmxFile);
    
    /*!
     * @brief       Sets the resources sub-directory that contains tileset images. By default,
     *              tilesets are loaded from the resources root.
     * @param       directory   Name of the tileset images directory.
     */
    static void
    setTilesetsDirectory(const std::string& directory);
    
    /**
     * @}
     */
    
    virtual ~TiledMap() {}
    
    /**
     * @name        Inspecting A Tiled Map's Content
     * @{
     */
    
    /*!
     * @brief       Returns the tile coordinates from a 2D position.
     * @param       position    The position to look up.
     * @return      Integer tile coordinates for the 2D position.
     */
    ivec2
    indexPathForPosition(const vec2& position) const;
    
    /*!
     * @brief       Searches the tiled map for a layer with a specific name.
     * @param       name        The name to search for.
     * @return      The layer with that name, or nil if none was found.
     */
    ARC<TiledMapLayer>
    layerNamed(const std::string& name);
    
    /**
     * @}
     */
    
    
private:
    
    void
    _parseTMXFile(tinyxml2::XMLDocument* doc);
    
    static std::string  _tilesDirectory;
    
    TiledMapInfo        _info;
    
    std::unordered_map<std::string, ARC<TiledMapLayer>> _layers;
};


NS_END

#endif /* TiledMap_hpp */
