/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 * In particular this file is part of the Framework Core Library
 *
 * The iWear Framework 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 as in version 2 of the License.

 * 
 * The iWear Framework 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
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWEAR_DEBUG_H
#define __IWEAR_DEBUG_H

#ifdef __cplusplus
#include <cstddef>
#include <string>
#include <sstream>
#include <cxxabi.h>
extern "C" {
#else
#include <stddef.h>
#endif

extern void enable_verbose_crash( void ); // C Linkage

#ifdef __cplusplus
}
#endif

inline void segfault( void ) { int* i = NULL; int u = *i; *i = u; }

namespace iwear {

    inline std::string gen_ffl_string( const char * func, const char * file, int line )
    {
	/*
	std::string ffl(func);
	ffl += "\n\t";
	ffl += file;
	ffl += "\n\t";
	std::stringstream fs;
	fs << line;
	std::string ftmp;
	fs >> ftmp;
	ffl += ftmp;
	*/
	std::string ffl(func);
	ffl += " at ";
	ffl += file;
	ffl += ":";
	std::stringstream fs;
	fs << line;
	std::string ftmp;
	fs >> ftmp;
	ffl += ftmp;
	return ffl;
    }

    inline std::string gen_fl_string( const char * file, int line )
    {
	std::string fl;
	fl += file;
	fl += ":";
	std::stringstream fs;
	fs << line;
	std::string ftmp;
	fs >> ftmp;
	fl += ftmp;
	return fl;
    }

#define DEMANGLE_BUFFER_SIZE 256
    inline std::string demangle_cpp_name( const char * name )
    {
	char demn[DEMANGLE_BUFFER_SIZE+1];
	size_t size = DEMANGLE_BUFFER_SIZE;
	int st;
	abi::__cxa_demangle(name,demn,&size,&st);
	return std::string(demn);
    }

    template<class T>
    inline std::string typenameof( const T& t)
    {
	return demangle_cpp_name(typeid(t).name());
    }

    inline std::string current_exception_name( void )
    {
	return demangle_cpp_name(abi::__cxa_current_exception_type()->name());
    }

}// namespace iwear

#ifdef __DEBUGSTREAM_H
#define DOUT d_dbg
#else
#define DOUT cout
#endif

#define __FFL__ iwear::gen_ffl_string( __PRETTY_FUNCTION__, __FILE__, __LINE__ )

#define __FL__ iwear::gen_fl_string( __FILE__, __LINE__ )

#define PH1 /** This has passed Phase 1 check */ 
#define PH2 /** This has passed Phase 2 check */ 
#define PH3 /** This has passed Phase 3 check */ 
#define PH4 /** This has passed Phase 4 check */ 
#define PH5 /** This has passed Phase 5 check */ 
#define PH6 /** This has passed Phase 6 check */ 

#define P1CLEAR BuildPhase::check(1);
#define P2CLEAR BuildPhase::check(2);
#define P3CLEAR BuildPhase::check(3);
#define P4CLEAR BuildPhase::check(4);
#define P5CLEAR BuildPhase::check(5);
#define P6CLEAR BuildPhase::check(6);
#define P7CLEAR BuildPhase::check(7);


#endif
