#include "stdafx.h"

#include "Xfire_base.h"
#include "variables.h"

//rechnet die einzelnen chars des strings zusammen
BYTE Xfire_base::accStringByte(char* str){
	BYTE temp=0;

	//keins tirng? bye bye
	if (str==NULL)
		return 0;

	for(unsigned int i=0;i<(int)strlen(str);i++)
	{
		temp+=str[i];
	}

	return temp;
}

//lowercased einen string
void Xfire_base::strtolower(char*str)
{
	//keins tirng? bye bye
	if (str==NULL)
		return;

	//lowercase it :)
	for(unsigned int i=0;i<(int)strlen(str);i++)
	{
		str[i]=tolower(str[i]);
	}
}

void Xfire_base::strtolowerT(TCHAR*str)
{
	//keins tirng? bye bye
	if (str==NULL)
		return;

	//lowercase it :)
	for(unsigned int i=0;i<(int)_tcslen(str);i++)
	{
		str[i]=tolower(str[i]);
	}
}

//uppercased einen string
void Xfire_base::strtoupper(char*str)
{
	//keins tirng? bye bye
	if (str==NULL)
		return;

	//lowercase it :)
	for(unsigned int i=0;i<(int)strlen(str);i++)
	{
		str[i]=toupper(str[i]);
	}
}

//setzt einen string
void Xfire_base::setString(char*from,char**to)
{
	//keine quelle, kein ziel? dann nix machen
	if (from==NULL||to==NULL)
		return;

	//stringgr��e auslesen
	int size=strlen(from);

	//bestehenden zielpointer leeren
	if (*to!=NULL)
		delete[] *to;

	//neuen string anlegen
	*to=new char[size+1];

	//string in neues array kopieren
	strcpy_s(*to,size+1,from);
}

//setzt einen string
void Xfire_base::appendString(char*from,char**to)
{
	//keine quelle, kein ziel? dann nix machen
	if (from==NULL||to==NULL||*to==NULL)
		return;

	//stringgr��e auslesen
	int size=strlen(from);
	int size2=strlen(*to);

	//tempor�ren pointer anlegen
	char* append=new char[size+size2+1];

	//string in neues array kopieren
	strcpy_s(append,size+size2+1,*to);
	//zus�tzlichen stirng anh�ngen
	strcat_s(append,size+size2+1,from);
	//altes to entfernen
	delete[] *to;
	//appendstring zuordnen
	*to=append;
}

//liest einen stringval aus der db und setzt einen string f�r
void Xfire_base::readStringfromDB(char*name,unsigned int dbid,char**to)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||to==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	if (!db_get_s(NULL, protocolname, temp,&dbv))
	{
		//string setzen
		setString(dbv.pszVal,to);
		//dbval wieder freigeben
		db_free(&dbv);
	}
}

//liest einen stringval aus der db welches unterid hat und setzt einen string f�r
void Xfire_base::readStringfromDB(char*name,unsigned int dbid,int id,char**to)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||to==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i_%i", name, dbid, id);
	if (!db_get_s(NULL, protocolname, temp,&dbv))
	{
		//string setzen
		setString(dbv.pszVal,to);
		//dbval wieder freigeben
		db_free(&dbv);
	}
}

//liest einen stringval aus der db und setzt einen string f�r
void Xfire_base::readUtf8StringfromDB(char*name,unsigned int dbid,char**to)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||to==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	if (!db_get_utf(NULL, protocolname, temp,&dbv))
	{
		//string setzen
		setString(dbv.pszVal,to);
		//dbval wieder freigeben
		db_free(&dbv);
	}
}

//liest einen stringval aus der db welches unterid hat und setzt einen string f�r
void Xfire_base::readUtf8StringfromDB(char*name,unsigned int dbid,int id,char**to)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||to==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i_%i", name, dbid, id);
	if (!db_get_utf(NULL, protocolname, temp,&dbv))
	{
		//string setzen
		setString(dbv.pszVal,to);
		//dbval wieder freigeben
		db_free(&dbv);
	}
}


//schreibt einen stringval in die db welche unterid hat
void Xfire_base::writeStringtoDB(char*name,unsigned int dbid,int id,char*val)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||val==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i_%i", name, dbid, id);
	db_set_s(NULL, protocolname, temp,val);
}

