//
//  SuperTuxKart - a fun racing game with go-kart
//  Copyright (C) 2006-2015 SuperTuxKart-Team
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 3
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


#include "map_manager.h"
#include "map.h"

#include "../config/stk_config.h"
#include "../graphics/irr_driver.h"
#include "../io/file_manager.h"


#include <algorithm>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <stdio.h>

MapManager* map_manager = 0;
std::vector<std::string>  MapManager::m_map_search_path;

/** Constructor (currently empty). The real work happens in loadTrackList.
 */
MapManager::MapManager()
{}   // TrackManager

//-----------------------------------------------------------------------------
/** Delete all tracks.
 */
MapManager::~MapManager()
{
    for(Maps::iterator i = m_maps.begin(); i != m_maps.end(); ++i)
        delete *i;
}   // ~TrackManager

//-----------------------------------------------------------------------------
/** Adds a directory from which tracks are loaded. The track manager checks if
 *  either this directory itself contains a track, and if any subdirectory
 *  contains a track.
 *  \param dir The directory to add.
 */
void MapManager::addMapSearchDir(const std::string &dir)
{
    m_map_search_path.push_back(dir);
}   // addTrackDir



//-----------------------------------------------------------------------------
/** Get TrackData by the track identifier.
 *  \param ident Identifier = basename of the directory the track is in.
 *  \return      The corresponding track object, or NULL if not found
 */
Map* MapManager::getMap(const std::string& ident) const
{
    for(Maps::const_iterator i = m_maps.begin(); i != m_maps.end(); ++i)
    {

        if ((*i)->getIdent() == ident)
            return *i;
    }

    return NULL;

}   // getTrack

//-----------------------------------------------------------------------------
/** Removes all cached data from all tracks. This is called when the screen
 *  resolution is changed and all textures need to be bound again.
 */
void MapManager::removeAllCachedData()
{
    for(Maps::const_iterator i = m_maps.begin(); i != m_maps.end(); ++i)
        (*i)->removeCachedData();
}   // removeAllCachedData


//-----------------------------------------------------------------------------
/** Returns a list with all track identifiert.
 */
std::vector<std::string> MapManager::getAllMapIdentifiers()
{
    std::vector<std::string> all;

    for(Maps::const_iterator i = m_maps.begin(); i != m_maps.end(); ++i)
    {

        all.push_back((*i)->getIdent());
    }
    return all;
}   // getAllTrackNames

//-----------------------------------------------------------------------------
/** Loads all tracks from the track directory (data/track).
 */
void MapManager::loadMapList()
{
    m_all_map_dirs.clear();

    m_maps.clear();
    for(unsigned int i=0; i<m_map_search_path.size(); i++)
    {
        const std::string &dir = m_map_search_path[i];

        // First test if the directory itself contains a track:
        // ----------------------------------------------------
        if(loadMap(dir)) continue;  // track found, no more tests

        // Then see if a subdir of this dir contains tracks
        // ------------------------------------------------
        std::set<std::string> dirs;
        file_manager->listFiles(dirs, dir);
        for(std::set<std::string>::iterator subdir = dirs.begin();
            subdir != dirs.end(); subdir++)
        {
            if(*subdir=="." || *subdir=="..") continue;
            loadMap(dir+*subdir+"/");
        }   // for dir in dirs
    }   // for i <m_track_search_path.size()
}  // loadTrackList

// ----------------------------------------------------------------------------
/** Tries to load a track from a single directory. Returns true if a track was
 *  successfully loaded.
 *  \param dirname Name of the directory to load the track from.
 */
bool MapManager::loadMap(const std::string& dirname)
{
    std::string config_file = dirname+"map.xml";
    if(!file_manager->fileExists(config_file))
        return false;

    Map *l_map;

    try
    {
        l_map = new Map(config_file);
    }
    catch (std::exception& e)
    {
        Log::error("MapManager", "Cannot load map <%s> : %s\n",
                dirname.c_str(), e.what());
        return false;
    }


    m_all_map_dirs.push_back(dirname);
    m_maps.push_back(l_map);
    //updateGroups(l_map);



    return true;
}   // loadTrack

// ----------------------------------------------------------------------------
/** Removes a track.
 *  \param ident Identifier of the track (i.e. the name of the directory).
 */
void MapManager::removeMap(const std::string &ident)
{
    Map *l_map = getMap(ident);
    if (l_map == NULL)
        Log::fatal("MapManager", "There is no map named '%s'!!", ident.c_str());

    //if (l_map->isInternal()) return;

    std::vector<Map*>::iterator it = std::find(m_maps.begin(),
                                                 m_maps.end(), l_map);
    if (it == m_maps.end())
        Log::fatal("MapManager", "Cannot find map '%s' in map!!", ident.c_str());

    int index = it - m_maps.begin();







    // Adjust all indices of tracks with an index number higher than
    // the removed track, since they have been moved down. This must
    // be done for all tracks and all arenas


    m_maps.erase(it);
    m_all_map_dirs.erase(m_all_map_dirs.begin()+index);
    delete l_map;
}   // removeTrack


// ----------------------------------------------------------------------------
