/*===========================================================================
 *
 * DF3DDebugDialog.CPP - Dave Humphrey (uesp@m0use.net), 10 November 2000
 *
 *=========================================================================*/

	/* Includes */
#include "stdafx.h"
#include "DF3DDebugDialog.H"
#include "Resource.h"
#include "command.h"


	/* To ensure only one debug dialog at a time */
static HWND hLastDebugDialog = NULL;

	/* Allows us to unhook temporarily at any time */
static boolean HookLog = TRUE;

	/* For setting up the keyboard hook */
static HHOOK hKeyboardHook = NULL;

	/* For use in the keyboard hook */
static boolean IsActivated = FALSE;

	/* Handle to the current debug window */
static HWND hDialogHandle = NULL;


#undef  __FUNC__
#define __FUNC__ "DF3DDebugProcessCommand()"
/*===========================================================================
 *
 * Function - boolean DF3DDebugProcessCommand (void);
 *
 * Processes the current command in the input text area.
 *
 *=========================================================================*/
boolean DF3DDebugProcessCommand (void) {
  cmd_parameter_t CMDParameters;
  char            Buffer[256];
  char		  OutputBuffer[512];
  boolean	  Result;
  char*		  pParse;
  int		  LoopCounter;
  int		  OutputSize;

	/* Get and clear input textbox */
  SendDlgItemMessage(hDialogHandle, IDC_DEBUG_INPUTTEXT, WM_GETTEXT, (WPARAM) 255, (LPARAM) &Buffer[0]);
  SendDlgItemMessage(hDialogHandle, IDC_DEBUG_INPUTTEXT, WM_SETTEXT, 0, 0);

  pParse = trim(Buffer);

	/* Ensure a non-empty command string */
  if (*pParse != NULL_CHAR) {

		/* Add the command to the history list */
    SendDlgItemMessage(hDialogHandle, IDC_DEBUG_INPUTTEXT, CB_INSERTSTRING, 0, (LPARAM) (LPCTSTR) pParse);

		/* Run the command */
    Result = CommandHandler.ParseCommand(Buffer, CMDParameters);

		/* Output the results on success */
    //if (Result) {
      OutputSize = sprintf (OutputBuffer, "%s(", strupr(Buffer));

      for (LoopCounter = 0; LoopCounter < CMDParameters.NumParameters; LoopCounter++) {
        OutputSize += sprintf (OutputBuffer + OutputSize, "%s", CMDParameters.pParameters[LoopCounter]);

	if (LoopCounter != CMDParameters.NumParameters - 1) {
	  strcat (OutputBuffer, ", ");
	  OutputSize += 2;
	 }
       }
      
      DF3DDebugPrintf("%s) returned: \"%s\"", OutputBuffer, CMDParameters.pReturnValue);
      if (CMDParameters.AllocateReturn) DestroyPointer(CMDParameters.pReturnValue);
     //}
   }

  return (TRUE);
 }
/*===========================================================================
 *		End of Function DF3DDebugProcessCommand()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "DF3DDebugKeyboardHook()"
/*===========================================================================
 *
 * Function - LRESULT DF3DDebugKeyboardHook (Code, wParam, lParam);
 *
 * Custom keyboard hook procedure for dealing with the DF3D debug dialog.
 * Only installed when the debug window is opened and only parses key
 * events when the dialog is activated.
 *
 *=========================================================================*/
LRESULT __stdcall DF3DDebugKeyboardHook (int Code, WPARAM wParam, LPARAM lParam) {  
  
	/* Handle dialog key events */
  if (IsActivated) {

		/* Enter up code execute command */
    if (wParam == 13 && (KF_UP & HIWORD(lParam)) != 0) {
      DF3DDebugProcessCommand();
     }

    //SystemLog.Printf ("Message 0x%04X: wParam = %d, %d, lParam = %ld (%ld)", Code, LOWORD(wParam), HIWORD(wParam), lParam, KF_UP);
   }

	/* Call the next keyboard hook */  
  return CallNextHookEx(hKeyboardHook, Code, wParam, lParam);
 }
/*===========================================================================
 *		End of Function DF3DDebugKeyboardHook()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "D3DDebugAddLine()"
/*===========================================================================
 *
 * Function - void DF3DDebugAddLine (pString);
 *
 * Adds a line of text to the console in the same format as printf() functions.
 *
 *=========================================================================*/
void DF3DDebugAddLine (const char* pString) {
  int Result;

	/* Ignore any invalid input */
  if (pString == NULL) pString = "DF3DDebugAddLine() - NULL input string received!";

  Result = SendDlgItemMessage (hLastDebugDialog, IDC_DEBUG_OUTPUTTEXT, WM_GETTEXTLENGTH, 0, 0);
  Result = SendDlgItemMessage (hLastDebugDialog, IDC_DEBUG_OUTPUTTEXT, EM_SETSEL, (WPARAM) (int) Result, (LPARAM) (int) Result);
  Result = SendDlgItemMessage (hLastDebugDialog, IDC_DEBUG_OUTPUTTEXT, EM_REPLACESEL, (WPARAM) (BOOL) FALSE, (LPARAM) (LPCTSTR) pString);
 }
/*===========================================================================
 *		End of Function DF3DDebugAddLine()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "D3DDebugPrintf()"
/*===========================================================================
 *
 * Function - void DF3DDebugPrintf (pString, ...);
 * 
 * Outputs text to the console in the same format as printf() functions.
 *
 *=========================================================================*/
