// Include

String GetExtExecutable(const char *ext);
bool LaunchFile(const String& file);
int LaunchCommand(const char *cmd, void (*readCallBack)(String &));
int LaunchCommand(const char *cmd, String &ret);

String GetDesktopFolder();
String GetProgramsFolder();
String GetAppDataFolder();
String GetMusicFolder();
String GetPicturesFolder();
String GetVideoFolder();
String GetPersonalFolder();
String GetTemplatesFolder();
String GetDownloadFolder();

bool FileCat(const char *bigFile, const char *appendFile);


// Functions

int LaunchCommand(const char *cmd, void (*readCallBack)(String &))
{
	LocalProcess p;
	if(!p.Start(cmd))
		return -1;
	String str;
	while(p.IsRunning()) {
		str = p.Get();
		if (readCallBack)
			readCallBack(str);
		Ctrl::ProcessEvents();
	}
	str = p.Get();
	if (readCallBack)
		readCallBack(str);
	return p.GetExitCode();
}
int LaunchCommand(const char *cmd, String &ret)
{
	ret = "";
	LocalProcess p;
	if(!p.Start(cmd))
		return -1;
	while(p.IsRunning()) {
		ret.Cat(p.Get());
		Ctrl::ProcessEvents();
	}
	ret.Cat(p.Get());
	return p.GetExitCode();
}
bool LaunchFile(const String& file)
{
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
	HINSTANCE ret;
	WString fileName(file);
	ret = ShellExecuteW(NULL, L"open", fileName, NULL, L".", SW_SHOWDEFAULT);
	if ((long)ret > 32)
		return true;
	else
		return false;
#endif
#ifdef PLATFORM_POSIX
	int ret;
	if (GetDesktopManager() == "gnome") 
		ret = system("gnome-open \"" + file + "\"");
	//else if (GetDesktopManager() == "kde") 
	//	ret = system("kfmclient exec \"" + file + "\" &"); // xdg-open could be another option
	else {
		ret = system("xdg-open \"" + file + "\"");
	}
	if (ret >= 0)
		return true;
	else
		return false;
#endif
}
String GetExtExecutable(const char *ext)
{
	String exeFile;
	String file = AppendFileName(GetPersonalFolder(), String("pru.") + ext);
	SaveFile(file, " ");
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
	HINSTANCE ret;
	WString fileW(file);
	WCHAR exe[1024];
	ret = FindExecutableW(fileW, NULL, exe);
	if ((long)ret > 32)
		exeFile = WString(exe).ToString();
	else
		exeFile = "";
#endif
#ifdef PLATFORM_POSIX
	String mime;
	LaunchCommand(String("xdg-mime query filetype ") + file, mime);
	LaunchCommand(String("xdg-mime query default ") + mime, exeFile);
#endif
	DeleteFile(file);
	return exeFile;
}

#if defined(PLATFORM_WIN32)
String GetShellFolder(const char *local, const char *users) 
{
	String ret = FromSystemCharset(GetWinRegString(local, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 
									   HKEY_CURRENT_USER));
	if (ret == "" && *users != '\0')
		return FromSystemCharset(GetWinRegString(users, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 
									   HKEY_LOCAL_MACHINE));
	else
		return ret;
}
String GetIEFolder() 
{
	String ret = FromSystemCharset(GetWinRegString("Download Directory", "Software\\Microsoft\\Internet Explorer", HKEY_CURRENT_USER));
	if (ret == "")
		ret =  FromSystemCharset(GetWinRegString("Save Directory", "Software\\Microsoft\\Internet Explorer\\Main", HKEY_CURRENT_USER)); 
	return ret;
}
String GetDesktopFolder()	{return GetShellFolder("Desktop", "Common Desktop");};
String GetProgramsFolder()	{return FromSystemCharset(GetWinRegString("ProgramFilesDir", "Software\\Microsoft\\Windows\\CurrentVersion", HKEY_LOCAL_MACHINE));};
String GetAppDataFolder()	{return GetShellFolder("AppData", "Common AppData");};
String GetMusicFolder()		{return GetShellFolder("My Music", "CommonMusic");};
String GetPicturesFolder()	{return GetShellFolder("My Pictures", "CommonPictures");};
String GetVideoFolder()		{return GetShellFolder("My Video", "CommonVideo");};
String GetPersonalFolder()	{return GetShellFolder("Personal", 0);};
String GetTemplatesFolder()	{return GetShellFolder("Templates", "Common Templates");};
String GetDownloadFolder()	
{
	String browser = GetExtExecutable("html");
	browser = ToLower(browser);
	if (browser.Find("iexplore") >= 0)
		return GetIEFolder();
	else
		return GetDesktopFolder();		// I do not to do it in other browsers !!
};
#endif
#ifdef PLATFORM_POSIX
String GetPathXdg(String xdgConfigHome, String xdgConfigDirs)
{
	String ret = "";
	if (FileExists(ret = AppendFileName(xdgConfigHome, "user-dirs.dirs"))) ;
  	else if (FileExists(ret = AppendFileName(xdgConfigDirs, "user-dirs.defaults"))) ;
  	else if (FileExists(ret = AppendFileName(xdgConfigDirs, "user-dirs.dirs"))) ;
  	return ret;
}