//schreibt einen stringval in die db welche unterid hat
void Xfire_base::writeStringtoDB(char*name,unsigned int dbid,char*val)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||val==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	db_set_s(NULL, protocolname, temp,val);
}

//schreibt einen stringval in die db welche unterid hat
void Xfire_base::writeUtf8StringtoDB(char*name,unsigned int dbid,int id,char*val)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||val==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i_%i", name, dbid, id);
	db_set_utf(NULL, protocolname, temp,val);
}

//schreibt einen stringval in die db welche unterid hat
void Xfire_base::writeUtf8StringtoDB(char*name,unsigned int dbid,char*val)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL||val==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	db_set_utf(NULL, protocolname, temp,val);
}


//schreibt einen bytewert in die db
void Xfire_base::writeBytetoDB(char*name,unsigned int dbid,int val)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	db_set_b(NULL, protocolname, temp, val);
}

//schreibt einen wordwert in die db
void Xfire_base::writeWordtoDB(char*name,unsigned int dbid,int val)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL)
		return;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	db_set_w(NULL, protocolname, temp, val);
}


//liest einen byteval aus der db und gibt es zur�ck
unsigned char Xfire_base::readBytefromDB(char*name,unsigned int dbid,int defaultval)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL)
		return 0;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	return db_get_b(NULL, protocolname, temp, defaultval);
}

//liest einen wordval aus der db und gibt es zur�ck
unsigned int Xfire_base::readWordfromDB(char*name,unsigned int dbid,int defaultval)
{
	//keine quelle, kein ziel? dann nix machen
	if (name==NULL)
		return 0;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	return db_get_w(NULL, protocolname, temp, defaultval);
}

//entfernt einen dbeintrag
BOOL Xfire_base::removeDBEntry(char*name,unsigned int dbid)
{
	//kein name?
	if (name==NULL)
		return 0;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i", name, dbid);
	
	//eintrag entfernen
	if (!db_get(NULL, protocolname, temp,&dbv))
	{
		db_free(&dbv);
		db_unset(NULL, protocolname, temp);

		return TRUE;
	}
	return FALSE;
}

//entfernt einen dbeintrag welche unterid's hat
BOOL Xfire_base::removeDBEntry(char*name,unsigned int dbid,int id)
{
	//kein name?
	if (name==NULL)
		return 0;

	//wert aus der dblesen
	mir_snprintf(temp, 128, "%s_%i_%i", name, dbid, id);
	
	//eintrag entfernen
	if (!db_get(NULL, protocolname, temp,&dbv))
	{
		db_free(&dbv);
		db_unset(NULL, protocolname, temp);

		return TRUE;
	}
	return FALSE;
}

//sucht innerhalb eines strings ein anderen string und liefert true zur�ck wenn gefunden
BOOL Xfire_base::inString(char*str,char*search,char**pos) {
	//leere pointer?, dann FALSE zur�ck
	if (str==NULL||search==NULL)
	{
		//poszeiger, falls �bergeben, auf NULL setzen
		if (pos) *pos=NULL; 
		return FALSE;
	}

	//ist der gesuchte string gr��er, wie der string wo gesucht werden soll? dann FALSE zur�ck
	unsigned int sizeofsearch=strlen(search);
	if (sizeofsearch>strlen(str))
	{
		//poszeiger, falls �bergeben, auf NULL setzen
		if (pos) *pos=NULL; 
		return FALSE;
	}

	char* src=str;
	char* s=search;

	while(*src!=0)
	{
		if (*src==*s) //gleich, dann zum n�chsten buchstaben springen
			s++;
		else if (*s==0) //string ende erreicht? dann true
		{
			//poszeiger mit aktueller pos f�llen, da position gefunden
			if (pos) *pos=src-sizeofsearch;
			return TRUE;
		}
		else //anderer biuchstabe? dann wieder zur�ck zum anfangsbuchstaben
			s=search;
		src++;
	}
	if (*s==0) //string ende erreicht? dann true
	{
		//poszeiger mit aktueller pos f�llen, da position gefunden
		if (pos) *pos=src-sizeofsearch;
		return TRUE;
	}

	//poszeiger, falls �bergeben, auf NULL setzen
	if (pos) *pos=NULL; 
	//nix gefunden, FALSE
	return FALSE;
}

