///////////////////////////////////////////////////////////////
// mimimalistic debugging & logging
// Created by Yulius Dudinsky ( ddnsky@gmail.com ) 
///////////////////////////////////////////////////////////////
# pragma once
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>

#ifdef _MSC_VER
#define DBG_BREAK()			__asm { int 3 }
//#define DBG_BREAK()			_CrtDbgBreak()
#else 
#define DBG_BREAK()			ASSERT( false )
#endif


#define DBG_LOG()                                (std::cerr)
#define DBG_CMSG(msg)                            (DBG_LOG()<<msg)
#define DBG_CERR(msg)                            (DBG_LOG()<<msg)
#define DBG_MSGBOX(header,msg)                   (DBG_LOG()<<header<<':'<<msg)
#define DBG_ASSERTION_FAILED(expr_)              (std::cerr<<" Assertion failed :"<<expr_<<" in File: "<<__FILE__<<" Line:"<<__LINE__<<'\n'); abort(); 
#define DBG_TRACE( ... )                         (fprintf( stderr, __VA_ARGS__ ))
#define DBG_FLUSH()                              (std::cerr<<std::endl)


//#define RTASSERTM_( expr, msg ) { static bool gThisAssertIgnore = false; if( !gThisAssertIgnore && !(expr) ) { DBG_MSG( msg ); argo::Debug::AssertionFailed( #expr, &gThisAssertIgnore ); } }
//#define RTASSERT_IGNORABLE( expr )		RTASSERTM_( expr, "" )
//#define RTASSERTM( expr, msg )  { if( !(expr) ) { DBG_MSG( msg ); argo::Debug::AssertionFailed( #expr, 0 ); } }
#define RTASSERT( expr )		{ if( !(expr) ) { DBG_ASSERTION_FAILED( #expr ); } }
#define RTNEVER()				RTASSERT(0)
#define ASSERT(x)               BOOST_ASSERT(x)

/*
#ifdef __cplusplus
extern "C" {
#endif//__cplusplus

void nstd_Trace( char const* fmt ... );
void nstd_Trace_( char const* fmt, va_list ap );
int nstd_MsgBox( char const* theTitle, char const* theText, bool doRetryIgnoreButtons = false );
void nstd_AssertionFailed( const char* Expr, bool* theAssertionIgnore );
void nstd_FatalError( const char* theTitle, const char* theMessage, bool doRetryIgnoreButton );

#ifdef __cplusplus
}
#endif//__cplusplus

#ifndef DBG_ASSERT_ON
#if !defined(RELEASEFINAL) || defined( _DEBUG )
#define DBG_ASSERT_ON
#endif
#endif

#define DBG_FLUSH_()			argo::Debug::Flush()
#define DBG_LOG_()				std::cerr<<( __FILE__ , __LINE__ )()
#define DBG_MSG( msg )			argo::Debug::GetLog( __FILE__ , __LINE__ )() << msg
#define DBG_MES( msg )			(void)( DBG_MSG( msg ), DBG_FLUSH() )
#define DBG_COMMA ,
#define DBG_FERR( msg )			(void)( DBG_MSG( msg ), argo::Debug::FatalError( "DBG_FERR" ), 0 )
#define DBG_MSGBOX( msg )		(void)( DBG_MSG( msg ), argo::Debug::MsgBox( "DBG_MSGBOX", 0 ), 0 )
*/