String GetPathDataXdg(String fileConfig, const char *folder) 
{
	String fileData = LoadFile(fileConfig);
	
	int pos = fileData.Find(folder);
	if (pos < 0)
		return Null;
	pos += strlen(folder);
	
	while ((IsSpace(fileData[pos]) && fileData[pos] != '=') && fileData[pos] != '\0')
		pos++;
	if (fileData[pos] == '\0')
		return Null;
	if (fileData[pos] != '=')
		return Null;
	
	pos++;
	
	while ((IsSpace(fileData[pos]) && fileData[pos] != '\"') && fileData[pos] != '\0')
		pos++;
	if (fileData[pos] == '\0')
		return Null;
	
	String ret = "";
	if (fileData[pos] == '\"') {		//Between ""
		pos++;
		while (fileData[pos] != '\"' && fileData[pos] != '\0') {
			ret.Cat(fileData[pos]);
			pos++;
		}
	} else {
		while (!IsSpace(fileData[pos]) && fileData[pos] != '\0') {
			ret.Cat(fileData[pos]);
			pos++;
		}
	}
	
	pos = ret.Find("$HOME/");
	pos += strlen("$HOME/");
	if (pos >= 0) 
		ret = AppendFileName(GetHomeDirectory(), ret.Right(ret.GetLength()-pos));
	else if (!FileExists(ret))
		ret = AppendFileName(GetHomeDirectory(), ret);
	
	return ret;		
}
String GetShellFolder(const char *local, const char *users) 
{
 	String xdgConfigHome = GetEnv("XDG_CONFIG_HOME");
  	if (xdgConfigHome == "")		// By default
  		xdgConfigHome = AppendFileName(GetHomeDirectory(), ".config");
  	String xdgConfigDirs = GetEnv("XDG_CONFIG_DIRS");
  	if (xdgConfigDirs == "")			// By default
  		xdgConfigDirs = "/etc/xdg";
  	String xdgFileConfigData = GetPathXdg(xdgConfigHome, xdgConfigDirs);
  	String ret = GetPathDataXdg(xdgFileConfigData, local);
  	if (ret == "" && *users != '\0')
  		return GetPathDataXdg(xdgFileConfigData, users);
  	else
  		return ret;
}
String GetDesktopFolder()	{return GetShellFolder("XDG_DESKTOP_DIR", "DESKTOP");};
String GetProgramsFolder()	{return "/usr/bin;/usr/local/bin;/bin;/sbin;/usr/sbin";};
String GetAppDataFolder()	{return GetShellFolder("XDG_DOCUMENTS_DIR", "DOCUMENTS");};
String GetMusicFolder()		{return GetShellFolder("XDG_MUSIC_DIR", "MUSIC");};
String GetPicturesFolder()	{return GetShellFolder("XDG_PICTURES_DIR", "PICTURES");};
String GetVideoFolder()		{return GetShellFolder("XDG_VIDEOS_DIR", "VIDEOS");};
String GetPersonalFolder()	{return GetShellFolder("XDG_DOCUMENTS_DIR", "DOCUMENTS");};
String GetTemplatesFolder()	{return GetShellFolder("XDG_TEMPLATES_DIR", "XDG_TEMPLATES_DIR");};
String GetDownloadFolder()	{return GetShellFolder("XDG_DOWNLOAD_DIR", "DOWNLOAD");};
#endif

bool FileCat(const char *bigFile, const char *appendFile)
{
	FileAppend f(bigFile);
	if(!f.IsOpen())
		return false;
	FileIn fi(appendFile);
	if(!fi.IsOpen())
		return false;
	CopyStream(f, fi, fi.GetLeft());
	fi.Close();
	f.Close();
	if(f.IsError()) 
		return false;
	return true;
}

