//	FilePath.h - A class representing a file path on the OS.
//	----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//
//	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, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#ifndef FILEPATH_H_
#define FILEPATH_H_

#include <string>
#include <vector>

///	A class representing a file path on the OS.
class FilePath
{
  public:
	///	Default constructor.
	FilePath();
	///	Constructor.
	/*!
		\param p The path to initialise the object to.
	 */
	FilePath(const std::wstring& p);
	///	Copy Constructor.
	FilePath(const FilePath& other);
	///	Destructor.
	~FilePath();

	///	Sets the path.
	void setPath(const std::wstring& p);
	///	Returns the path as a string.
	const std::wstring& getPath() const {return path;};
	///	Returns the extension if this path is a file, minus the '.' prefix.
	std::wstring getExtension() const;
	///	Returns the name of the file, minus its extension.
	std::wstring getName() const;
	///	Returns the name of the file with its extension.
	std::wstring getNameWithExtension() const;

	///	Returns true if the path points to a file/directory on the filesystem.
	bool exists() const;
	///	Returns true if the path points to a file.
	bool isFile() const;
	///	Returns true if the path points to a directory.
	bool isDirectory() const;

	///	Tries to create a directory with the current path.
	/*!
		\return True if the action was successful, false otherwise.
	 */
	bool createAsDirectory() const;

	///	Returns the number of child files if path is a directory.
	int getNumChildren() const;
	///	Returns the indexed child if path is a directory.
	/*!
		\return 0 if the file does not exist/this path is not a directory. The
		caller is responsible for deleting the returned FilePath object.
	 */
	FilePath getChild(int index) const;
	///	Returns a FilePath object pointing to the named child.
	/*!
		\return An empty FilePath object. The returned file is not
		guaranteed to exist on the filesystem (i.e. you might want to use this
		method to create a file as a child of a particular directory).
	 */
	FilePath getChild(const std::wstring& child) const;

	///	Returns the parent directory.
	FilePath getParent() const;

	///	Copies the file/directory at this path to another path.
	bool copyTo(const std::wstring& dest);

	///	Returns a FilePath object pointing to the user's 'application data' directory.
	/*!
		Note: On Linux This will return /home/<user>/.<APP_NAME> where APP_NAME
		is set in the makefile.

		It is expected that this will be used like this:
		\code
		FilePath::getAppDataPath().getChild(AppSettings::applicationName).getChild(<config-file-name>);
		\endcode
	 */
	static FilePath getAppDataPath();
	///	Returns a FilePath object pointing to the current executable's directory.
	static FilePath getCurrentExecutableDir();
	///	Returns a FilePath object pointing to the parent directory for the program's data files.
	static FilePath getDataFilesDir();
	///	Returns a FilePath object pointing to the user's home directory.
	static FilePath getHomeDir();
	///	Returns a vector of the system's fonts folder(s).
	static std::vector<FilePath> getFontsDirs();
  private:
	///	The path as a string.
	std::wstring path;

#ifndef WIN32
	///	We store a narrow copy of the path string for the various POSIX functions we use.
	std::string narrowPath;
#endif
};

#endif
