/**
 * @file
 * $URL$
 * $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 Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at your

 *
 * 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 Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser 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_UTILITY_H
#define __IWEAR_UTILITY_H

#pragma warning( disable: 4001 )

#ifdef __cplusplus
#include <iostream>
#include <sstream>
#include <cmath>
#include <map> // To get the binary_function stuff for comparators
#include <stdexcept>
#ifdef _GNUC
#include <cxxabi.h>
#endif
#include<boost/tokenizer.hpp>
#include<string>
#include<list>
#include <ctime>
#include <boost/cstdint.hpp>
using namespace boost;
#include "iwear/gettimeofday.h"
extern "C" {
#else
#include <math.h>
#endif


#include <time.h>
//#include <sys/time.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#include <stdlib.h>
//#include <demangle.h>

	
extern const char * iwear_char_to_hex_up[256];
extern const char * iwear_char_to_hex_low[256];

extern int bitcount_8_table[256];
#ifdef _WIN32
#define inline
#endif
inline const char * ctohexu( char c ) { return iwear_char_to_hex_up[(uint32_t)((uint8_t)c)];}
inline const char * ctohexl( char c ) { return iwear_char_to_hex_low[(uint32_t)((uint8_t)c)];}

/**
 * This function enables a verbose crash handler. It will display a simple
 * stack trace in case of an catched SIGSEGV or SIGABRT. Be aware, that if
 * something triggered a signal, the signal handler displaying the stack trace
 * isnt safe to call, so the program then might crash or hang or blow up your
 * pc.
 */

inline int bitcount8( char b )
{
    return bitcount_8_table[(int)b];
}
/**
 * This is really faster than a loop (7-8 times).
 * If you really need faster than this, search for an inline assembler way.
 * Tabelling is only 12% faster than this (27 against 24 opcodes)
 */
#define BITCOUNT32(x)     (((BX_SUBROTAND_(x)+(BX_SUBROTAND_(x)>>4)) & 0x0F0F0F0F) % 255)
#define BX_SUBROTAND_(x)  ((x) - (((x)>>1)&0x77777777)                    \
                               - (((x)>>2)&0x33333333)                    \
                               - (((x)>>3)&0x11111111))

/**
 * Takes about 14 cycles
 */
#define BITREVERSE32(n)		\
n = ((n >>  1) & 0x55555555) | ((n <<  1) & 0xaaaaaaaa); \
n = ((n >>  2) & 0x33333333) | ((n <<  2) & 0xcccccccc); \
n = ((n >>  4) & 0x0f0f0f0f) | ((n <<  4) & 0xf0f0f0f0); \
n = ((n >>  8) & 0x00ff00ff) | ((n <<  8) & 0xff00ff00); \
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);

#define ENUM_MIN_BITS(x) INT_MIN_BITS(num_##x)

/**
 * Constant determination of minimum bits needed for a specific representation.
 * Does currently only work for values that need no more than 19 bits.
 */
#define INT_MIN_BITS(x) \
((x) > 0  ? \
 ((x) > 1  ? \
  ((x) > 3  ? \
   ((x) > 7  ? \
    ((x) > 15  ? \
     ((x) > 31  ? \
      ((x) > 63  ? \
       ((x) > 127  ? \
	((x) > 255  ? \
	 ((x) > 511  ? \
	  ((x) > 1023  ? \
	   ((x) > 2047  ? \
	    ((x) > 4095  ? \
	     ((x) > 8191  ? \
	      ((x) > 16383  ? \
	       ((x) > 32767  ? \
		((x) > 65535  ? \
		 ((x) > 131071  ? \
		  ((x) > 262143  ? \
		   ((x) > 524287  ? 20 : 19) \
		    : 18) : 17) : 16) : 15) : 14) : 13) : 12) : 11) : 10) : 9) \
		     : 8) : 7) : 6) : 5) : 4) : 3) : 2) : 1) : 0)

#ifdef __cplusplus
}
#endif

// Those template functionality makes only sense within C++
#ifdef __cplusplus


namespace iwear
{
    /**
     * @namespace iwear
     * This Documents the iwear namsepace.
     *
     * The iwear namespace is the top namespace of every entity in the iwear
     * framework. It currently consists of several namespaces at lower level,
     * but a hiearachy depth of more than 3 is not desired.
     */

