/*

				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;

    // Display the Splash Screen
    hSplash = CreateDialog (hInst, MAKEINTRESOURCE(IDD_SPLASH), NULL, Splash_DlgProc);

    //  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;
    }

    SetDlgItemText(hSplash, IDC_LOADSTATUS, rstring(IDS_SPLASH_ICQ));

    SetupICQ();				// This is to tell ICQ where the SF program is.

    SetDlgItemText(hSplash, IDC_LOADSTATUS, rstring(IDS_SPLASH_LOADING));

#ifdef TOOLBAR
    InitCommonControls(); // For the toolbar.
#endif
    hwndToolBar = NULL;

    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 (_fstrlen(pszCmdLine) > 0) {
		commandLine = (LPSTR) GlobalAllocPtr(GPTR, _fstrlen(pszCmdLine) + 1);
		if (commandLine != NULL) {
			_fstrcpy(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);
    SetForegroundWindow(hSplash); // Make the splash window on top of the MDI window.
    UpdateWindow(hSplash);

    Sleep(2000);            // Delay so user has a chance to see the logo.
    DestroyWindow(hSplash); // Closing the splash window now makes it look smoother.
    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[300], szPreviousPath[300];
  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, 299) == 0)
    goto Cleanup;

  dwSize = 299;

  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.

  DefaultMessageLoop(); // Allow the splash window to repaint.

  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);
    goto Cleanup;
  }

  // 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);
    goto Cleanup;
  }

  // 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);
    goto Cleanup;
  }

  // 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);
    goto Cleanup;
  }

  // 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);
    goto Cleanup;
  }

  // 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);
    goto Cleanup;
  }

Cleanup:
  return;
}