/*==========================================================================
 *
 *  Copyright (C) 1994-1995 Microsoft Corporation.  All Rights Reserved.
 *
 *  File:       dpf.c
 *  Content:    debugging printf
 *@@BEGIN_MSINTERNAL
 *  History:
 *   Date       By      Reason
 *   ====       ==      ======
 *   06-jan-95  craige  initial implementation
 *   03-mar-95  craige  added dprintf2
 *   31-mar-95  craige  add DPFInit to read WIN.INI for [DirectDraw] section;
 *                      added dprintf3
 *   01-apr-95  craige  happy fun joy updated header file
 *   06-apr-95  craige  made stand-alone
 *   18-jun-95  craige  use negative dpf level to display ONLY that level
 *   06-dec-95  jeffno  Changed dprintf to use c-standard variable argument
 *                      list techniques. Also added abs for NT
 *   06-feb-96  colinmc added simple assertion mechanism for DirectDraw
 *   15-apr-96  kipo    added msinternal
 *       20-may-96      andyco  forced ansi entry points on all functions
 *@@END_MSINTERNAL
 *
 ***************************************************************************/
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "dpf.h"
#include <stdarg.h>


#ifdef DEBUG

#define USE_DDASSERT

#ifndef START_STR
    #define START_STR   "DDRAW: "
#endif
#ifndef PROF_SECT
    #define PROF_SECT   "DirectDraw"
#endif

#define END_STR         "\r\n"

HWND            hWndListBox;
LONG            lDebugLevel = 0;

/*
 * dumpStr
 */
static void dumpStr( LPSTR str )
{
    OutputDebugStringA( str );

    #ifdef DPF_HWND
        if( hWndListBox != NULL )
        {
            if( !IsWindow( hWndListBox ) )
            {
                hWndListBox = NULL;
            }
        }
        if( hWndListBox != NULL )
        {
            UINT        sel;
            int len;
            len = strlen( str );
            if( len > 0 )
            {
                if( str[len-1] == '\r' || str[len-1] == '\n' )
                {
                    str[len-1] = 0;
                }
                if( len > 1 )
                {
                    if( str[len-2] == '\r' || str[len-2] == '\n' )
                    {
                        str[len-2] = 0;
                    }
                }
            }
            SendMessage( hWndListBox, LB_ADDSTRING, 0, (LONG) (LPSTR) str );
            sel = (UINT) SendMessage( hWndListBox, LB_GETCOUNT, 0, 0L );
            if( sel != LB_ERR )
            {
                SendMessage( hWndListBox, LB_SETCURSEL, sel-1, 0L );
            }
        }
    #endif

} /* dumpStr */

/*
 * dprintf
 */
void cdecl dprintf( UINT lvl, LPSTR szFormat, ...)
{
    char        str[256];
    BOOL        allow = FALSE;
    va_list ap;
    va_start(ap,szFormat);


    if( lDebugLevel < 0 )
    {
#ifndef WIN95
        if( (UINT) abs( lDebugLevel ) == lvl )
#else
        if( (UINT) labs( lDebugLevel ) == lvl )
#endif
        {
            allow = TRUE;
        }
    }
    else if( (UINT) lDebugLevel >= lvl )
    {
        allow = TRUE;
    }

    if( allow )
    {
        wsprintfA( (LPSTR) str, START_STR );
        wvsprintfA( str+lstrlenA( str ), szFormat, ap);   //(LPVOID)(&szFormat+1) );

        lstrcatA( (LPSTR) str, END_STR );
        dumpStr( str );
    }

    va_end(ap);
} /* dprintf */

/*
 * DPFInit
 */
void DPFInit( void )
{
    lDebugLevel = GetProfileIntA( PROF_SECT, "debug", 0 );

} /* DPFInit */

#ifdef USE_DDASSERT

/*
 * NOTE: I don't want to get into error checking for buffer overflows when
 * trying to issue an assertion failure message. So instead I just allocate
 * a buffer that is "bug enough" (I know, I know...)
 */
#define ASSERT_BUFFER_SIZE   512
#define ASSERT_BANNER_STRING "************************************************************"
#define ASSERT_BREAK_SECTION "BreakOnAssert"
#define ASSERT_BREAK_DEFAULT FALSE
#define ASSERT_MESSAGE_LEVEL 0

void _DDAssert( LPCSTR szFile, int nLine, LPCSTR szCondition )
{
    char buffer[ASSERT_BUFFER_SIZE];

    /*
     * Build the debug stream message.
     */
    wsprintfA( buffer, "ASSERTION FAILED! File %s Line %d: %s", szFile, nLine, szCondition );

    /*
     * Actually issue the message. These messages are considered error level
     * so they all go out at error level priority.
     */
    dprintf( ASSERT_MESSAGE_LEVEL, ASSERT_BANNER_STRING );
    dprintf( ASSERT_MESSAGE_LEVEL, buffer );
    dprintf( ASSERT_MESSAGE_LEVEL, ASSERT_BANNER_STRING );

    /*
     * Should we drop into the debugger?
     */
    if( GetProfileIntA( PROF_SECT, ASSERT_BREAK_SECTION, ASSERT_BREAK_DEFAULT ) )
    {
        /*
         * Into the debugger we go...
         */
        DEBUG_BREAK();
    }
}

#endif /* USE_DDASSERT */

#endif