    /**
     * @name Format String Functions
     *
     * Those functions will give us the possibilty to get format strings to
     * corresponding types at compile time through template instantiation and
     * full compiler optimization.
     * Those format strings do not support any kind of precision specifier, or
     * alignment/padding specifiers.
     * @{
     */
    /// Generic definition for this template
    template<typename T> const char * get_fmt_str( T );

    /// Specilizations
    template<> inline const char * get_fmt_str(short) 		{ return "%hd"; }
    template<> inline const char * get_fmt_str(unsigned short) 	{ return "%hu"; }
    template<> inline const char * get_fmt_str(int) 		{ return "%d"; }
    template<> inline const char * get_fmt_str(unsigned int) 	{ return "%u"; }
    template<> inline const char * get_fmt_str(long) 		{ return "%ld"; }
    template<> inline const char * get_fmt_str(unsigned long) 	{ return "%lu"; }
    
#if defined(__GNUC__ ) && !defined(__STRICT_ANSI__)
    template<> inline const char * get_fmt_str(long long) 	{ return "%lld"; }
    template<> inline const char * get_fmt_str(unsigned long long) { return "%llu"; }
#endif
    /**
     * Here we have a little inconsistence within the standard. For output it
     * says that %f is the same as %lf but for input it specifies that %lf
     * refers to double, whereas it is not really clear that %f refers only to
     * a float value. Therfore we assume that for a float we use %f while we
     * use %lf for doubles.
     */
    template<> inline const char * get_fmt_str(float) 		{ return "%f"; }
    template<> inline const char * get_fmt_str(double) 		{ return "%lf"; }
    template<> inline const char * get_fmt_str(long double) 	{ return "%Lf"; }
//    template<> inline const char * get_fmt_str(uintmax_t) { return "%ju"; }
//    template<> inline const char * get_fmt_str(intmax_t) { return "%jd"; }
    template<> inline const char * get_fmt_str(char) 		{ return "%c"; }
    template<> inline const char * get_fmt_str(unsigned char) 	{ return "%c"; }
    template<> inline const char * get_fmt_str(wchar_t) 	{ return "%lc"; }
    template<> inline const char * get_fmt_str(void *) 		{ return "%p"; }


    /// Generic template for not implemented format strings. Will issue compile time error
    template<typename T> void you_tried_to_compile_with_an_unsupported_fmt_str_template_instantiation( T );

    template <typename T> const char * get_fmt_str( T t)
    {
	you_tried_to_compile_with_an_unsupported_fmt_str_template_instantiation(t);
	return NULL;
    }
    /**
     * @}
     */
    inline timeval time_from_string( const char * from)
    {
	tm it;
	memset(&it,0,sizeof(it));
	timeval xxx;
	strptime(from,"%Y-%m-%d %H:%M:%S",&it);
	xxx.tv_sec = mktime(&it);
	const char * point = strchr(from,'.');
	double subsec = atof(point);
	//xxx.tv_usec = (suseconds_t)((double)subsec * 1000000);
	xxx.tv_usec = static_cast<long>(subsec * 1000000.0);
/*
	std::cout << "Year " << it.tm_year  << std::endl;
	std::cout << "Month " << it.tm_mon << std::endl;
	std::cout << "Sec " << it.tm_sec << std::endl;
	std::cout << "SubSec " << subsec << std::endl;
	std::cout << "USec " << xxx.tv_usec << std::endl;
	*/
	return xxx;
    }

    /**
     * Sets a timeout of now+tof into that function. Almost all pthread api
     * functions need this for a timeout.
     */
    inline void clock_settimeout( timespec& tot, float tof )
    {
	clock_gettime( CLOCK_REALTIME, &tot );
	tot.tv_sec += static_cast<long int>(floor(tof));
	tot.tv_nsec += static_cast<long int>((tof-floor(tof)) * 1000000000.0);
	tot.tv_sec += tot.tv_nsec / 1000000000;
	tot.tv_nsec = (tot.tv_nsec % 1000000000);
    }


    /**
     * This is an ugly function which we use to force a rewrite
     */
    template<class M, class V>
    void map_force_insert( M& m, const V& v )
    {
	typename M::iterator i = m.insert(v).first;
	i->second = v.second;
	const_cast<typename M::key_type>(i->first) = v.first;
    }

    /**
     * In some rare cases a c-cstyle cast is needed. To easily grep for them in
     * code, we give them a name here.
     */
    template<class T, class T2> 
    T unsafe_cast(T2 a) 
    { 
//	return (T)a; 
    }

