/*****************************************************************************/
/*                                                                           */
/*   VECTREX HP3000 Software Emulator              Copyright K.Wilkins 1996  */
/*                                                                           */
/*****************************************************************************/
/*                                                                           */
/*   Title      : Vectrex emulator debugging functions                       */
/*                                                                           */
/*   File Name  : VDEBUG.C   (name change)                                   */
/*                                                                           */
/*   Author     : Keith Wilkins                                              */
/*                                                                           */
/*   Version    : 1.00                                                       */
/*                                                                           */
/*   Desciption : This file contains the functions for the Vectrex debugging */
/*                functions                                                  */
/*                                                                           */
/*   Functions  : fDebugInit()          - Debug initialisation               */
/*                fDebug()              - Debug message printing             */
/*                fDebugMonitorToggle() - Toggle the monitor ON/OFF          */
/*                fDebugMonitor()       - The runtime debugger               */
/*                                                                           */
/*****************************************************************************/
/*                                                                           */
/*   Revision History:                                                       */
/*                                                                           */
/*   Version    Date    Who  Description of changes                          */
/*   -------    ----    ---  ----------------------                          */
/*                                                                           */
/*    0.01    15/03/93  K.W  Creation of empty file and descriptions         */
/*    1.00    05/08/96  K.W  Public release of DVE V1.0                      */
/*                                                                           */
/*****************************************************************************/

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <malloc.h>
# include <time.h>

#include <standard.h>
#include <tools.h>

#include "io.h"
#include "keyboard.h"
#include "vectrex.h"
#include "verror.h"
#include "vdebug.h"


#define VARG_BUFF_SIZE  500
T_INT DebugWinId;

/* Define local function prototypes */
// Define window size/position array for debug & monitor windows
// sizes MUST be correct for fixed font, otherwise garbage may appear!
WININFO asDbgWin[RESOLUTION_COUNT]=
{
// Xpos Ypos Xsiz Ysiz
     5,   5, 592, 6*8,
     5,   5, 592, 10*8,
     5,   5, 592, 12*8,
     5,   5, 592, 24*8,
     5,   5, 592, 34*8,
     5,   5, 176,  5*8,
};

T_INT debug_destructor(PARAMETER *parameter);

/*****************************************************************************/
/*                                                                           */
/*   Function    : fDebugInit()                                              */
/*                                                                           */
/*   Author      : K.W                                                       */
/*                                                                           */
/*   Description : This function initialises the debug functionality by      */
/*                 registering the debug KEYS to toggle the debug window     */
/*                 and Monitor window ON/OFF.                                */
/*                                                                           */
/*   Accepts     : nothing                                                   */
/*                                                                           */
/*   Returns     : T_INT                                                     */
/*                                                                           */
/*****************************************************************************/

T_INT fDebugInit(T_VOID)
{
 time_t dtime;
 static T_CHAR text[300];
 if (bGblDebugEnable==T_TRUE)
 {
  if (open_debug_window()==T_FALSE)
  {
   return (bGblDebugEnable=T_FALSE);
  }
  if (bGblGUIEnable==T_FALSE)
  {
   hide_all_windows();
   back_save(FORCED_SAVE);
   show_all_windows();
  }
  bGblGUIEnable=T_TRUE;
  dtime=time(NULL);
  sprintf(text,"%s %s","fDebugToggle(): Debug switched ON", ctime(&dtime));
  strtok(text,"\n\0");
  edit_log_add(get_window(DebugWinId),text);
 }
 return(T_TRUE);
}

/* Local Functions to toggle ON/OFF functions */

/*****************************************************************************/
/*                                                                           */
/*   Function    : fDebug()                                                  */
/*                                                                           */
/*   Author      : K.W                                                       */
/*                                                                           */
/*   Description : This prints a message to the screen and to the debug file */
/*                 if open. Printing or file output is only done if the      */
/*                 tLevel >= tGblDebugLevel. All screen output is done via   */
/*                 the functions in io.c fOutText().                         */
/*                                                                           */
/*   Accepts     : BYTE tLevel, char *Text with formatting                   */
/*                                                                           */
/*   Returns     : Nothing                                                   */
/*                                                                           */
/*****************************************************************************/

