/* +---------------------------------------------------------------------------+
   |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
   |                                                                           |
   |                   http://mrpt.sourceforge.net/                            |
   |                                                                           |
   |   Copyright (C) 2005-2008  University of Malaga                           |
   |                                                                           |
   |    This software was written by the Perception and Robotics               |
   |      research group, University of Malaga (Spain).                        |
   |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
   |                                                                           |
   |  This file is part of the MRPT project.                                   |
   |                                                                           |
   |     MRPT 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.                                   |
   |                                                                           |
   |   MRPT 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 MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
   |                                                                           |
   +---------------------------------------------------------------------------+ */
#ifndef  SystemUtils_H
#define  SystemUtils_H

#include <MRPT/UTILS/utils_defs.h>


/** Represents an invalid timestamp, where applicable.
  */
#define INVALID_TIMESTAMP ( 0 )

/*---------------------------------------------------------------
	Class
  ---------------------------------------------------------------*/
namespace UTILS
{
	/** A system independent time type, it holds the the number of 100-nanosecond intervals since January 1, 1601 (UTC).
     * \sa SystemUtils::getCurrentTime, SystemUtils::timeDifference, INVALID_TIMESTAMP
	 */
	typedef uint64_t TTimeStamp;

	/** Here there are useful functions related with time, files,memory, and storage of vectors in files.
	 */
	namespace SystemUtils
	{
		/** Extract just the name (without extension) of a filename from a complete path plus name plus extension.
		  *  This function works for either "/" or "\" directory separators.
		  * \sa extractFileExtension,extractFileDirectory
		  */
		std::string  extractFileName(const std::string& filePath);

		/** Extract the extension of a filename.
		  * \sa extractFileName,extractFileDirectory
		  */
		std::string  extractFileExtension(const std::string &filePath);

		/** Extract the whole path (the directory) of a filename from a complete path plus name plus extension.
		  *  This function works for either "/" or "\" directory separators.
		  * \sa extractFileName,extractFileExtension
		  */
		std::string  extractFileDirectory(const std::string &filePath);

		/** Test if a given file (or directory) exists.
		 */
		bool  fileExists(const std::string& fileName);

		/** Returns the current system time.
		 */
		UTILS::TTimeStamp  getCurrentTime( );

		/** Transform from standard "time_t" (actually a double number, it can contain fractions of seconds) to TTimeStamp.
		  */
		UTILS::TTimeStamp  time_tToTimestamp( const double &t );

		/** Transform from standard "time_t" to TTimeStamp.
		  */
		UTILS::TTimeStamp  time_tToTimestamp( const time_t &t );

		/** Retuns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds.
          	*/
		double timeDifference( const UTILS::TTimeStamp &t1, const UTILS::TTimeStamp &t2 );

		/** Transform a time interval (in seconds) into TTimeStamp (e.g. which can be added to an existing valid timestamp)
		  */
		UTILS::TTimeStamp secondsToTimestamp( const double &nSeconds );

		/** Returns a formated string with the given time difference (passed as the number of seconds), as a string [H]H:MM:SS.MILISECS
		  */
		std::string formatTimeInterval( const double &timeSeconds );

		/** Convert a timestamp into this textual form: YEAR/MONTH/DAY,HH:MM:SS.MMM
		 */
		std::string  dateTimeToString(const UTILS::TTimeStamp &t);

		/** Convert a timestamp into this textual form: YEAR/MONTH/DAY
		 */
		std::string  dateToString(const UTILS::TTimeStamp &t);

		/** Returns the number of seconds ellapsed from midnight in the given timestamp
		 */
		double  extractDayTimeFromTimestamp(const UTILS::TTimeStamp &t);

		/** Convert a timestamp into this textual form: HH:MM:SS.MMM
		 */
		std::string  timeToString(const UTILS::TTimeStamp &t);

		/** A useful function for debuging, which saves a std::vector into a text file (compat. with MATLAB)
		* \return Returns false on any error, true on everything OK.
		*/
		bool  vectorToTextFile( const std::vector<float> &vec, const std::string &fileName );

		/** A useful function for debuging, which saves a std::vector into a text file (compat. with MATLAB)
		* \return Returns false on any error, true on everything OK.
		*/
		bool  vectorToTextFile( const std::vector<double> &vec, const std::string &fileName );

		/** A useful function for debuging, which saves a std::vector into a text file (compat. with MATLAB)
		* \return Returns false on any error, true on everything OK.
		*/
		bool  vectorToTextFile( const std::vector<int> &vec, const std::string &fileName );

		/** A useful function for debuging, which saves a std::vector into a text file (compat. with MATLAB)
		* \return Returns false on any error, true on everything OK.
		*/
		bool  vectorToTextFile( const std::vector<size_t> &vec, const std::string &fileName );

		/** Returns the memory occupied by this process, in bytes
		  */
		unsigned long  getMemoryUsage();

		/** Creates a directory
		  * \return Returns false on any error, true on everything OK.
		  * \todo Seems to return false on Linux even after creating the directory OK.
		  */
		bool  createDirectory( const std::string &dirName );

		/** Deletes a single file. For multiple files see deleteFiles
		  * \return Returns false on any error, true on everything OK.
		  * \sa deleteFiles
		  */
		bool deleteFile( const std::string &fileName );

		/** Delete one or more files, especified by the (optional) path and the file name (including '?' or '*') - Use forward slash ('/') for directories for compatibility between Windows and Linux, since they will be internally traslated into backward slashes ('\') if MRPT is compiled under Windows.
		  * \sa deleteFile
		  */
		void deleteFiles(const std::string &s);

		/** Delete all the files in a given directory
		  * \sa deleteFile
		  */
		void deleteFilesInDirectory(const std::string &s);



		/** Returns a lower-case version of a string.
		  * \sa toLowerCase
		  */
		std::string  toUpperCase(const std::string& str);

		/** Returns an upper-case version of a string.
		  * \sa toUpperCase
		  */
		std::string  toLowerCase(const std::string& str);

		/** Returns the MRPT compilation date
		  */
		std::string MRPT_getCompilationDate();

		/** Returns a string describing the MRPT version including the SVN number.
		  */
		std::string MRPT_getVersion();

		/** Call this to register handlers for fatal erros (memory access,etc) that show useful debug information (It is called automatically normally, no need for the user to explicitly call this method.).
		  */
		void registerFatalExceptionHandlers();

		/** Decodes a UTF-8 string into an UNICODE string.
		  *  See http://en.wikipedia.org/wiki/UTF-8  and http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451/.
		  */
		void decodeUTF8( const std::string &strUTF8, vector_word &out_uniStr );

		/** Encodes a 2-bytes UNICODE string into a UTF-8 string.
		  *  See http://en.wikipedia.org/wiki/UTF-8 and http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451/.
		  */
        void encodeUTF8( const vector_word &input, std::string &output );

	} // End of class def.

} // End of namespace

#endif