    template<class T, class T2> 
    T dammit_cast(T2 a) 
    { 
//	return (T)a; 
    }

    inline void list_explode( std::list<std::string>& l, const std::string& s, const std::string& d )
    {
	boost::tokenizer<boost::char_separator<char> > tok( s,
		boost::char_separator<char>( d.c_str() ) );

	for( boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin(); beg != tok.end(); ++beg)
	{
	    l.push_back(*beg);
	}
    }




   /**
    * Comparator to be used as template argument for associative containers
    * like std::map and std::set. This particular comparator dereferences the
    * object before comparing, so this must be a pointer. This is usefull to
    * keep pointer to existing objects, but want to keep track of the objects
    * rather than the pointers.
    */
    template <class _Tp>
    struct deref_less : public std::binary_function<_Tp,_Tp,bool>
    {
	  bool operator()(const _Tp& __x, const _Tp& __y) const { return (*__x) < (*__y); }
    };

    template <class _Tp>
    struct deref_greater : public std::binary_function<_Tp,_Tp,bool>
    {
	  bool operator()(const _Tp& __x, const _Tp& __y) const { return (*__x) > (*__y); }
    };

    template <class _Tp>
    struct deref_equal : public std::binary_function<_Tp,_Tp,bool>
    {
	  bool operator()(const _Tp& __x, const _Tp& __y) const { return (*__x) == (*__y); }
    };

    struct cstring_less : public std::binary_function<const char *, const char *,bool>
    {
	bool operator()(const char * __x, const char * __y) const
	{
    	    return (strcmp(__x,__y) < 0	);
	}
    };

    template<class _Tp>
    struct compare_equal : public std::binary_function<_Tp,_Tp,bool>
    {
	bool operator()( const _Tp& __x, const _Tp& __y) const { return (__x) == (__y); }
    };

    template<>
    inline bool compare_equal<double>::operator()( const double& __x, const double& __y) const
    {

	///@todo TODO FIXME obsolete
	return fabs((__x) - (__y)) < 0.001;//double_epsilon;
    }
} // namespace iwear

/**
 * @addtogroup Output_Operators
 *
 * Those operators are generally defined to output certain own defined
 * classes, or classes which have no output format by standard.
 *
 * @{
 */

inline std::ostream& operator<<(std::ostream& o, const timeval& u)
{
    char buf[8];
    // cast it here to avoid warnings in case suseconds is defined to something
    // else than a long
    snprintf(buf,8,".%06lu",static_cast<unsigned long int>(u.tv_usec));
    o << u.tv_sec;
    o << (buf);
    return o;
}
/**
 * @}
 */
inline const timeval& operator+= ( timeval& a, double r )
{
    uint32_t secs = static_cast<uint32_t>(floor(r));
    uint32_t msecs = static_cast<uint32_t>((r - floor(r)) * 1000000.0);
    a.tv_sec += secs;
    a.tv_usec += msecs;
    return a;
}

inline timeval operator+ ( const timeval& a, double r )
{
    timeval u(a);
    uint32_t secs = static_cast<uint32_t>(floor(r));
    uint32_t msecs = static_cast<uint32_t>((r - floor(r)) * 1000000.0);
    u.tv_sec += secs;
    u.tv_usec += msecs;
    return u;
}

inline bool operator==( const timeval& a, const timeval& b)
{
    return( memcmp(&a,&b,sizeof(timeval)) == 0 );
}

inline bool operator!=( const timeval& a, const timeval& b )
{
    return( !(a == b));
}

inline bool operator<( const timeval& a, const timeval& b )
{
    return ( a.tv_sec < b.tv_sec || ((a.tv_sec == b.tv_sec) && (a.tv_usec < b.tv_usec)) );
}

inline bool operator>( const timeval& a, const timeval& b )
{
    return ( a.tv_sec > b.tv_sec || ((a.tv_sec == b.tv_sec) && (a.tv_usec > b.tv_usec)) );
}

inline bool operator>=( const timeval& a, const timeval& b )
{
    return ( a.tv_sec > b.tv_sec || ((a.tv_sec == b.tv_sec) && (a.tv_usec >= b.tv_usec)) );
}

inline bool operator<=( const timeval& a, const timeval& b )
{
    return ( a.tv_sec < b.tv_sec || ((a.tv_sec == b.tv_sec) && (a.tv_usec <= b.tv_usec)) );
}
#endif // #ifdef __cplusplus


#endif // __IWEAR_UTILITY_H