/*
#ifdef __cplusplus
#include <iosfwd>
namespace argo {
	struct Debug {
		class LogMsg {
			LogMsg(); LogMsg( LogMsg const& ); void operator=( LogMsg const& ); friend struct Debug; 
		public:
			~LogMsg();
			std::ostream& operator()() const;
		};

		Debug();
		Debug( char const* theAppFileName );
		~Debug();

		static LogMsg GetLog( const char* nameOfFile = 0, int lineInFile = 0 );

		static void OpenFile( char const* aAppFileName );
		static void Flush();
		static void CloseFile();
		
		static int FatalError( const char* theTitle, const char* theMessage, bool doRetryIgnoreButton );
		static void FatalError( const char* theMessage );

		static void*	NewMemTrace( size_t sz );
		static void		DelMemTrace( void* ptr );
		static void		DumpMemUnfreed();
		static void		Trace( char const* fmt ... );
	
		typedef int( *DoMsgBoxFn )( char const* theText, char const* theTitle, int theFlags );
		static DoMsgBoxFn gDoMsgBox;
	};
}
#endif//__cplusplus


#if defined( DEBUG_ERROR_ON )

#	define DMES( msg )				    DBG_MES( msg )
#	define DMSG( msg )				    DBG_MSG( msg )
#	define ASSERT( x )					RTASSERT( x )
#	define ASSERTM( expr, msg )		    RTASSERTM( expr, msg )
#	define ASSERT_( x )					RTASSERT_( x )
#	define ASSERTM_( expr, msg )		RTASSERTM_( expr, msg )
#	define VERIFY( expr )			    ASSERT( expr )
#	define VERIFYM( expr, msg )			ASSERTM( expr, msg )
#	define ASSUME_NEVER()			    RTNEVER()
#	define DBREAK()				        DBG_BREAK()
#	define DNEVER()						RTNEVER()

#	define DBG_BeParanoid( text )	    text

#	define DMESIF( expr, msg )		    if( expr ) DMES( msg );
#	define DBREAKIF( expr )             if( expr ) DBG_BREAK()
#	define DTRACE( ... )   	            argo::Debug::Trace( __VA_ARGS__ )

#else

#	define DMES( msg )                 ((void)0)
#	define DMSG( msg )                 ((void)0)
#	define VERIFY( expr )              (expr)
#	define VERIFYM( expr, msg )        (expr)
#	define ASSERT( expr )			   ((void)0)
#	define ASSERTM( expr, msg )        ((void)0)
#	define ASSERT_( expr )		       ((void)0)
#	define ASSERTM_( expr, msg )       ((void)0)
#	define DNEVER()					

#	ifdef _MSC_VER
#		define ASSUME_NEVER()              __assume( false )
#	else
#		define ASSUME_NEVER()        
#	endif

#	define DBREAK()                    ((void)0)
#	define DBG_BeParanoid( text )
#	define DMESIF( expr, msg )         ((void)0)
#	define DBREAKIF( expr )            ((void)0)
#	define DTRACE( ... )
#endif

# if defined( RELEASEFINAL )
#	define DBG_Retail( text )	text
#	define DBG_NotRetail( text )
#	define DBG_Switch( debug_text, retail_text ) retail_text
#	define ARGO_STATIC_ASSERT( expr )
# else
#	define DBG_Retail( text )
#	define DBG_NotRetail( text )	text
#	define DBG_Switch( debug_text, retail_text ) debug_text
#	define ARGO_STATIC_ASSERT( expr ) typedef char __DEBUG_JOIN__( STATIC_ASSERT_ERROR_, __LINE__ ) [1][(expr)]
# endif


#define __DEBUG_JOIN__( X, Y )  __DEBUG_JOIN1__( X, Y )
#define __DEBUG_JOIN1__( X, Y ) __DEBUG_JOIN2__( X, Y )
#define __DEBUG_JOIN2__( X, Y ) X##Y
#define STRINGIZE_INDIRECT( F, X ) F( X )
#define STRINGIZE( X ) #X
#define __LINESTR__ STRINGIZE_INDIRECT( STRINGIZE, __LINE__ )
#define __FILELINEFUN__ ( __FILE__ " " __LINESTR__ " " __FUNCTION__ )
#define __FUNLINE__ ( __FUNCTION__ " " __LINESTR__ )
#define __MESSAGE__ __FILE__ "(" __LINESTR__ ") : message X1234: "
#define __FIXME__ __FILE__ "(" __LINESTR__ ") : message X1234: !!FIXME!!"
#define CTASSERT( expr ) ARGO_STATIC_ASSERT( expr ) 
*/









