/****************************************************************************
** Class Utils implementation ...
**
** Created: Wed Sep 09 07:53:05 2004
**
** Here we have some misc functions which are needed by a few classes 
** but can not really be assigned to any of those classes.
**
****************************************************************************/

#include <qfileinfo.h>
#include <qfile.h>

#include "global.h"
#include "utils.h"

void Utils::Test ()
{
	iTest = 1;
}

Utils::Utils()
{

}

Utils::~Utils ()
{

}

QString Utils::iso639 (QString qsCode, bool bReverse)
{
	// This function will return the Country name of the found two-letter - code
	// according to the iso639 standard (ftp://dkuug.dk/i18n/ISO_639)
	char *arrayCountry [] = {"aa", "Afar", "ab", "Abkhazian", "af", "Afrikaans", 
	"am", "Amharic", "ar", "Arabic", "as", "Assamese", "ay", "Aymara", "az", "Azerbaijani", 
	"ba", "Bashkir", "be", "Byelorussian", "bg", "Bulgarian", "bh", "Bihari", "bi", "Bislama", 
	"bn", "Bengali; Bangla", "bo", "Tibetan", "br", "Breton", "ca", "Catalan", "co", "Corsican", 
	"cs", "Czech", "cy", "Welsh", "da", "Danish", "de", "German", "dz", "Bhutani", "el", "Greek", 
	"en", "English", "eo", "Esperanto", "es", "Spanish", "et", "Estonian", "eu", "Basque", 
	"fa", "Persian", "fi", "Finnish", "fj", "Fiji", "fo", "Faroese", "fr", "French", "fy", "Frisian", 
	"ga", "Irish", "gd", "Scots Gaelic", "gl", "Galician", "gn", "Guarani", "gu", "Gujarati", 
	"ha", "Hausa", "he", "Hebrew (formerly iw)", "hi", "Hindi", "hr", "Croatian", "hu", "Hungarian", 
	"hy", "Armenian", "ia", "Interlingua", "id", "Indonesian (formerly in)", "ie", "Interlingue", 
	"ik", "Inupiak", "is", "Icelandic", "it", "Italian", "iu", "Inuktitut", "ja", "Japanese", 
	"jw", "Javanese", "ka", "Georgian", "kk", "Kazakh", "kl", "Greenlandic", "km", "Cambodian", 
	"kn", "Kannada", "ko", "Korean", "ks", "Kashmiri", "ku", "Kurdish", "ky", "Kirghiz", 
	"la", "Latin", "ln", "Lingala", "lo", "Laothian", "lt", "Lithuanian", "lv", "Latvian, Lettish", 
	"mg", "Malagasy", "mi", "Maori", "mk", "Macedonian", "ml", "Malayalam", "mn", "Mongolian", 
	"mo", "Moldavian", "mr", "Marathi", "ms", "Malay", "mt", "Maltese", "my", "Burmese", 
	"na", "Nauru", "ne", "Nepali", "nl", "Dutch", "no", "Norwegian", "oc", "Occitan", 
	"om", "(Afan) Oromo", "or", "Oriya", "pa", "Punjabi", "pl", "Polish", "ps", "Pashto, Pushto", 
	"pt", "Portuguese", "qu", "Quechua", "rm", "Rhaeto-Romance", "rn", "Kirundi", "ro", "Romanian", 
	"ru", "Russian", "rw", "Kinyarwanda", "sa", "Sanskrit", "sd", "Sindhi", "sg", "Sangho", 
	"sh", "Serbo-Croatian", "si", "Sinhalese", "sk", "Slovak", "sl", "Slovenian", "sm", "Samoan", 
	"sn", "Shona", "so", "Somali", "sq", "Albanian", "sr", "Serbian", "ss", "Siswati", "st", "Sesotho", 
	"su", "Sundanese", "sv", "Swedish", "sw", "Swahili", "ta", "Tamil", "te", "Telugu", "tg", "Tajik", 
	"th", "Thai", "ti", "Tigrinya", "tk", "Turkmen", "tl", "Tagalog", "tn", "Setswana", "to", "Tonga", 
	"tr", "Turkish", "ts", "Tsonga", "tt", "Tatar", "tw", "Twi", "ug", "Uighur", "uk", "Ukrainian", 
	"ur", "Urdu", "uz", "Uzbek", "vi", "Vietnamese", "vo", "Volapuk", "wo", "Wolof", "xh", "Xhosa", 
	"yi", "Yiddish (formerly ji)", "yo", "Yoruba", "za", "Zhuang", "zh", "Chinese", "zu", "Zulu"};
	uint t, iCount;
	int iReverse;
	QString qsReturn;
	iCount = (int)(sizeof (arrayCountry) / (sizeof (char *) * 2.0));
	// Determines forward/backward looking up.
	iReverse = 0;
	if (bReverse)
		iReverse = -1;
	
	for (t=0;t<iCount;t++)	{
		if (qsCode == arrayCountry[t*2 - iReverse])	{
			qsReturn = QString ((char *)arrayCountry[t*2+1 + iReverse]);
			return qsReturn;
		}
	}
	return qsCode;
}

