/*********************************************************************
  d4ex_win.c   (c)Copyright Sequiter Software Inc., 1990-1993.
  All rights reserved.

  This example program is a Windows application similar in operation to
  d4exampl.c

  *********************************************************************/

#include "d4all.h"
#include <windows.h>

#ifdef __TURBOC__
extern unsigned _stklen = 10000 ;
#endif


/*********** Structure Declarations **********************************/

typedef struct
{
#ifdef S4MEDIUM
  char *ptr ;
#else
  LPSTR  ptr ;
#endif
} D4PARSE_STR;

typedef struct
{
  HWND      hWnd ;
  HANDLE    hInst ;
  D4PARSE_STR  parse_str ;
  int          x,y ;
  TEXTMETRIC   tm ;
  LPMSG        lpmsg ;
  MSG          msg ;  /* Last Message */
  int          did_close ;
  int          did_quit ;
  HCURSOR      hSaveCursor ;
} D4DISPLAY;

FIELD4INFO field_info[] =
{
{ "TEST_FIELD",'C',20,0 },
{ 0,0,0,0 },
};


/*********** Function Prototype and Global Variable Declarations *****/

HCURSOR hHourGlass, hSaveCursor ;
D4DISPLAY display ;
extern MSG msg ;
extern TEXTMETRIC tm ;

int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int) ;
BOOL InitApplication(HANDLE) ;
BOOL InitInstance(HANDLE, int) ;
LRESULT CALLBACK MainWndProc(HWND, UINT, UINT, LONG) ;
extern void verify_switches() ;

void S4FUNCTION d4display_init( HWND ) ;
void S4FUNCTION d4parsestring_init( D4PARSE_STR *, LPSTR ) ;
void S4FUNCTION d4display_str( char *, int ) ;
int S4FUNCTION d4display_quit() ;


/*********** Windows initialization functions ************************/

BOOL InitApplication(HANDLE hInstance)
{
  WNDCLASS  wc;

  wc.style = (UINT) NULL;
  wc.lpfnWndProc = MainWndProc;

  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon( (HINSTANCE) NULL, IDI_APPLICATION);
  wc.hCursor = LoadCursor( (HINSTANCE) NULL, IDC_ARROW);
  wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  wc.lpszMenuName =  "TestMenu";
  wc.lpszClassName = "TestWClass";

  return (RegisterClass(&wc));
}


BOOL InitInstance( HANDLE hInstance, int nCmdShow)
{
  HWND   hWnd;

  hWnd = CreateWindow(
    "TestWClass",
    "Test CodeBase",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    (HWND) NULL,
    (HMENU) NULL,
    hInstance,
    NULL
    );

  if (!hWnd)
    return (FALSE);

  SetTimer( hWnd, hWnd, 1000, NULL ) ;

  d4display_init( hWnd ) ;
  display.hInst = hInstance ;     /* for t4filter.c */

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  return (TRUE);
}

LRESULT CALLBACK MainWndProc( HWND hWnd, UINT message, UINT wParam,
                             LONG lParam)
{
  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  case WM_CLOSE:
    display.did_close =  1 ;
    return (DefWindowProc(hWnd, message, wParam, lParam));

  default:
    return (DefWindowProc(hWnd, message, wParam, lParam));
  }
  return (long) NULL;
}

/************ display text in Windows functions ***********************/

void S4FUNCTION d4parsestring_init( D4PARSE_STR *p_str, LPSTR p )
{
  memset( p_str, 0, sizeof(D4PARSE_STR) ) ;

#ifdef S4MEDIUM
  lstrcpy( pointer, p ) ;
  p_str->ptr = pointer ;
#else
  p_str->ptr =  p ;
#endif
}