void Xfire_base::strreplace(char*search,char*replace,char**data) {
	if (replace == NULL)
		replace = "";

	//leere pointer?, dann zur�ck
	if (search == NULL || data == NULL || *data == NULL)
	{
		return;
	}

	char* pos=NULL;
	//gesuchten string suchen
	if (this->inString(*data,search,&pos))
	{
		//gefunden? dann replace
		*pos=0;
		char* newdata=NULL;
		//alles vorm gefunden anh�ngen
		this->setString(*data,&newdata);
		//ersetzendes anh�ngen
		this->appendString(replace,&newdata);
		//poszeiger um die gr��e des zusuchenden strings erh�hen
		pos+=strlen(search);
		//rest anh�ngen
		this->appendString(pos,&newdata);
		//alten string l�schen
		delete[] *data;
		*data=NULL;
		//neuen auf diesen setzen
		this->setString(newdata,data);
		//tempor�ren newdata l�schen
		delete[] newdata;
	}
}

//stringvergleich mit wildcards
BOOL Xfire_base::wildcmp(const TCHAR *search,const TCHAR *text) {
	//keine g�ltigen strings, dann abbruch
	if (search==NULL || text==NULL || *text==0 || *search==0)
		return FALSE;

	//wildcardmodus
	int wildc=0;

	do {
		//wilcard gefunden?
		if (*search=='*')
		{
			//wildcardmodus an
			wildc=1;
			//n�chsten suchzeichen
			search++;
			//wenn searchzeichen 0, dann 1 zur�ckgeben, da der rest des searchstings egal ist
			if (*search==0)
				return TRUE;
		}

		//pr�fe searchzeichen mit textzeichen, aber nut wenn kein wildcardmodus aktiv ist
		if (*search!=*text && !wildc)
			return FALSE;

		//kein wildcardmodus
		if (!wildc)
		{	
			//n�chstes suchzeichen
			search++;
		}
		//wenn suchzeichen und textzeichen gleich ist
		else if (*search==*text)
		{
			//den wildcardmodus abschalten
			wildc=0;
			//n�chstes suchzeichen
			search++;
		}
		//n�chstes textzeichen
		text++;
		//wenn textende erreicht und suchzeichen noch vorhanden, dann 0 zur�ckgegebn
		if (*text==0 && *search!=0)
			return FALSE;
	}
	//solange weiter bis kein suchzeichen mehr vorhanden is
	while(*search!=0);

	//textzeichen �brig 0 zur�ck
	if (*text!=0)
		return FALSE;

	//volle �bereinstimmung
	return TRUE;
}

//wrapper wenn nur gameid angegeben
BOOL Xfire_base::getIniValue(unsigned int gameid,const char* valname,char*out,int sizeofout) {
	return Xfire_base::getIniValue(gameid,0,valname,out,sizeofout);
}


//l�d einen eintrag aus der ini
BOOL Xfire_base::getIniValue(unsigned int gameid,unsigned int subid,const char* valname,char*out,int sizeofout) {
	//kein ziel oder kein variablenname, dann FALSE zur�ck
	if (!out || !valname)
		return FALSE;

	char idstring[15];
	char path[MAX_PATH];

	//pfad einlesen
	if (!getIniPath(path))
		return FALSE; //kein pfad bug?!?!

	if (subid==0) {
		mir_snprintf(idstring, 15, "%d", gameid);

		if (xfire_GetPrivateProfileString(idstring, valname, "", out, sizeofout, path))
			return TRUE;

		subid++;
	}

	mir_snprintf(idstring, 15, "%d_%d", gameid, subid);

	if (xfire_GetPrivateProfileString(idstring, valname, "", out, sizeofout, path))
		return TRUE;

	return FALSE;	
}

BOOL Xfire_base::getIniPath(char*path) {
	//kein ziel abbruch
	if (!path)
		return FALSE;
	strcpy(path, XFireGetFoldersPath ("IniFile"));
	strcat_s(path,MAX_PATH,"xfire_games.ini");
	return TRUE;
}

