#include "stdafx.h"

const Config DEFAULT_CONFIG = {
	{0},		// Use default (My Documents/Screenshots)
	FALSE,		// Don't upload screenshots
	TRUE,		// Do keep screenshots
	FALSE,		// Don't start helper on startup
	HSC_WIN10	// Emulate Win7+ "Snipping Tool" shortcut
};

#define OpenRootKey(hkey,access)		\
	RegCreateKeyEx(HKEY_CURRENT_USER,	\
		_T(ROOT_KEYNAME),				\
		0,								\
		NULL,							\
		REG_OPTION_NON_VOLATILE,		\
		access,							\
		NULL,							\
		hkey,							\
		NULL)

// Enumeration callback for GetConfig
static BOOL
ConfigCallback(HKEY hKey,
			   LPTSTR szValName,
			   DWORD dwValSize,
			   DWORD dwValType,
			   PVOID pData)
{
	Config *cfg = pData;
	if (!cfg) return FALSE;

	CopyIfMatch(hKey, cfg,
		ScreenshotDir, REG_PATH_SZ)
	else CopyIfMatch(hKey, cfg,
		Upload, REG_DWORD)
	else CopyIfMatch(hKey, cfg,
		KeepScreenshots, REG_DWORD)
	else CopyIfMatch(hKey, cfg,
		HelperStartup, REG_DWORD)
	else CopyIfMatch(hKey, cfg,
		HelperShortcut, REG_DWORD)

	return TRUE;
}

Config *
GetConfig(void)
{
	HKEY hkRootKey = NULL;
	BOOL bRes;
	DWORD dwErr;
	HANDLE hHeap = GetProcessHeap();
	Config *cfg = HeapAlloc(hHeap, 0, sizeof(Config));

	if (!cfg) return NULL;

	// Copy in the default config
	CopyMemory(cfg, &DEFAULT_CONFIG, sizeof(Config));

	if ((dwErr = OpenRootKey(&hkRootKey, KEY_READ))) {
		HeapFree(hHeap, 0, cfg);
		SetLastError(dwErr);
		return NULL;
	}

	bRes = RegGetAllValues(hkRootKey, ConfigCallback, cfg);
	dwErr = GetLastError();
	RegCloseKey(hkRootKey);

	if (!bRes) {
		FreeConfig(cfg);
		SetLastError(dwErr);
		return NULL;
	}

	// If ScreenshotDir is NULL, set it to My Documents
	if (!strlen(cfg->ScreenshotDir)) {
		HRESULT hrRes;

		// afaict, My Pictures isn't an easily accessible folder.
		// There's CSIDL_MYPICTURES, but that's XP-only (and also
		// points to a virtual folder???).
		hrRes = SHGetFolderPath(NULL,
			CSIDL_PERSONAL,
			NULL,
			SHGFP_TYPE_CURRENT,
			cfg->ScreenshotDir);

		if (FAILED(hrRes)) {
			// TODO: error management
			// For now, just empty the string
			*cfg->ScreenshotDir = 0;
		} else {
			PathAppend(cfg->ScreenshotDir,
				_T("Screenshots"));
		}
	}

	// TODO: Detect startup

	return cfg;
}

BOOL
SaveConfig(Config *cfg)
{
	HKEY hkRootKey;
	DWORD dwErr;

	if (!cfg) return FALSE;

	if ((dwErr = OpenRootKey(&hkRootKey, KEY_WRITE))) {
		SetLastError(dwErr);
		return FALSE;
	}

	StoreConfig(hkRootKey, cfg,
		ScreenshotDir, REG_SZ)
	StoreConfig(hkRootKey, cfg,
		Upload, REG_DWORD)
	StoreConfig(hkRootKey, cfg,
		KeepScreenshots, REG_DWORD)
	StoreConfig(hkRootKey, cfg,
		HelperStartup, REG_DWORD)
	StoreConfig(hkRootKey, cfg,
		HelperShortcut, REG_DWORD)

	RegCloseKey(hkRootKey);
	return TRUE;
}

void
FreeConfig(Config *cfg)
{
	HANDLE hHeap = GetProcessHeap();
	if (!cfg) return;

	HeapFree(hHeap, 0, cfg);
	return;
}