QString Utils::checkForExe( QString qsExe )
{
	QString qsExePath;
	QFileInfo fileInfo("/tmp/out.txt");
	// the next check is to see if we can find 
	system ((const char *)QString ("which %1 > /tmp/out.txt 2>/dev/null").arg(qsExe));
	fileInfo.setFile("/tmp/out.txt");
	// Okay we can not find it, so we wont bother asking the user ...
	if (fileInfo.size() > 4)	{
		QFile theFile ("/tmp/out.txt");
		theFile.open (IO_ReadOnly);
		theFile.readLine(qsExePath, 4096);
		theFile.close();
		if (!qsExePath.isEmpty())	{
			qsExePath.remove("\n");
			return qsExePath;
		}
	}
	return QString();
}

QString Utils::getToolsDisplayName (QString qsExecutableName)
{
	int t = getIndexFromToolName (qsExecutableName);
	// All external Tools are defined in global.h
	struct structTools { 
		char *pExecutableName;
		char *pDisplayName;
		char *pDescription;
	};
	const structTools toolsArray[] = { EXTERNAL_TOOLS };

	if (t >= 0)
		return QString (toolsArray[t].pDisplayName);
	return qsExecutableName;
}

int Utils::getIndexFromToolName (QString qsExecutableName)
{
	uint t, iNrOfTools;
	// All external Tools are defined in global.h
	struct structTools { 
		char *pExecutableName;
		char *pDisplayName;
		char *pDescription;
	};
	const structTools toolsArray[] = { EXTERNAL_TOOLS };
	iNrOfTools = sizeof (toolsArray) / ((sizeof (char *) * 3));

	for (t=0;t<iNrOfTools;t++)
		if (qsExecutableName == QString (toolsArray[t].pExecutableName))
			return t;
	return -1;
}

QString Utils::getToolByIndex (uint iIndex)
{
	uint iNrOfTools;
	// All external Tools are defined in global.h
	struct structTools { 
		char *pExecutableName;
		char *pDisplayName;
		char *pDescription;
	};
	const structTools toolsArray[] = { EXTERNAL_TOOLS };
	iNrOfTools = sizeof (toolsArray) / ((sizeof (char *) * 3));
	if (iIndex > iNrOfTools-1)
		return QString();

	return QString (toolsArray[iIndex].pExecutableName);
}

QValueList<Utils::toolsPaths *>Utils::scanSystem()
{
	static QValueList<Utils::toolsPaths *>listToolsPaths;
	Utils::toolsPaths *pEntry;

	uint t, iNrOfTools;
	// All external Tools are defined in global.h
	struct structTools { 
		char *pExecutableName;
		char *pDisplayName;
		char *pDescription;
	};
	const structTools toolsArray[] = { EXTERNAL_TOOLS };
	iNrOfTools = sizeof (toolsArray) / ((sizeof (char *) * 3));

	// Note at this point if there were entries in thelist they ought to be deleted already.
	listToolsPaths.clear();
	for (t=0;t<iNrOfTools;t++)	{
		pEntry = new Utils::toolsPaths;
		pEntry->qsExecutableName = QString( toolsArray[t].pExecutableName );
		pEntry->qsFullPath  = checkForExe ( toolsArray[t].pExecutableName );
		if ( pEntry->qsFullPath.isEmpty() )	{
			 pEntry->qsFullPath = pEntry->qsExecutableName;
			 pEntry->bPresent = false;
		}
		else
			pEntry->bPresent = true;
		listToolsPaths.append(pEntry);
	}
	// Please remember unlike the norm to create/destroy objects in the same class I pass the entries in this list on to another class.
	return listToolsPaths;
}

