/*

				Global application initialisation
				
*/

#include "netfone.h"

LPSTR pszFrameClass;					// MDI frame window class
LPSTR pszMDIClientClass;				// MDI client window class
LPSTR pszClientClass;					// MDI child window class
static LPSTR pszServerClass;			// MDI child window class

//	INITAPPLICATION  --  Initialise globals and register classes

BOOL InitApplication(HINSTANCE hInstance)
{
    WNDCLASS WndClass;

    hInst = hInstance;

    //  Initialise some of the global strings

#if NETFONE_COMMAND_PORT == 2074
    pszAppName = "Speak Freely";
#else
	//	Just so we don't accidentally ship one with a nonstandard port
    pszAppName = "EXPERIMENTAL Speak Freely";
#endif    
    pszFrameClass = SPEAK_FREE_FRAME_CLASS;
    pszMDIClientClass = "MDICLIENT";
    pszClientClass = "SpeakFreeClientClass";

    //  Initialise & register the various window classes
    
    //	Main (frame) window

    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = (WNDPROC) Frame_WndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(hInstance, IDI_FRAME);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = IDM_FRAME;
    WndClass.lpszClassName = pszFrameClass;

    if (!RegisterClass(&WndClass)) {
        return FALSE;
    }
    
    //	Connection client window
    
    WndClass.style |= CS_DBLCLKS;
    WndClass.lpfnWndProc = (WNDPROC) connectWndProc;
    WndClass.cbWndExtra = sizeof(LPVOID);
    WndClass.hCursor = NULL;
    WndClass.hIcon = LoadIcon(hInstance, IDI_CLIENT);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = pszClientClass;
	WndClass.hbrBackground = (HBRUSH) (COLOR_MENU + 1);

    if (!RegisterClass(&WndClass)) {
        return FALSE;
    }

    SetupICQ();				// Register Speak Freely with ICQ

    return TRUE;
}

//	INITINSTANCE  --  Initialise a new instance

BOOL InitInstance(HINSTANCE hInstance, LPSTR pszCmdLine, INT nCmdShow)
{
	RECT r;
	
	/*	Save the command line so we can use it later to open a
		connection file specified there.  */

	if (strlen(pszCmdLine) > 0) {
		commandLine = (LPSTR) GlobalAllocPtr(GPTR, strlen(pszCmdLine) + 1);
		if (commandLine != NULL) {
			strcpy(commandLine, pszCmdLine);
		}
	}	
	
    //  Create the frame window

	GetWindowRect(GetDesktopWindow(), &r);
    hwndMDIFrame = CreateWindow(pszFrameClass, pszAppName, WS_OVERLAPPEDWINDOW,
                                 CW_USEDEFAULT, CW_USEDEFAULT,
                                 (r.right - r.left) / 2, (r.bottom - r.top) / 2,
                                 NULL, NULL, hInstance, NULL);

    if (hwndMDIFrame == NULL) {
        return FALSE;
    }

    //  Load our accelerators

    hAccel = LoadAccelerators(hInst, IDA_FRAME);

    if (hAccel == NULL) {
        return FALSE;
    }

    //  Display the main window

    ShowWindow(hwndMDIFrame, nCmdShow);
    UpdateWindow(hwndMDIFrame);
    
    /*	If we were invoked with file names on the command line,
    	as happens when a .SFX file is double clicked in the File
    	Manager (assuming the association has been made), open the
    	specified connection files.  */
    
    if (commandLine != NULL) {
		ParseCommandLine(hwndMDIFrame, commandLine);
    	GlobalFreePtr(commandLine);
    	commandLine = NULL;
    }
    return TRUE;
}

/*
	This is my (Brian) implementation of the popular SpeakICQ patch.  Rather than try to
	make the original more robust, I'm writing my own.  There was no error checking in the
	original version, which could potentially be very dangerous.
*/

