////////////////////////////////////////////////////////////////////////////////
// Debug.h
//
//  Debugging and error handling code.

#ifndef __DEBUG_H__
#define __DEBUG_H__

void DisplayError(LPCTSTR szFile, int nLine, LPCTSTR lpMessage);
void DisplayError(LPCTSTR szFile, int nLine, HRESULT hResult, LPCTSTR lpMessage);
void Trace(LPCTSTR lpFormat, ...);

#define DISPLAYERRORCODE(h, s)\
    DisplayError(__FILE__, __LINE__, h, _T(s))
#define DISPLAYERROR(s)\
    DisplayError(__FILE__, __LINE__, _T(s))
#define DISPLAYLASTERROR(s)\
    DisplayError(__FILE__, __LINE__, GetLastError(), _T(s))

#ifdef _DEBUG

#define TRACE                   ::Trace
#define TRACE0(sz)              ::Trace(_T("%s"), _T(sz))
#define TRACE1(sz, p1)          ::Trace(_T(sz), p1)
#define TRACE2(sz, p1, p2)      ::Trace(_T(sz), p1, p2)
#define TRACE3(sz, p1, p2, p3)  ::Trace(_T(sz), p1, p2, p3)

#define DEBUG_TIMING_START()    \
{\
    LARGE_INTEGER   liStart, liEnd, liFreq;\
    QueryPerformanceCounter(&liStart)

#define DEBUG_TIMING_END(s) \
    QueryPerformanceCounter(&liEnd);\
    QueryPerformanceFrequency(&liFreq);\
    Trace(_T(s) _T(" took %d us\n"), \
        MulDiv((int)(liEnd.QuadPart - liStart.QuadPart), \
        1000000, (int)liFreq.QuadPart));\
}


#else

#define TRACE              1 ? (void)0 : ::Trace
#define TRACE0(sz)
#define TRACE1(sz, p1)
#define TRACE2(sz, p1, p2)
#define TRACE3(sz, p1, p2, p3)

#define DEBUG_TIMING_START()
#define DEBUG_TIMING_END(s)

#endif

#endif