/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmCoreAPI.h"
#include "glmAssert.h"
#include "glmString.h"
#include "glmArray.h"

namespace glm
{
	class FileName;

	/** 
	* \brief files and directories handling
	*
	* \ingroup utils
	* \author Golaem <dev@golaem.com>
	*/
	class GLM_CORE_API FileDir
	{
	public:
		//************************************************************
		//! @name Gestion de fichiers
		//************************************************************
		//@{
		static FILE* open(const glm::GlmString& pathname, const glm::GlmString& mode);

		//------------------------------------------------------------
		//! Indique si le fichier ou un repertoire existe
		/*! \param pathname Chemin et nom du fichier ou repertoire
		\return Vrai si il existe
		*/ //---------------------------------------------------------
		static bool exist(const glm::GlmString& pathname);
		static bool exist(const char* pathname);

		//------------------------------------------------------------
		//! Renvoie la taille d'un fichier
		/*! \param pathname Chemin et nom du fichier
		\return Sa taille en octets
		*/ //---------------------------------------------------------
		static long size(const glm::GlmString& pathname);

		//------------------------------------------------------------
		//! Efface un fichier
		/*! \param pathname Chemin et nom du fichier
		*/ //---------------------------------------------------------
		static void remove(const glm::GlmString& pathname);

		/** 
		* \brief Create a directory
		* \param directoryPath The full path to directory
		* \return True if directory has been created or already exists
		*/
		static bool createDirectoryPath(const char* directoryPath);
		static bool getFileDirectoryPath(const char* filePath, char* directoryPathBuffer, size_t directoryPathBufferSize);
		
		static bool createDirectoryTree(const char* directoryPath);

		//------------------------------------------------------------
		//! Copy une fichier source dans un fichier destination (duplication)
        /*! \param srcpathname Chemin et nom du fichier source
        \param dstpathname Chemin et nom du fichier destination
        \return vrai si la copie a réussi
        */
        //---------------------------------------------------------
        static bool copy(const glm::GlmString& dstpathname, const glm::GlmString& srcpathname);
        //@}

		//------------------------------------------------------------
		//! Compare two files byte to byte
		/*! \param filePath1 the path of the first file
		\param filePath2 the path of the second file
		\return true if filePath1 and filePath2 content are the same
		*/ //---------------------------------------------------------
		static bool sameContent(const glm::GlmString& filePath1, const glm::GlmString& filePath2);
		//@}

        //************************************************************
        //! @name Gestion des répertoires
        //************************************************************
        //@{
        //------------------------------------------------------------
        //! Renvoie le charactère / ou \ utilisé pour définir les répertoires
        /*! \return le charactère correspondante
         */
        //---------------------------------------------------------
        static char slashChr()
		{
#ifdef _MSC_VER
			return '\\';
#else
			return '/';
#endif
		}

        //------------------------------------------------------------
        //! Renvoie le charactère / ou \ utilisé pour définir les répertoires
        /*! \return la chaine correspondante
		*/ //---------------------------------------------------------
		static glm::GlmString slashStr()
		{
#ifdef _MSC_VER
			return "\\";
#else
			return "/";
#endif
		}

		//------------------------------------------------------------
		//! Corrige un chemin en tenant compte de slashStr
        /*! \param pathname le chemin d'origine
        \return le chemin corrigé
        */
        //---------------------------------------------------------
        static glm::GlmString correctPath(const glm::GlmString& pathname);

		/** 
		* \brief Returns the current executable directory.
		*/
		static glm::GlmString getExecutableDirectory();

		/** 
		* \brief Returns the current executable name.
		*/
		static glm::GlmString getExecutableName();

		/** 
		* \brief Returns current working directory.
		*/
		static glm::GlmString getWorkingDirectory();
		/**
		* \brief Changes the current working directory.
		*/
		static void setWorkingDirectory(const glm::GlmString & workingDirectory);


		/**
		* \brief find a file in the system PATH environment variable
		* \param fileName name of the file to find
		* \return the path if found, an empty string otherwise
		*/
		static glm::GlmString findInSystemPath( const glm::GlmString& fileName ) ;
		//@}

		static bool getLastModificationTime(const char* filename, uint64_t& modificationTime);
		static void findFile(glm::Array<GlmString>& aList, const char *apath, const char *wild, bool recurs, bool directoriesInsteadOfFiles, bool completePath);
	};
}

