/************************************************************************/
/* Ex Nihlo Engine by Hermanns Christophe								*/
/************************************************************************/
/* This program is free software; you can redistribute it and/or		*/
/* modify it under the terms of the GNU General Public License			*/
/* as published by the Free Software Foundation; either version 2		*/
/* of the License, or (at your option) any later version.				*/
/*																		*/
/* This program is distributed in the hope that it will be useful,		*/
/* but WITHOUT ANY WARRANTY; without even the implied warranty of		*/
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.					*/
/*																		*/
/* See the GNU General Public License for more details.					*/
/*																		*/
/* You should have received a copy of the GNU General Public License	*/
/* along with this program; if not, write to the Free Software			*/
/* Foundation, Inc., 59 Temple Place - Suite 330,						*/
/* Boston, MA  02111-1307, USA.											*/
/*																		*/
/* If you use a important part of this code please send me a mail		*/
/* I just want to see where my code go thks :)							*/
/************************************************************************/

/************************************************************************/
/* Contact                                                              */  
/************************************************************************/
/* ExNihilo Website :www.ploksoftware.org                               */
/*                                                                      */
/* Hermanns Christophe ExNihilo creator and main programmer             */
/*                                                                      */
/* Mail             : Data@ploksoftware.org								*/
/* ICQ              : 8030901											*/
/* MSN Messenger    : Data_7@hotmail.com								*/
/*                                                                      */
/*                                                                      */
/************************************************************************/

/************************************************************************/
/* File Description             										*/
/************************************************************************/
/* File Name   :ExCTrace.h												*/
/*																		*/
/* Start Date   :03/15/2002												*/
/*																		*/
/* Last Update :06/20/2003                                              */
/*																		*/
/* File Description :													*/
/*                                                                      */
/* For update of this file check : www.ploksoftware.org                 */
/************************************************************************/

#ifndef EXCTRACE_H__
#define EXCTRACE_H__

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#ifndef GCC_295
	#include <ostream>
#endif
#include <string.h>
#include <time.h>
#include <sys/timeb.h>
#include <sys/types.h>

#include <iostream>
#include <strstream>
#ifdef UNIX_SRC
	#include <typeinfo>
#else
	#include <typeinfo.h>
#endif
/*
	Traceable call stack
	Before compiling make your choice betwene
	1) NORMAL
	2) TRACE
	3) DEBUG
	4) LOG
	
	NORMAL :
		Guard and UnGard are defined as nothing use only when you 
		have finish your programe
	TRACE :
		Each function call will be show on consol and each 
		function out to
	DEBUG :
		If any exception occure you will show on consol the 
		call stack and where the programme bug ...
	LOG	:
		Same as Debug but all is redirect to log.txt
	TRACETIME:
		Show tge time each function take
*/

#ifndef UNIX_SRC
	// under WIN32 change here
	// UNIX users use the configure script
	#define DEBUG
#endif

#define EXC throw 1;
 
//#ifndef UNIX_SRC
	#ifdef NORMAL
		#define Guard(function) 
		#define UnGuard
		#define Trace
		#define Error
	#else 
	#ifdef LOG
	static std::ofstream logfile("callstack.log",std::ios::app);\
		#define Guard(function)	static char * __FUNCTION_NAME__ = #function;\
										try {
		#define UnGuard } catch (...) {\
										time_t tt;struct tm *ttb;tt = time(NULL);ttb = localtime(&tt);\
										logfile<<"*********************CALL STACK*********************"<<std::endl;\
										logfile<<"* Date   : "<<asctime(ttb);\
										logfile<<"* Module : "<<__FUNCTION_NAME__<<std::endl;\
										logfile<<"* Line   : "<<__LINE__<<std::endl;\
										logfile<<"* File   : "<<__FILE__<<std::endl;\
										logfile<<"* Make date : "<<__DATE__<<" "<<__TIME__<<std::endl;\
										logfile<<"***************************************************"<<std::endl;\
										throw; }
	#elif defined DEBUG
		#define Guard(function)	static char * __FUNCTION_NAME__ = #function;\
										try {
		#define UnGuard } catch (...) {\
										time_t tt;struct tm *ttb;tt = time(NULL);ttb = localtime(&tt);\
										std::cout<<"*********************CALL STACK*********************"<<std::endl;\
										std::cout<<"* Date   : "<<asctime(ttb);\
										std::cout<<"* Module : "<<__FUNCTION_NAME__<<std::endl;\
										std::cout<<"* Line   : "<<__LINE__<<std::endl;\
										std::cout<<"* File   : "<<__FILE__<<std::endl;\
										std::cout<<"* Make date : "<<__DATE__<<" "<<__TIME__<<std::endl;\
										std::cout<<"***************************************************"<<std::endl;\
										throw; }
	#elif defined TRACE
			#define Guard(function)	static char * __FUNCTION_NAME__ = #function;\
										std::cout<<">>>> Module : "<<__FUNCTION_NAME__<<std::endl;
			#define UnGuard				std::cout<<"<<<< Module : "<<__FUNCTION_NAME__<<std::endl;

	
	#elif defined TRACETIME
		static std::ofstream logfile("TraceTime.log",std::ios::out);
		#define Guard(function)	static char * __FUNCTION_NAME__ = #function;\
										__timeb64 ltime,ltime2;\
										logfile<<"Enter function : "<<__FUNCTION_NAME__<<std::endl;\
										_ftime64(&ltime );
		#define UnGuard					_ftime64(&ltime2 );\
										logfile<<"Time in func   : "<<ltime2.millitm-ltime.millitm <<std::endl;\
										logfile<<"Leave function : "<<__FUNCTION_NAME__<<std::endl;

	#endif //TRACETIME


	#define Trace(why) static char * __WHY__ = #why;\
										time_t tt;struct tm *ttb;tt = time(NULL);ttb = localtime(&tt);\
										std::cout<<"***********************TRACE***********************"<<std::endl;\
										std::cout<<"* Date      : "<<asctime(ttb);\
										std::cout<<"* Module    : "<<__FUNCTION_NAME__<<std::endl;\
										std::cout<<"* Line      : "<<__LINE__<<std::endl;\
										std::cout<<"* File      : "<<__FILE__<<std::endl;\
										std::cout<<"* Make date : "<<__DATE__<<" "<<__TIME__<<std::endl;\
										std::cout<<"* Cause     : "<<__WHY__<<std::endl;\
										std::cout<<"* Error     : "<<errno<<std::endl;\
										std::cout<<"***************************************************"<<std::endl;
	
	#endif // !NORMAL
//#endif
							
#endif // EXCTRACE_H__