T_SWORD fDebugXX(T_PUCHAR pcDebugString,...)
{
 static FILE  *pfDebugErrorFile=NULL;
 static FILE  *pfDebugFile=NULL;
 static T_UCHAR acTextBuffer[VARG_BUFF_SIZE];
 va_list tGlop;

 /* Expand the varable argument list into the text buffer */
 /* Initialise the variable array */
 va_start(tGlop,pcDebugString);

 if (vsprintf(acTextBuffer,pcDebugString,tGlop)==-1)
 {
  fFatal("fDebugXX - Vararg Buffer Overflow");
  fKBDgetch();
 }
 va_end(tGlop);

 /* Test the tLevel */
 if (tGblDebugMsgLevel==VERROR)
 {
  /* If the error file isnt open then open it */
  if (pfDebugErrorFile==NULL)
  {
   if ((pfDebugErrorFile=fopen("vectrex.err","w"))==NULL)
   {
    fFatal("fDebugXX() - Couldn't open error log file <vectrex.err>");
    return(0);
   }
  }
  fprintf(pfDebugErrorFile,"%s\n",acTextBuffer);
 }

 /* Now print to the window only if its been enabled, we dont need to */
 /* check the window handle but we will just in case                  */
 if ((bGblDebugEnable==T_TRUE) && (tGblDebugMsgLevel>=tGblDebugLevel))
 {
  if (window_exist(DebugWinId)==T_TRUE)
  {
   WINDOW_LISTEN_ELEMENT *DebugWin=get_window(DebugWinId);
   edit_log_add(DebugWin,acTextBuffer);
  }
  /* Output debug to file only if enabled */
  if (bGblDebugFileEnable==T_TRUE)
  {
   if (pfDebugFile==NULL)
   {
    if ((pfDebugFile=fopen("vectrex.dbg","w"))==NULL)
    {
     fFatal("fDebugXX() - Couldnt open debug log file <vectrex.dbg>");
     return(0);
    }
   }
   fprintf(pfDebugFile,"<%010ld> %s\n",lwGblSystemTickTotal,acTextBuffer);
  }
 }
 return(0);
}

T_INT open_debug_window(T_VOID)
{
 WINDOW_LISTEN_ELEMENT *DebugWin;
 OPEN_WIN w;
 w.x_pos=asDbgWin[wGblDisplayMode].iWinXpos;
 w.y_pos=asDbgWin[wGblDisplayMode].iWinYpos;
 w.breite=asDbgWin[wGblDisplayMode].iWinXsize;
 w.hoehe=asDbgWin[wGblDisplayMode].iWinYsize;
 w.border=2;
 w.color=ddark_grau;
 w.bcolor=dhell_grau;
 w.art=RAW_WINDOW|WITH_CLOSE_BUTTON|WITH_HIDE_BUTTON|WITH_DRAG_BUTTON|VIRTUAL_FRONT_WINDOW|REMEMBER|EDIT_TRUE;
 w.id=WIN_OPEN_CHOOSES_ID;
 w.variablen=NULL;
 w.mem_bild=NULL;
 w.pcx_bild=NULL;
 w.name="Debug Window for DVE";
 w.destructor=debug_destructor;
 w.area_funktion=execute_activate;
 w.tasten_funktion=NULL;
 MOUSE_VERSTECKE
 DebugWin=open_window(&w);
 if (DebugWin==NULL)
 {
  show_message("Debug Window opening error!");
  MOUSE_ZEIGE
  return T_FALSE;
 }
 DebugWinId=DebugWin->id;
 print_srect(DebugWin,PRINT_WIN_RAW,0,0,DebugWin->b,DebugWin->h,ddark_grau,weiss,2);
 // this makes the window a LOG window, which logs all to debug.tmp
 edit(DebugWin,"debug.tmp",EDIT_LOG);
 MOUSE_ZEIGE
 return T_TRUE;
}

T_VOID close_debug_window(T_VOID)
{
 WINDOW_LISTEN_ELEMENT *DebugWin=get_window(DebugWinId);
 if (DebugWin!=NULL)
 {
  DebugWin->parameter=NULL; // might not be zero, but must forced, since it
                            // is a none returning destructor using window
  close_window(DebugWin,CLOSE_DEFAULT);
 }
}

T_INT debug_destructor(PARAMETER *parameter)
{
 WINDOW_LISTEN_ELEMENT *window=(WINDOW_LISTEN_ELEMENT *)parameter->window_element;
 T_DEBUG_ENTRY("debug_destructor",75)
 if (parameter==NULL)
 {
  show_message("No Parameter in DESTRUCTOR()");
  T_DEBUG_FUNCTION_POSITION(1)
  T_DEBUG_LEAVE
  return -1;
 }
 if (window==NULL)
 {
  show_message("I can't find myself!!! (Window not closed)");
  T_DEBUG_FUNCTION_POSITION(2)
  T_DEBUG_LEAVE
  return -1;
 }
 else
 {
// interesting part of destructor (just a notifier in this case
  bGblDebugEnable=T_FALSE; // same as in debug toggle :-)
//  set_functions();
//  reset_state=T_FALSE;
//  wGblQuitFlag=EMU_RESTART;
 }
 window->destructor=NULL; // the rest is done by close_window
 window->parameter=NULL;
 T_DEBUG_LEAVE
 return -1; // keine variablen da, dann ebene = -1
}
