/*
UserinfoEx plugin for Miranda IM

Copyright:
� 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol

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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include "commonheaders.h"
#include "version.h"

#include "mir_menuitems.h"
#include "ctrl_base.h"
#include "ctrl_button.h"
#include "ctrl_contact.h"
#include "dlg_propsheet.h"
#include "dlg_anniversarylist.h"
#include "psp_options.h"
#include "ex_import/svc_ExImport.h"
//#include "ex_import/svc_ExImVCF.h"
#include "svc_avatar.h"
#include "svc_contactinfo.h"
#include "svc_email.h"
#include "svc_gender.h"
#include "svc_homepage.h"
#include "svc_phone.h"
#include "svc_refreshci.h"
#include "svc_reminder.h"
#include "svc_timezone.h"
#include "svc_timezone_old.h"
#include "flags/svc_flags.h"

static PLUGININFOEX pluginInfo = {
	sizeof(PLUGININFOEX),
	__PLUGIN_DISPLAY_NAME,
	__VERSION_DWORD,
	__DESC,
	__AUTHOR,
	__AUTHOREMAIL,
	__COPYRIGHT,
	__AUTHORWEB,
	UNICODE_AWARE,
	// {9C23A24B-E6AA-43c6-B0B8-D6C36D2F7B57}
	{0x9c23a24b, 0xe6aa, 0x43c6, {0xb0, 0xb8, 0xd6, 0xc3, 0x6d, 0x2f, 0x7b, 0x57}}
};

static HANDLE ghModulesLoadedHook		= NULL;
static HANDLE ghTopToolBarLoaded		= NULL;
static HANDLE ghModernToolBarLoaded		= NULL;
static HANDLE ghShutdownHook			= NULL;
static HANDLE ghPrebuildStatusMenu		= NULL;
int hLangpack;

/*
============================================================================================
	event hooks
============================================================================================
*/

/**
 * This function is called by the ME_TTB_MODULELOADED event.
 * It adds a set of buttons to the TopToolbar plugin.
 *
 * @param	wParam	- not used
 * @param	lParam	- not used
 *
 * @return	always 0
 **/
static INT OnTopToolBarLoaded(WPARAM wParam, LPARAM lParam)
{
	DlgAnniversaryListOnTopToolBarLoaded();
	SvcReminderOnTopToolBarLoaded();
	return 0;
}

/**
 * This function is called by Miranda just after loading all system modules.
 *
 * @param	wParam	- not used
 * @param	lParam	- not used
 *
 * @return	always 0
 **/
static INT OnModulesLoaded(WPARAM wParam, LPARAM lParam)
{
	myGlobals.PopUpActionsExist = ServiceExists(MS_POPUP_REGISTERACTIONS);
	myGlobals.MsgAddIconExist = ServiceExists(MS_MSG_ADDICON);

	// init meta contacts
	INT_PTR ptr = CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
	myGlobals.szMetaProto = (ptr != CALLSERVICE_NOTFOUND) ? (LPCSTR)ptr : NULL;

	// options
	OptionsLoadModule();
	// create services to receive string lists of languages and timezones
	SvcConstantsLoadModule();
	// load module to remind user about birthday and a anniversary
	SvcReminderOnModulesLoaded();
	// load extended intagration services
	SvcEMailOnModulesLoaded();
	SvcHomepageLoadModule();
	SvcPhoneLoadModule();
	SvcGenderLoadModule();
	SvcFlagsOnModulesLoaded();

#ifdef _DEBUG // new feature, not in release jet
	NServices::NAvatar::OnModulesLoaded();
#endif

	// build contact's menuitems
	RebuildMenu();
	ghPrebuildStatusMenu = HookEvent( ME_CLIST_PREBUILDSTATUSMENU, (MIRANDAHOOK)RebuildAccount);

	// install known modules strings to database
	DB::Setting::WriteAString(NULL, "KnownModules", MODULELONGNAME, USERINFO","MODNAME","MOD_MBIRTHDAY","MODNAMEFLAGS);

	return 0;
}

