/***************************************************************************
 *   Copyright (C) 2005 by Thierry CHARLES   *
 *   thierry@les-charles.net   *
 *                                                                         *
 *   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 2 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 "pathres.h"
#include "lib/lib_file.h"
#include "lib/lib_logging.h"

/** Ajoute un chemin à la liste des chemins de recherche ou en change la priorité */
void PathsListRes::addPath(const wxString & sPath, bool bActive, uint iPriority)
{
    wxString sNormalizedPath = normalizePath(sPath);

    TPathsList::iterator it = this->_findFirst(sNormalizedPath);
    if(it != this->paths.end())
        this->paths.erase(it);

    if(iPriority < 0 || iPriority >= this->paths.size())
        this->paths.push_back(PathData(bActive,sNormalizedPath));
    else if(iPriority == 0)
        this->paths.push_front(PathData(bActive,sNormalizedPath));
    else
    {
        TPathsList::iterator it = this->paths.begin();
        while(it != this->paths.end() && iPriority)
        {
            it++;
            iPriority--;
        }
        this->paths.insert(it,PathData(bActive,sNormalizedPath));
    }
}

/** supprime un chemin de la liste de recherche */
void PathsListRes::removePath(const wxString & sPath)
{
    TPathsList::iterator it = this->findFirst(sPath);
    if(it != this->paths.end())
        this->paths.erase(it);
}

/**
 * renvoie le chemin complet jusqu'à un fichier
 * @param sRelativeFile nom de fichier relatif
 * @param sExecutionPath chemin d'execution du rendu : il est prioritaire sur les chemins de librairies
 * @returns "" si le fichier n'a pas pu etre trouvé
 */
wxString PathsListRes::getAbsoluteFilePath(const wxString & _sRelativeFile, const wxString sExecutionPath) const
{
    wxString sRelativeFile = normalizePath( _sRelativeFile , false);

    if(libfile::isAbsolute(sRelativeFile))
    {
        if(libfile::exists( sRelativeFile ))
            return sRelativeFile;
        else
            return wxT("");
    }

    if(sExecutionPath.length())
    {
        wxString sTestedPath = normalizePath(sExecutionPath, true) + sRelativeFile;
        if(libfile::exists(sTestedPath))
            return normalizePath( sTestedPath, false );
    }

    TPathsList::const_iterator it = this->paths.begin();
    while(it != this->paths.end())
    {
        if((*it).bActive)
        {
            wxString sTestedPath = (*it).sPath + sRelativeFile;
            if(libfile::exists(sTestedPath))
                return normalizePath( sTestedPath, false );
        }
        it++;
    }
    return wxString();
}

/** renvoie un iterator sur le premier chemin equivalent à sPath */
PathsListRes::TPathsList::iterator PathsListRes::findFirst(const wxString & sPath)
{
    return this->_findFirst(normalizePath(sPath));
}

/** normalise le chemin passé en paramètre */
wxString PathsListRes::normalizePath(const wxString & sPath, bool bDirectory)
{
    wxString sNormalizedPath = libfile::normalize( sPath );
    if(bDirectory && sNormalizedPath[sNormalizedPath.length() - 1] != '/')
        sNormalizedPath += wxT('/');

    return sNormalizedPath;
}

/** renvoie un iterator sur le premier chemin egal à sPath */
PathsListRes::TPathsList::iterator PathsListRes::_findFirst(const wxString & sNormalizedPath)
{
    TPathsList::iterator it = this->paths.begin();
    while(it != this->paths.end())
    {
        if((*it).sPath == sNormalizedPath)
            return it;
        it++;
    }
    return it;
}

/** efface toute la liste */
void PathsListRes::clear()
{
    this->paths.erase(this->paths.begin(),this->paths.end());
}
