#pragma once
#include <imagehlp.h>

namespace Gos2 {

typedef BOOL (__stdcall *SYMCLEANUPPROC)( HANDLE );
typedef BOOL (__stdcall *SYMINITIALIZEPROC)( HANDLE, LPSTR, BOOL );
typedef BOOL (__stdcall *SYMSTACKWALKPROC)( DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE );
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)( HANDLE, DWORD );
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)( HANDLE, DWORD );
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL );
typedef BOOL (__stdcall *SYMSETOPTIONSPROC)( DWORD );
typedef BOOL (__stdcall *SYMGETLINEFROMADDRPROC)( HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE );
typedef BOOL (__stdcall *SYMLOADMODULEPROC)( HANDLE, HANDLE, LPSTR, LPSTR, DWORD, DWORD );
typedef BOOL (__stdcall *SYMUNLOADMODULEPROC)( HANDLE, DWORD );


class Debug : public GosDebug
{
public:
	static int				HandleError( int Flags, TCHAR *Text );

	static bool *			Cat( _TCHAR *pCategoryName );
	static void				EnableCat( bool *pCat );
	static void				DisableCat( bool *pCat );
	static void				Output( _TCHAR *pFmt,... );
    static void             OutputV( _TCHAR *pFmt, va_list arglist );

	static bool				LoadImageHlp();
	static void				InitStackWalk( STACKFRAME* sf, CONTEXT* Context );
	static _TCHAR *			GetLocationFromAddress( IMAGEHLP_LINE* ImageHlp_pline, _TCHAR* Buffer, int Address );
	static _TCHAR*			GetSymbolFromAddress( _TCHAR* Buffer, int Address );
	static int				WalkStack( STACKFRAME* sf );
	static _TCHAR*			DecodeAddress( DWORD Address, bool brief );
	static void				WalkStack( DWORD* RoutineAddresses, DWORD NumberOfLevels, DWORD IgnoreLevels );
	static DWORD			WalkUp();

	static SYMFUNCTIONTABLEACCESSPROC	_SymFunctionTableAccess;
	static SYMSTACKWALKPROC				_StackWalk;
	static SYMGETMODULEBASEPROC			_SymGetModuleBase;
	static SYMGETLINEFROMADDRPROC		_SymGetLineFromAddr;
	static SYMGETSYMFROMADDRPROC		_SymGetSymFromAddr;
	static SYMLOADMODULEPROC			_SymLoadModule;
	static SYMINITIALIZEPROC			_SymInitialize;
	static SYMSETOPTIONSPROC			_SymSetOptions;
	static SYMUNLOADMODULEPROC			_SymUnloadModule;

	static HMODULE hModImagehlp;
	static HMODULE hModMsdbi;
	static void* MainModuleBase;
	
	//
	// Buffer for symbol names
	//
	static	BYTE						sym[ sizeof(IMAGEHLP_SYMBOL) + 512 ];
	static	PIMAGEHLP_SYMBOL			psym;
	static	DWORD						LastOffset;
	static	bool						bLoadAllSymbols;

};


} using namespace Gos2;