static INT OnShutdown(WPARAM wParam, LPARAM lParam)
{
	UnhookEvent(ghShutdownHook);
	DlgContactInfoUnLoadModule();
	SvcReminderUnloadModule();

	// uninitialize classes
	CtrlContactUnLoadModule();
	CtrlButtonUnloadModule();

	SvcConstantsUnloadModule();
	UnhookEvent(ghPrebuildStatusMenu);
	SvcEMailUnloadModule();
	SvcFlagsUnloadModule();
	SvcGenderUnloadModule();
	SvcHomepageUnloadModule();
	SvcPhoneUnloadModule();

	mir_free(hMenuItemAccount);
	return 0;
}

/*
============================================================================================
	plugin interface & DllEntrypoint
============================================================================================
*/

/**
 * This function is called by Miranda to get some information about this plugin.
 *
 * @return	pointer to pluginInfo struct
 **/
extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
{
	myGlobals.mirandaVersion = mirandaVersion;
	return &pluginInfo;
}

/**
 * This function returns the provided interfaces.
 *
 * @return	array of interfaces
 **/

extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {
	MIID_UIUSERINFO,		// replace the default userinfo module
	MIID_SREMAIL,			// Send/Receive E-Mail service is provided
	MIID_LAST
};

/**
 * This function is called by Miranda just to make it possible to unload some memory, ...
 *
 * @return	0
 **/
extern "C" INT __declspec(dllexport) Unload(VOID)
{
	return 0;
}

/**
 * This function is called by Miranda to initialize the plugin.
 *
 * @return	0
 **/
extern "C" INT __declspec(dllexport) Load(void)
{
	mir_getLP(&pluginInfo);

	// init common controls
	INITCOMMONCONTROLSEX ccEx;
	ccEx.dwSize = sizeof(ccEx);
	ccEx.dwICC = ICC_WIN95_CLASSES|ICC_DATE_CLASSES;
	InitCommonControlsEx(&ccEx);

	ZeroMemory(&myGlobals, sizeof(MGLOBAL));

	// init clist interface
	pcli = (CLIST_INTERFACE*)CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, 0);

	// init new miranda timezone interface
	mir_getTMI(&tmi);

	// init freeimage interface
	INT_PTR result = CALLSERVICE_NOTFOUND;
	if(ServiceExists(MS_IMG_GETINTERFACE))
		result = CallService(MS_IMG_GETINTERFACE, FI_IF_VERSION, (LPARAM)&FIP);

	if(FIP == NULL || result != S_OK) {
		MessageBoxEx(NULL, TranslateT("Fatal error, image services not found. Flags Module will be disabled."), _T("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0);
		return 1;
	}

	if (IsWinVerVistaPlus())
	{
		HMODULE hDwmApi = LoadLibraryA("dwmapi.dll");
		if (hDwmApi)
			dwmIsCompositionEnabled = (pfnDwmIsCompositionEnabled)GetProcAddress(hDwmApi,"DwmIsCompositionEnabled");
	}

	// check for dbx_tree
	myGlobals.UseDbxTree = ServiceExists("DBT/Entity/GetRoot");

	// load icon library
	IcoLib_LoadModule();

	SvcFlagsLoadModule();
	tmi.getTimeZoneTime ? SvcTimezoneLoadModule() : SvcTimezoneLoadModule_old();
	SvcContactInfoLoadModule();
	SvcEMailLoadModule();
	SvcRefreshContactInfoLoadModule();

	CtrlContactLoadModule();
	// load my button class
	CtrlButtonLoadModule();
	// initializes the Ex/Import Services
	SvcExImport_LoadModule();
	// load the UserInfoPropertySheet module
	DlgContactInfoLoadModule();

	// Anniversary stuff
	DlgAnniversaryListLoadModule();
	SvcReminderLoadModule();

	// Now the module is loaded! Start initializing certain things
	ghModulesLoadedHook = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
	ghTopToolBarLoaded = HookEvent(ME_TTB_MODULELOADED, OnTopToolBarLoaded);
	ghShutdownHook = HookEvent(ME_SYSTEM_SHUTDOWN, OnShutdown);
	return 0;
}

/**
 * Windows needs it for loading.
 *
 * @return	TRUE
 **/
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason) {
		case DLL_PROCESS_ATTACH:
			ghInst = hinst;
			break;
	}
	return TRUE;
}