/*
				Speak Freely
				Main program

  This is the main module for Speak Freely, originally written by John
Walker, maintained since 1998 by Brian C. Wiles.

  All source code to Speak Freely is in the public domain.  This is in
accordance with the original license as specified by John Walker.

*/

#include "netfone.h"

static DWORD lastYieldTime = 0;

void MessageLoop(MSG *pmsg)
{
#ifdef TOOLBAR
  /* OK, I admit...THIS IS STUPID CODE!!!  Due to some funky inner workings of
     Monkeysoft Windoze, it appears that the main Speak Freely window does not
     receive WM_MOUSEMOVE and related messages.  However, I noticed that these
     messages do get passed to the message loop.  So, until I find a better
     (i.e. "supported") way, the message loop directly passes the message to
     the frame window message handler.  This leaves a very bad taste in my mouth.
     -BCW 04/30/1999
   */ 
  if((pmsg->message == WM_MOUSEMOVE) || (pmsg->message == WM_LBUTTONDOWN)
    || (pmsg->message == WM_LBUTTONUP))
    Frame_WndProc(pmsg->hwnd, pmsg->message, pmsg->wParam, pmsg->lParam);
#endif

   	if (!((hDlgPropeller != NULL && IsDialogMessage(hDlgPropeller, pmsg)) ||
   		(hDlgAnswer != NULL && IsDialogMessage(hDlgAnswer, pmsg)) ||
		(hDlgSpectral != NULL && IsDialogMessage(hDlgSpectral, pmsg)) ||
		(hDlgChat != NULL && IsDialogMessage(hDlgChat, pmsg)) ||
		(hwndToolBar != NULL && IsDialogMessage(hwndToolBar, pmsg)) ||
   		IsVoxMonitorMessage(pmsg)
   		)) {
        if (!TranslateMDISysAccel(hwndMDIClient, pmsg) &&
            !TranslateAccelerator(hwndMDIFrame, hAccel, pmsg)) {
            TranslateMessage(pmsg);
            DispatchMessage(pmsg);
        }
   }
}

void DefaultMessageLoop()
{
	MSG msg;
	
	if ((GetTickCount() - lastYieldTime) > 350) {
//OutputDebugString("DefaultMessageLoop\r\n");
		propeller(IDC_PH_MSGCHECK, ++messageChecks);
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			MessageLoop(&msg);
	  	}
    }
}

//	WINMAIN  --  Main application entry point

INT PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrev,
				   LPSTR pszCmdLine, INT nCmdShow)
{
    MSG msg;
    LPSTR cp;
    
    /* Check command line for another connection */

	hPrev = (HINSTANCE) FindWindow(SPEAK_FREE_FRAME_CLASS, NULL);
    if (hPrev) {
		HWND hwnd = FindWindow(SPEAK_FREE_FRAME_CLASS, NULL);
		
	    SendMessage(hwnd, WM_NEW_COMMANDLINE, 0, (LPARAM) pszCmdLine);
	    if (IsIconic(hwnd)) {
	    	PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
	    } else {
	    	SetFocus(hwnd);
	    }
		return 0;
	}
    
    //	Disable floating point error interrupts
    
/*{
 int i = _control87(0, 0);
 char s[80];
 wsprintf(s, "%0X", i);
 MessageBox(NULL, s, NULL, MB_OK);
}*/
//    _control87(_EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW,
//			   _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW);
    _control87(_EM_ZERODIVIDE | _EM_OVERFLOW | _EM_INVALID | _EM_DENORMAL |
								_EM_UNDERFLOW | _EM_INEXACT,
			   _MCW_EM);
//   _control87(/*_EM_ZERODIVIDE | _EM_OVERFLOW | _EM_INVALID | _EM_DENORMAL |
//								_EM_UNDERFLOW | */ _EM_INVALID | _EM_UNDERFLOW | _EM_INEXACT,
//			   _MCW_EM);
/*{
 int i = _control87(0, 0);
 char s[80];
 wsprintf(s, "%0X", i);
 MessageBox(NULL, s, NULL, MB_OK);
}*/
    
    //	Check for and process "start iconic" command line switch
    
    if ((cp = _fstrstr(pszCmdLine, "-S")) != NULL ||
    	(cp = _fstrstr(pszCmdLine, "/S")) != NULL ||
    	(cp = _fstrstr(pszCmdLine, "-s")) != NULL ||
    	(cp = _fstrstr(pszCmdLine, "/s")) != NULL) {
    	if ((cp == pszCmdLine || isspace(cp[-1])) &&
    		(cp[2] == 0 || isspace(cp[2]))) {
    		nCmdShow = SW_SHOWMINIMIZED;
    		_fmemcpy(cp, "  ", 2);
    	}
    } 
    
	//	Initialise application

    if (!InitApplication(hInstance)) {
        return FALSE;
    }
    
    //	Initialise instance

    if (!InitInstance(hInstance, pszCmdLine, nCmdShow)) {
        return FALSE;
    }

	/*	MDI message dispatching loop.  The business with
		PeekMessage conspires with the anti-lockup code so
		that we only set lastYieldtime when we start
		processing a set of messages from the queue. */

    while (GetMessage(&msg, NULL, 0, 0)) {
    	MessageLoop(&msg);
	  	/*	Note that there may be a tiny timing window here
	  		that I can't think of any way to slam.  If a message
	  		gets queued by interrupt code between here and the
	  		call on GetMessage, lastYieldTime will be reset
	  		without actually yielding to another application. */
	  	if (!waNetNoMsgLoopIns &&
	  			PeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_NOREMOVE) == 0) {
			lastYieldTime = GetTickCount();
		}
    }
    return msg.wParam;
}
