/*
Splash Screen Plugin for Miranda NG (www.miranda-ng.org)
(c) 2004-2007 nullbie, (c) 2005-2007 Thief

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 "stdafx.h"

CMPlugin g_plugin;

BOOL bstartup = true; // startup?
BOOL bserviceinvoked = false;
BOOL bmodulesloaded = false; // modules are loaded

// path to miranda's dir, config file path, splash path, sound path
wchar_t szDllName[MAX_PATH], szSplashFile[MAX_PATH], szSoundFile[MAX_PATH], szPrefix[128], inBuf[80];
wchar_t *szMirDir;
char szVersion[MAX_PATH];
#ifdef _DEBUG
wchar_t szLogFile[MAX_PATH];
#endif
SPLASHOPTS options;
HWND hwndSplash;

/////////////////////////////////////////////////////////////////////////////////////////

PLUGININFOEX pluginInfoEx = {
	sizeof(PLUGININFOEX),
	__PLUGIN_NAME,
	PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
	__DESCRIPTION,
	__AUTHOR,
	__COPYRIGHT,
	__AUTHORWEB,
	UNICODE_AWARE,
	// C64CC8E0-CF03-474A-8B11-8BD4565CCF04
	{ 0xc64cc8e0, 0xcf03, 0x474a, { 0x8b, 0x11, 0x8b, 0xd4, 0x56, 0x5c, 0xcf, 0x04 } }
};

CMPlugin::CMPlugin() :
	PLUGIN<CMPlugin>("SplashScreen", pluginInfoEx)
{}

/////////////////////////////////////////////////////////////////////////////////////////

void SplashMain()
{
	if (bstartup) {
		// Retrive path to exe of current running Miranda is located
		szMirDir = Utils_ReplaceVarsW(L"%miranda_path%");
		Miranda_GetVersionText(szVersion, MAX_PATH);

		#ifdef _DEBUG
		mir_snwprintf(szLogFile, L"%s\\%s.log", szMirDir, _A2W(__PLUGIN_NAME));
		initLog();
		wchar_t *mirandaVerString = mir_a2u(szVersion);
		logMessage(L"Miranda version", mirandaVerString);
		mir_free(mirandaVerString);
		logMessage(L"Dll Name", _A2W(__FILENAME));
		#endif

		ReadDbConfig();
	}

	if (bstartup & (options.active == 1)) {
		DBVARIANT dbv = { 0 };
		if (!g_plugin.getWString("VersionPrefix", &dbv)) {
			mir_wstrcpy(szPrefix, dbv.pwszVal);
			db_free(&dbv);
		}
		else
			mir_wstrcpy(szPrefix, L"");

		if (!g_plugin.getWString("Path", &dbv)) {
			mir_wstrcpy(inBuf, dbv.pwszVal);
			db_free(&dbv);
		}
		else mir_wstrcpy(inBuf, L"splash\\splash.png");

		wchar_t szExpandedSplashFile[MAX_PATH];
		ExpandEnvironmentStrings(inBuf, szExpandedSplashFile, _countof(szExpandedSplashFile));
		mir_wstrcpy(inBuf, szExpandedSplashFile);

		wchar_t *pos3 = nullptr;
		pos3 = wcsrchr(inBuf, ':');
		if (pos3 == nullptr)
			mir_snwprintf(szSplashFile, L"%s\\%s", szMirDir, inBuf);
		else
			mir_wstrcpy(szSplashFile, inBuf);

		if (!g_plugin.getWString("Sound", &dbv)) {
			mir_wstrcpy(inBuf, dbv.pwszVal);
			db_free(&dbv);
		}
		else mir_wstrcpy(inBuf, L"sounds\\startup.wav");

		wchar_t szExpandedSoundFile[MAX_PATH];
		ExpandEnvironmentStrings(inBuf, szExpandedSoundFile, _countof(szExpandedSoundFile));
		mir_wstrcpy(inBuf, szExpandedSoundFile);

		wchar_t *pos2;
		pos2 = wcschr(inBuf, ':');
		if (pos2 == nullptr)
			mir_snwprintf(szSoundFile, L"%s\\%s", szMirDir, inBuf);
		else
			mir_wstrcpy(szSoundFile, inBuf);

		#ifdef _DEBUG
		logMessage(L"SoundFilePath", szSoundFile);
		#endif

		wchar_t szOldPath[MAX_PATH] = { 0 };

		if (options.random) // randomly select a splash file
		{
			int filescount = 0;
			wchar_t szSplashDir[MAX_PATH] = { 0 }, szSearch[MAX_PATH] = { 0 };
			wchar_t *p = nullptr;
			wchar_t files[255][50]; //TODO: make memory allocation dynamic

			mir_wstrcpy(szSplashDir, szSplashFile);
			mir_wstrcpy(szOldPath, szSplashFile);
			// find the last \ and null it out, this leaves no trailing slash
			p = wcsrchr(szSplashDir, '\\');
			if (p) *p = 0;
			// create the search filter
			mir_snwprintf(szSearch, L"%s\\*.*", szSplashDir);
			// FFFN will return filenames
			HANDLE hFind = INVALID_HANDLE_VALUE;
			WIN32_FIND_DATA ffd;
			hFind = FindFirstFile(szSearch, &ffd);
			if (hFind != INVALID_HANDLE_VALUE) {
				do {
					if (!(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) {
						#ifdef _DEBUG
						logMessage(L"Found file", ffd.cFileName);
						#endif
						//files = new char[mir_strlen(ffd.cFileName)];
						//files[filescount] = new char[mir_strlen(ffd.cFileName)];
						wchar_t ext[5];
						wmemcpy(ext, ffd.cFileName + (mir_wstrlen(ffd.cFileName) - 4), 5);

						#ifdef _DEBUG
						logMessage(L"Extention", ext);
						#endif

						if (mir_wstrcmpi(ext, L".png") & mir_wstrcmpi(ext, L".bmp"))
							continue;

						#ifdef _DEBUG
						logMessage(L"File has valid ext", ext);
						#endif
						mir_wstrcpy(files[filescount++], ffd.cFileName);
					} //if
				} while (FindNextFile(hFind, &ffd));

				srand((unsigned)time(0));
				int r = 0;
				if (filescount) r = (rand() % filescount) + 1;

				mir_snwprintf(szSplashFile, L"%s\\%s", szSplashDir, files[r - 1]);

				#ifdef _DEBUG
				logMessage(L"final file", szSplashFile);
				#endif
				FindClose(hFind);
			} //if
		}

		// Call splash display routine
		ShowSplash(false);
	}
	bstartup = false;
}

int PlugDisableHook(WPARAM wParam, LPARAM lParam)
{
	DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;

	if (options.inheritGS) {
		if (!strcmp(cws->szModule, "Skin") && !strcmp(cws->szSetting, "UseSound"))
			g_plugin.setByte("PlaySound", cws->value.bVal);

		if (!strcmp(cws->szModule, "PluginDisable") && !strcmp(cws->szSetting, _T2A(szDllName)))
			g_plugin.setByte("Active", cws->value.bVal);
	}

	return 0;
}

static int ModulesLoaded(WPARAM wParam, LPARAM lParam)
{
	bmodulesloaded = true; // all modules are loaded now, let other parts know about this fact

	if (hwndSplash) {
		if (PostMessage(hwndSplash, WM_LOADED, 0, 0)) {
			#ifdef _DEBUG
			logMessage(L"Posted WM_LOADED message", L"done");
			#endif
		}
	}

	// Service to call splash
	CreateServiceFunction(MS_SHOWSPLASH, ShowSplashService);

	#ifdef _DEBUG
	logMessage(L"Loading modules", L"done");
	#endif

	return 0;
}

int CMPlugin::Load()
{
	HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
	HookEvent(ME_OPT_INITIALISE, OptInit);
	HookEvent(ME_DB_CONTACT_SETTINGCHANGED, PlugDisableHook);

	SplashMain();
	mir_free(szMirDir);
	return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////

int CMPlugin::Unload()
{
	UnregisterClass(SPLASH_CLASS, g_plugin.getInst());
	return 0;
}