BOOL Xfire_base::getIconPath(char*path) {
	//kein ziel abbruch
	if (!path)
		return FALSE;
	strcpy(path, XFireGetFoldersPath ("IconsFile"));
	return TRUE;
}

BOOL Xfire_base::getGamename(unsigned int gameid,char* out,int outsize){
	//kein ziel
	if (!out)
		return FALSE;

	if (!getIniValue(gameid,"LongName",out,outsize))
	{
		//customnamen laden, wenn vorhanden
		DBVARIANT dbv;
		char dbstr[80]="";
		mir_snprintf(dbstr, XFIRE_MAXSIZEOFGAMENAME, "customgamename_%d", gameid);
		if (!db_get(NULL,protocolname,dbstr,&dbv)) {
			mir_snprintf(out, outsize, "%s", dbv.pszVal);
			db_free(&dbv);
			return TRUE;
		}
		else
			return FALSE;
	}
	return TRUE;
}

//wandelt einen buffer mit gr��e in ein hicon mit hilfe von gdi+ um
HICON Xfire_base::createHICONfromdata(LPVOID data,unsigned int size) {
	//zielspeichern anlegen
	HGLOBAL buffer=GlobalAlloc(GMEM_MOVEABLE, size); 
	if (buffer) {
		LPVOID data2=GlobalLock(buffer);
		if (data2) {
			CopyMemory(data2, data, size); 
			
			IStream* stream=NULL;
			if (CreateStreamOnHGlobal(data2,FALSE,&stream)== S_OK)
			{
				HICON hicon=NULL;
				Gdiplus::Bitmap image(stream);

				image.GetHICON(&hicon);
				stream->Release();

				GlobalUnlock(buffer);
				GlobalFree(buffer);

				return hicon;
			}
			GlobalUnlock(buffer);
		}
		GlobalFree(buffer);
	}
	return NULL;
}

//wandelt einen buffer mit gr��e in ein hicon mit hilfe von gdi+ um
HBITMAP Xfire_base::createHBITMAPfromdata(LPVOID data,unsigned int size) {
	//zielspeichern anlegen
	HGLOBAL buffer=GlobalAlloc(GMEM_MOVEABLE, size); 
	if (buffer) {
		LPVOID data2=GlobalLock(buffer);
		if (data2) {
			CopyMemory(data2, data, size); 
			
			IStream* stream=NULL;
			if (CreateStreamOnHGlobal(data2,FALSE,&stream)== S_OK)
			{
				HBITMAP hbitmap=NULL;
				Gdiplus::Bitmap image(stream);

				image.GetHBITMAP(0,&hbitmap);
				stream->Release();

				GlobalUnlock(buffer);
				GlobalFree(buffer);

				return hbitmap;
			}
			GlobalUnlock(buffer);
		}
		GlobalFree(buffer);
	}
	return NULL;
}

//pr�ft ob processid noch g�ltig is
BOOL Xfire_base::isValidPid(DWORD pid) {
	DWORD aProcesses[1024],cbNeeded,cProcesses;

	if (pid==NULL)
		return FALSE;

	if (!EnumProcesses(aProcesses,sizeof(aProcesses),&cbNeeded))
		return FALSE;

	cProcesses = cbNeeded / sizeof(DWORD);

	for ( unsigned int i = 0; i < cProcesses; i++ )
		if (aProcesses[i]==pid)
		{
			return TRUE;
		}

	return FALSE;
}

//sucht nach einen process und liefert die pid
BOOL Xfire_base::getPidByProcessName(TCHAR *name, DWORD *pid) {
	if (pid==NULL||name==NULL)
		return FALSE;

	HANDLE hSnapShot = CreateToolhelp32Snapshot ( TH32CS_SNAPALL, 0);
	PROCESSENTRY32* processInfo = new PROCESSENTRY32;
	processInfo->dwSize = sizeof ( PROCESSENTRY32);

	while ( Process32Next ( hSnapShot,processInfo ) != FALSE)
	{
		if (processInfo->th32ProcessID!=0) {
			if (_tcsicmp(processInfo->szExeFile,name)==0)
			{
				*pid=processInfo->th32ProcessID;
				CloseHandle(hSnapShot);
				return TRUE;
			}
		}
	}
	CloseHandle(hSnapShot);
	return FALSE;
}