void S4FUNCTION d4display_init( HWND h )
{
  HDC hdc ;
  TEXTMETRIC tm ;

  memset( &display, 0, sizeof(D4DISPLAY) ) ;
  display.hWnd =  h ;
  display.lpmsg = &(display.msg) ;
  hdc =  GetDC(display.hWnd) ;
  GetTextMetrics( hdc, &tm ) ;
  display.tm = tm ;
  ReleaseDC(display.hWnd,hdc) ;
  display.x =  0 ;
  display.y =  0 ;
  display.did_close =  0 ;
  display.did_quit  =  0 ;
}

void  S4FUNCTION d4display_str( char *str, int is_new_line )
{                               
  RECT rect ;
  HDC hdc ;
  SIZE size;
  int len, height, width ;
  char blank_line[180] ;

  memset(blank_line, 32, 179) ;
  blank_line[179] = '\0' ;

  hdc =  GetDC(display.hWnd) ;
  len =   strlen(str) ;

  GetTextExtentPoint( hdc, str, len, &size ) ;

  height =  size.cy ;
  width  =  size.cx ;

  if ( is_new_line )
  {
    display.x  =  0 ;
    display.y +=  height +  display.tm.tmExternalLeading ;
  }

  GetClientRect( display.hWnd, &rect ) ;

  if ( (display.y+height) > rect.bottom )
  {
    display.y =  0 ;
    InvalidateRect( display.hWnd, &rect, 1 ) ;
  }

  TextOut( hdc, display.x,display.y, str, len ) ;

  if ( (display.y+(2*height)) > rect.bottom )
    TextOut( hdc, 0, 0, blank_line, strlen(blank_line) ) ;
  else   
    TextOut( hdc, 0, (display.y+height+display.tm.tmExternalLeading), blank_line, strlen(blank_line) ) ;

  display.x +=  width ;

  ReleaseDC(display.hWnd,hdc) ;
}

int S4FUNCTION d4display_quit( )
{
  /* If there is a message, the message is processed. */
  /* If the message says quit, then TRUE is returned. */
  if ( display.did_quit ) return 1 ;

  for (;;)
  {
    if ( ! display.did_close )
      if ( ! PeekMessage( display.lpmsg, display.hWnd, 0, 0, PM_NOREMOVE ) )
        return 0 ;

    if ( ! GetMessage( display.lpmsg, display.hWnd, 0, 0 ) )
    {
      MessageBox( display.hWnd, "", "Program Completed", MB_OK ) ;
      display.did_quit =  1 ;
      return 1 ;
    }

    TranslateMessage(display.lpmsg);
    DispatchMessage(display.lpmsg);
  }
}

/*********************************************************************/


int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
                   int nCmdShow)
{
  int rc ;
  CODE4 cb ;

  if (!hPrevInstance)
    if (!InitApplication(hInstance)){
      MessageBox(0,"","InitApplication Failed", MB_OK); 
      return (FALSE);
    }

  if (!InitInstance(hInstance, nCmdShow)){
    MessageBox(0, "", "InitInstance Failed", MB_OK); 
    return (FALSE);
  }
  d4parsestring_init( &display.parse_str, lpCmdLine ) ;

  d4init( &cb ) ;
  cb.hWnd = display.hWnd ;
#ifdef S4DLL
  cb.hInst = display.hInst ;
#endif

  verify_switches() ;
  d4display_str( "\nSwitches Verified Successfully!", 1 ) ;

  cb.auto_open = 0 ;
  cb.open_error = 0 ;
  if( d4open( &cb, "TEST.DBF" ) != 0 )
    d4display_str( "\nTEST.DBF Opened", 1 ) ;
  else
  {
    if( d4create(&cb,"TEST.DBF",field_info,0) != 0 )
      d4display_str( "\nTEST.DBF Created", 1) ;
  }
  d4close_all( &cb ) ;

  PostQuitMessage(0) ;

  for (;;)
  {
    if (d4display_quit() )
      return (display.msg.wParam) ;
  }
}