void SetupICQ(void)
{
	HKEY hSpeakFreelyKey, hICQ, hOwnerKey;
	char szSpeakFreelyPath[_MAX_PATH], szPreviousPath[_MAX_PATH];
	char szOwnerKey[100];
	DWORD dwDisposition, dwSize;
	int iKey;
	FILETIME ftLastWritten;

	// First, see if ICQ is installed (or at least the settings are there).
	if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Mirabilis\\ICQ", 0, KEY_ALL_ACCESS, &hICQ) != ERROR_SUCCESS) {
		return; // No, so don't do the patch.
	}

	// Now, create the Speak Freely key or open the existing key.
	if (RegCreateKeyEx(hICQ, "DefaultPrefs\\GlobalExt\\Speak Freely", 0, NULL,
					REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSpeakFreelyKey,
					&dwDisposition) != ERROR_SUCCESS) {
		RegCloseKey(hICQ);
		return;
	}

	// Now, find out where we're installed.
	if (GetModuleFileName(NULL, szSpeakFreelyPath, _MAX_PATH - 1) == 0) {
		goto Cleanup;
	}

	dwSize = _MAX_PATH - 1;

	if (RegQueryValueEx(hSpeakFreelyKey, "Path", NULL, NULL, szPreviousPath, &dwSize)
		!= ERROR_SUCCESS) {
		/* At this point, if the program fails to find the path value,
			we know that 1) ICQ is installed, 2) The Speak Freely
			settings are present, and 3) there is no setting for
			the executable path.  This is most likely because the
			user or another program told ICQ that Speak Freely is
			a different type of app than we're expecting.  This
			problem was reported by Hauke D. before Beta 8, but
			I didn't figure out a fix until the last minute.
			-BCW 05/09/1999
		*/
		szPreviousPath[0] = '\0';
	}

	if (!_stricmp(szSpeakFreelyPath, szPreviousPath)) {
		goto Cleanup;						// We're already set up from last time.
	}

	if (MessageBox(NULL, rstring(IDS_ICQ_CHANGE),
						rstring(IDS_ICQ_TITLE), MB_SYSTEMMODAL | MB_YESNO) == IDNO) {
		goto Cleanup;						// User doesn't want us to update ICQ settings.
	}

	SetICQData(hSpeakFreelyKey, szSpeakFreelyPath);

	RegCloseKey(hSpeakFreelyKey);			// We're done with the main settings

	// Now, create the Speak Freely key or open the existing key.
	if (RegCreateKeyEx(hICQ, "Owners", 0, NULL,
					REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSpeakFreelyKey,
					&dwDisposition) != ERROR_SUCCESS) {
		RegCloseKey(hICQ);
		return;
	}

	iKey = 0;								// Start at first key.

	dwSize = sizeof(szOwnerKey);

	while (RegEnumKeyEx(hSpeakFreelyKey, iKey++, szOwnerKey, &dwSize, NULL, NULL, NULL, &ftLastWritten) == ERROR_SUCCESS) {
		wsprintf(szOwnerKey, "%s\\Prefs\\Externals\\Speak Freely", szOwnerKey);
		RegDeleteKey(hSpeakFreelyKey, szOwnerKey);

		if (RegCreateKeyEx(hSpeakFreelyKey, szOwnerKey, 0, NULL,
							REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hOwnerKey,
							&dwDisposition) == ERROR_SUCCESS) {
			SetICQData(hOwnerKey, szSpeakFreelyPath);
			RegCloseKey(hOwnerKey);
		}

		dwSize = sizeof(szOwnerKey);
	} 

Cleanup:
	RegCloseKey(hSpeakFreelyKey);
	RegCloseKey(hICQ);
}

void SetICQData(HKEY hSpeakFreelyKey, char *szSpeakFreelyPath)
{
	char *regval;
	char szFormat[] = "[Host]\015\012Name=%h [%f %l]\015\012Network_address=%i\015\012" 
					  "PortNumber=2074\015\012[Debug]\015\012Debugging=0\015\012" 
					  "Loopback=0\015\012[Multicast]\015\012Scope=1\015\012" 
					  "[Encryption]\015\012Save_keys=0\015\012PGP_user_names=\015\012";
	DWORD dwVersion = 12;				// This is what the SpeakICQ patch had.

	// Now, we need to update the executable path.
	if (RegSetValueEx(hSpeakFreelyKey, "Path", 0, REG_SZ, szSpeakFreelyPath, strlen(szSpeakFreelyPath)) != ERROR_SUCCESS) {
		MessageBox(NULL, rstring(IDS_ICQ_ERROR), rstring(IDS_T_APP_TITLE_NORM), MB_ICONEXCLAMATION);
		return;
	}

	// Update the program URL
	regval = rstring(IDS_ICQ_URL);
	if (RegSetValueEx(hSpeakFreelyKey, "URL", 0, REG_SZ, regval, strlen(regval)) != ERROR_SUCCESS) {
		MessageBox(NULL, rstring(IDS_ICQ_ERROR), rstring(IDS_T_APP_TITLE_NORM), MB_ICONEXCLAMATION);
		return;
	}

	// Update the program extension
	regval = rstring(IDS_ICQ_EXTENSION);
	if (RegSetValueEx(hSpeakFreelyKey, "Extension", 0, REG_SZ, regval, strlen(regval) + 1) != ERROR_SUCCESS) {
		MessageBox(NULL, rstring(IDS_ICQ_ERROR), rstring(IDS_T_APP_TITLE_NORM), MB_ICONEXCLAMATION);
		return;
	}

	// Update the program format
	if (RegSetValueEx(hSpeakFreelyKey, "Format", 0, REG_SZ, szFormat, strlen(szFormat) + 1) != ERROR_SUCCESS) {
		MessageBox(NULL, rstring(IDS_ICQ_ERROR), rstring(IDS_T_APP_TITLE_NORM), MB_ICONEXCLAMATION);
		return;
	}

	// Update the program type
	if (RegSetValueEx(hSpeakFreelyKey, "Type", 0, REG_SZ, "File", 5) != ERROR_SUCCESS) {
		MessageBox(NULL, rstring(IDS_ICQ_ERROR), rstring(IDS_T_APP_TITLE_NORM), MB_ICONEXCLAMATION);
		return;
	}

	// Update the program version
	if (RegSetValueEx(hSpeakFreelyKey, "Version", 0, REG_DWORD, (LPBYTE) &dwVersion, sizeof dwVersion) != ERROR_SUCCESS) {
		MessageBox(NULL, rstring(IDS_ICQ_ERROR), rstring(IDS_T_APP_TITLE_NORM), MB_ICONEXCLAMATION);
	}
	return;
}