void DF3DDebugPrintf (const char* pString, ...) {
  va_list Args;
  char    Buffer[1025];

  va_start(Args, pString);
  vsprintf (Buffer, pString, Args);
  va_end(Args);

  strcat (Buffer, "\r\n");
  DF3DDebugAddLine(Buffer);
 }
/*===========================================================================
 *		End of Function DF3DDebugPrintf()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "DF3DDebugDialogProc()"
/*===========================================================================
 *
 * Function - BOOL DF3DDebugDialogProc (hWindow, Message, wParam, lParam);
 *
 *=========================================================================*/
BOOL FAR PASCAL DF3DDebugDialogProc (HWND hWindow, UINT Message, WPARAM wParam, LPARAM lParam) {
  int   KeyCode;

  
  switch (Message) {

		/* Handle activation type messages */
    case WM_ACTIVATE: {
      int Active = LOWORD(wParam);           

      if (Active == WA_INACTIVE) 
        IsActivated = FALSE;
      else
        IsActivated = TRUE;

      return (TRUE); }

		/* Remove the keyboard hook procedure */
    case WM_DESTROY:
      UnhookWindowsHookEx(hKeyboardHook);
      hLastDebugDialog = NULL;
      return (TRUE);

		/* Process keystrokes */
    case WM_KEYDOWN:
      KeyCode = (TCHAR) wParam;
      DF3DDebugPrintf("WM_KEYDOWN: VK = %d", KeyCode);
      break;
    case WM_KEYUP:
      KeyCode = (int) wParam;
      DF3DDebugPrintf("WM_KEYUP: VK = %d", KeyCode);
      if (KeyCode == 13) DF3DDebugProcessCommand();
      return (TRUE);

		/* Initialize the dialog */
    case WM_INITDIALOG:
      DF3DDebugDialogInit(hWindow);
      return TRUE;

		/* Command messages */
    case WM_COMMAND:

      switch (LOWORD(wParam)) {

       		/* Close the window */
        case IDCANCEL:
	  SystemLog.SetHookProc();
	  hLastDebugDialog = NULL;
	  DestroyWindow(hWindow);
	  return (TRUE);
        case IDOK:
          DF3DDebugProcessCommand();
	  return (TRUE);
       }
      
     break;
    }

  return (FALSE);
 }
/*===========================================================================
 *		End of Function DF3DDebugDialogProc()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "DF3DDebugDialogInit()"
/*===========================================================================
 *
 * Function - void DF3DDebugDialogInit (HWND hWindow);
 *
 *=========================================================================*/
void DF3DDebugDialogInit (HWND hWindow) { 

	/* Setup the logfile hook proc */
  SystemLog.SetHookProc(DF3DDebugHookProc);
  IsActivated = TRUE;
  hDialogHandle = hWindow;

	/* Setup the keyboard hook */
  hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, &DF3DDebugKeyboardHook,  NULL, GetCurrentThreadId());

	/* Clear the output textbox */
  //SendDlgItemMessage(hWindow, IDC_DEBUG_OUTPUTTEXT, LB_RESETCONTENT, 0, 0);
  //Result = SendDlgItemMessage (hLastDebugDialog, IDC_DEBUG_OUTPUTTEXT, WM_GETTEXTLENGTH, 0, 0);
  //Result = SendDlgItemMessage (hLastDebugDialog, IDC_DEBUG_OUTPUTTEXT, EM_SETSEL, (WPARAM) (int) Result, (LPARAM) (int) Result);
  //Result = SendDlgItemMessage (hLastDebugDialog, IDC_DEBUG_OUTPUTTEXT, EM_REPLACESEL, (WPARAM) (BOOL) FALSE, (LPARAM) (LPCTSTR) Buffer);
 }
/*===========================================================================
 *		End of Function DF3DDebugDialogInit()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "DisplayDF3DDebugDialog()"
/*===========================================================================
 *
 * Function - HWND DisplayDF3DDebugDialog (hWindow, hInstance);
 *
 *=========================================================================*/
HWND DisplayDF3DDebugDialog (HWND hWindow, HINSTANCE hInstance) {
  HWND Result;

	/* Ensure only one dialog is visible at a time */
  if (hLastDebugDialog != NULL) {
    ShowWindow(hLastDebugDialog, SW_SHOW);
    return (hLastDebugDialog);
   }

	/* Display the modeless dialog box */
  Result = CreateDialog(hInstance, "DF3D_DEBUG_DIALOG", hWindow,
			(DLGPROC) DF3DDebugDialogProc);

	/* Show the window on success */
  if (Result) {
    ShowWindow(Result, SW_SHOW);
    hLastDebugDialog = Result;
   }

  return (Result);
 }
/*===========================================================================
 *		End of Function DisplayDF3DDebugDialog()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "DF3DDebugHookProc()"
/*===========================================================================
 *
 * Function - void DF3DDebugHookProc (pString, Args);
 *
 * Hook procedure for the system log file.
 *
 *=========================================================================*/
void DF3DDebugHookProc (const char* pString, va_list Args) {
  char Buffer[1024] = "Log: ";

	/* Ensure a valid debug window handle */
  if (hLastDebugDialog == NULL || !HookLog) return;

	/* Create debug string */
  vsprintf (Buffer + 5, pString, Args);
  strcat(Buffer, "\r\n");

	/* Add string to textbox */
  DF3DDebugAddLine(Buffer);
 }
/*===========================================================================
 *		End of Function DF3DDebugHookProc()
 *=========================================================================*/