// main.cpp : main module of the plugin
//
#include "gnupgplugin.h"
HINSTANCE dllinstance;
PLUGINLINK *pluginLink;
PLUGININFO pluginInfo = {
	sizeof(PLUGININFO),
	"GnuPG Plugin (Ansi/Unicode)",
	0x00070002,	//	version dword
	"OpenPGP/GnuPG Plugin v0.7.0.2 by Zakhar V. Bardymov ("__DATE__")\n"
	" based on GnuPG Plugin v0.0.0.4 by Harald Treder",
	"Harald Treder, Zakhar V. Bardymov",
	"harald.treder(at)gmx.de, zvb(at)irkutsk.ru",
	"GPLv2",
	"http://www.miranda-im.org",
	UNICODE_AWARE,	//	right now the only flag, UNICODE_AWARE, is recognized here
	0	//	doesn't replace anything built-in
};
struct MM_INTERFACE   mmi;
struct LIST_INTERFACE li;
struct UTF8_INTERFACE utfi;
UINT storepassphraseschecked;
UINT autoimportpublickeyschecked;
UINT loggingonchecked;
char starttag[plugintagsize];
char endtag[plugintagsize];
char *pluginid="GnuPGPlugin";
char logfile[fullfilenamesize];
// zeichenketten zur identifizierung von werten in der datenbank
char *dbexecutable="Executable";
char *dbhomedirectory="HomeDirectory";
char *dbstorepassphrases="StorePassphrases";
char *dbautoimportpublickeys="AutoImportPublicKeys";
char *dblistpublickeys="ListPublicKeys";
char *dblistsecretkeys="ListSecretKeys";
char *dbimportpublickey="ImportPublicKey";
char *dbexportpublickey="ExportPublicKey";
char *dbdetectuserid="DetectUserID";
char *dbencrypt="Encrypt";
char *dbdecrypt="Decrypt";
char *dbtempdir="Tempdir";
char *dbkeyuserid="KeyUserID";
char *dbkey="Key";
char *dbkeymodified="KeyModified";
char *dbuseencryption="UseEncryption";
char *dbstarttag="StartTag";
char *dbendtag="EndTag";
char *dbloggingon="LoggingOn";
char *dblogfile="LogFile";
void ErrorMessage(const char *alevel, const char *atext, const char *ahint)
{
	char buf[errormessagesize];
	strcpy(buf,Translate(atext));
	strcat(buf," ");
	strcat(buf,Translate(ahint));
	MessageBoxA(NULL,buf,Translate(alevel),MB_OK);
}
void LogMessage(const char *astart, const char *atext, const char *aend)
{
	if (loggingonchecked!=BST_CHECKED)
		return;
	FILE *log=fopen(logfile,"a");
	if (log)
	{
		fputs(astart,log);
		fputs(atext,log);
		fputs(aend,log);
		fclose(log);
	}
}
//	DllMain
extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	dllinstance=hinstDLL;
	return TRUE;
}
int AddContact(WPARAM wparam, LPARAM lparam)
{
	CallService(MS_PROTO_ADDTOCONTACT,wparam,(LPARAM)pluginid);
	return 0;
}
void getcontactsetting(char *ostr, const char *key, const char *defstr)
	//	zvb: Created to be used in MainInit.
{
	DBVARIANT dbv;
	int err=DBGetContactSetting(NULL,pluginid,key,&dbv);
	strcpy(ostr,(!err?dbv.pszVal:defstr));
	DBFreeVariant(&dbv);
}
int MainInit(WPARAM wparam, LPARAM lparam)
{
	PROTOCOLDESCRIPTOR pd;
	CLISTMENUITEM cmi;
	HANDLE hcontact;
	//	zvb: slightly more readable now:
	getcontactsetting(gpgExecutable,dbexecutable,txtgpgexecutable);
	getcontactsetting(gpgHomeDirectory,dbhomedirectory,txtgpghomedirectory);
	getcontactsetting(gpgArgsListPublicKeys,dblistpublickeys,txtgpgargslistpublickeys);
	getcontactsetting(gpgArgsListSecretKeys,dblistsecretkeys,txtgpgargslistsecretkeys);
	getcontactsetting(gpgArgsImportPublicKey,dbimportpublickey,txtgpgargsimportpublickey);
	getcontactsetting(gpgArgsExportPublicKey,dbexportpublickey,txtgpgargsexportpublickey);
	getcontactsetting(gpgArgsDetectUserID,dbdetectuserid,txtgpgargsdetectuserid);
	getcontactsetting(gpgArgsEncrypt,dbencrypt,txtgpgargsencrypt);
	getcontactsetting(gpgArgsDecrypt,dbdecrypt,txtgpgargsdecrypt);
	getcontactsetting(gpgTempdir,dbtempdir,txtgpgtempdir);
	getcontactsetting(starttag,dbstarttag,"\r\n");
	getcontactsetting(endtag,dbendtag,"\r\n");
	getcontactsetting(logfile,dblogfile,"c:\\miranda-gnupg.log");
	loggingonchecked=DBGetContactSettingDword(NULL,pluginid,dbloggingon,BST_UNCHECKED);
	storepassphraseschecked
		=DBGetContactSettingDword(NULL,pluginid,dbstorepassphrases,BST_CHECKED);
	autoimportpublickeyschecked
		=DBGetContactSettingDword(NULL,pluginid,dbautoimportpublickeys,BST_CHECKED);
	
	if (existsFile(gpgExecutable))
	{
		updateKeyUserIDs(publickeyuserid);
		updateKeyUserIDs(secretkeyuserid);
	}
	else
		ErrorMessage(txtwarning,txtinvalidexecutable,txtverifyoptions);
	HookEvent(ME_OPT_INITIALISE,OptionsInit);
	HookEvent(ME_USERINFO_INITIALISE,UserInfoInit);
	//	register encryption protocol
	ZeroMemory(&pd,sizeof(pd));
	pd.cbSize=sizeof(PROTOCOLDESCRIPTOR);
	pd.szName=pluginid;
	pd.type=PROTOTYPE_ENCRYPTION;
	CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd);
	
	//	send/receive functions registration
	CreateProtoServiceFunction(pluginid,PSR_MESSAGE,RecvMsgSvc);
	CreateProtoServiceFunction(pluginid,PSS_MESSAGE,SendMsgSvc);
	//	zvb: let the Unicode calls be served by them too.
	CreateProtoServiceFunction(pluginid,PSR_MESSAGE"W",RecvMsgSvc);
	CreateProtoServiceFunction(pluginid,PSS_MESSAGE"W",SendMsgSvc);
	
	//	add the protocol to all contacts found in DB
	for (
		hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
		hcontact;
		hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0)
			)
		if (!CallService(MS_PROTO_ISPROTOONCONTACT,(WPARAM)hcontact,(LPARAM)pluginid))
			CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)hcontact,(LPARAM)pluginid);
	//	kontakte zur laufzeit in die protokoll kette einhaengen
	HookEvent(ME_DB_CONTACT_ADDED,AddContact);
	CreateServiceFunction(svcuseencryption,UseEncryptionService);
	CreateServiceFunction(svcsendpublickey,SendPublicKeyService);
	
	//	set contact menu items
	ZeroMemory(&cmi,sizeof(cmi));
	cmi.cbSize=sizeof(CLISTMENUITEM);
	//	encryption menuitem
	cmi.pszName=Translate(txtuseencryption);
	cmi.position=menuitemposition;
	cmi.pszService=svcuseencryption;
	useencryption=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&cmi);
	//	sendpublickey menuitem
	cmi.pszName=Translate(txtsendpublickey);
	cmi.position=menuitemposition+1;
	cmi.pszService=svcsendpublickey;
	sendpublickey=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&cmi);
	//	hook event fuer menumodifikation
	HookEvent(ME_CLIST_PREBUILDCONTACTMENU,UpdateContactMenu);
	return 0;
}
//	MirandaPluginInfo
extern "C" __declspec(dllexport) PLUGININFO *MirandaPluginInfo(DWORD mirandaVersion)
{
	/*
	if (mirandaVersion