void verify_switches()
{
  long d4switch ;

  d4switch = u4switch() ;

  d4display_str( " ", 1 ) ;
  d4display_str( " ", 1 ) ;
  d4display_str( "Library Conditional Compilation Switches:", 1 ) ;
  if( d4switch & 1 )
    d4display_str( "S4FOX - FoxPro Index File Compatibility", 1 ) ;
  if( d4switch & 2 )
    d4display_str( "S4CLIPPER - Clipper Index File Compatibility", 1 ) ;
  if( d4switch & 4 )
    d4display_str( "S4MDX - dBASE IV Index File Compatibility", 1 ) ;
  if( d4switch & 8 )
    d4display_str( "S4NDX - dBASE III or III PLUS Index File Compatibility", 1 ) ;
  if( d4switch & 0x10 )
    d4display_str( "S4DLL - Microsoft Windows DLL (S4DLL_BUILD on Library Build)", 1 ) ;
#ifdef S4DLL
  if( d4switch & 0x20 )
    d4display_str( "S4DLL - Microsoft Windows Dynamic with DLL", 1 ) ;
#else
  if( d4switch & 0x20 )
    d4display_str( "S4WINDOWS - Microsoft Windows Static with Static Library", 1 ) ;
#endif
  if( d4switch & 0x40 )
    d4display_str( "S4OS2 - OS/2", 1 ) ;
  if( d4switch & 0x40 )
    d4display_str( "S4CODE_SCREENS - CodeScreens output Functions", 1 ) ;
  if( d4switch & 0x100 ) 
    d4display_str( "S4DEBUG - Extensive CodeBase Error Checking", 1 ) ;
  if( d4switch & 0x200 )
    d4display_str( "S4ERROR_HOOK - Custom Error Function", 1 ) ;
  if( d4switch & 0x400 )
    d4display_str( "\nS4LOCK_CHECK - Internal CodeBase Locking Diagnostics", 1 ) ;
  if( d4switch & 0x800 )
    d4display_str( "\nS4LOCK_HOOK - Custom Lock Failure Function", 1 ) ;
  if( d4switch & 0x1000 )
    d4display_str( "\nS4MAX - Maximum Memory Allocation Testing", 1 ) ;
  if( d4switch & 0x2000 )
    d4display_str( "\nS4MEMO_OFF - Memo File support source code removed", 1 ) ;
  if( d4switch & 0x4000 )
    d4display_str( "\nS4OLD_CODE - Support Functions from CodeBase 4.5", 1 ) ;
  if( d4switch & 0x8000 )
    d4display_str( "\nS4OPTIMIZE_OFF - Memory Optimization source code removed", 1 ) ;
  if( d4switch & 0x10000 )
    d4display_str( "\nS4PORTABLE - Maximum Portability", 1 ) ;
  if( d4switch & 0x20000 )
    d4display_str( "\nS4SAFE  - Immediate File Length Updates", 1 ) ;
  if( d4switch & 0x40000 )
    d4display_str( "\nS4SINGLE  - Multi-user support source code removed", 1 ) ;

#ifdef S4OPTIMIZE_OFF
  if( (d4switch & 0x8000)  ==  0 )
    e4severe( e4result, "S4OPTIMIZE_OFF must be used in Library Build too." ) ;
#else
  if( d4switch & 0x8000  )
    e4severe( e4result, "S4OPTIMIZE_OFF must be off in Library Build too." ) ;
#endif

#ifdef S4FOX
  if( (d4switch & 1)  == 0 )
    e4severe( e4result, "S4FOX must be used in Library Build too." ) ;
#endif

#ifdef S4CLIPPER
  if( (d4switch & 2)  == 0 )
    e4severe( e4result, "S4CLIPPER must be used in Library Build too." ) ;
#endif

#ifdef S4MDX
  if( (d4switch & 4)  == 0 )
    e4severe( e4result, "S4MDX must be used in Library Build too." ) ;
#endif

#ifdef S4NDX
  if( (d4switch & 8)  == 0 )
    e4severe( e4result, "S4NDX must be used in Library Build too." ) ;
#endif
}