// =====================================================================
/*!
//
//  \file Ttypes.h
//  \brief ROOT用のDLLを作るための型解決ファイル
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: Ttypes.h,v 1.1 2005/04/07 00:40:08 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: Ttypes.h,v $
//  Revision 1.1  2005/04/07 00:40:08  goiwai
//  add binding category
//
//  Revision 1.3  2004/06/28 04:02:50  goiwai
//  TlogをTclogに変更
//
//  Revision 1.2  2004/06/24 15:15:25  goiwai
//  たくさんの変更
//  Tcout,Tcerr,Tlogをバッファ経由にした。
//  何個かexternした。Tlog,Tcout,Tcerr,Tinfo...Tcritなど出力関係。
//
//  Revision 1.1  2004/03/07 16:54:18  goiwai
//  ROOTと一緒に使えるCLDAQのIOに特化したモジュールです。
//
*/
// =====================================================================
#ifndef CLDAQ_IODLL__TTYPES_H
#define CLDAQ_IODLL__TTYPES_H

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <list>
#include <vector>
#include <map>
#if (__GNUC__==3) && (__GNUC_MINOR__>0)
#undef __DEPRECATED
#endif
#include <strstream>
#include <stdio.h>
#include <unistd.h>

#define Tfalse 0
#define Ttrue 1
#define Tios std::ios
#define Tlist std::list
#define Tvector std::vector
#define Tmap std::map
#define Tmultimap std::multimap
#define Tpair std::pair
#define Tcin std::cin
#define Tendl std::endl
#define Tends std::ends
#define Tdec std::dec
#define Thex std::hex
#define Toct std::oct
#define Tflush std::flush
#define Tsizeof(_type_) sizeof(_type_)

#define Tcout std::cout
#define Tcerr std::cerr
#define Tclog std::clog

typedef double Tdouble;
typedef int Tint;
typedef float Tfloat;
typedef char Tchar;
typedef long Tlong;
typedef unsigned char TUchar;
typedef unsigned int TUint;
typedef unsigned long TUlong;
typedef short Tshort;
typedef unsigned short TUshort;
typedef bool Tbool;
typedef Tbool Tbit;
typedef FILE TFileStream;
typedef size_t Tsize_t;
typedef void Tvoid;


typedef std::string Tstring;
typedef std::ofstream Tofstream;
typedef std::ifstream Tifstream;
typedef std::ostream Tostream;
typedef std::ostrstream Tostrstream;
typedef std::istream Tistream;


typedef Tvector<Tint> TintList;
typedef Tvector<TUint> TUintList;
typedef Tvector<TUshort> TUshortList;
typedef Tvector<Tdouble> TdoubleList;
typedef Tvector<Tfloat> TfloatList;
typedef Tvector<Tstring> TstringList;



const Tstring Tslash = "/";
const Tstring Ttab = "\t";
const Tstring Thour = "h";
const Tstring Tmin = "m";
const Tstring Tsec = "s";
const Tstring Tmsec = "ms";
const Tstring Tusec = "us";
const Tstring Tnsec = "ns";
const Tchar Tkey = '\x01';

enum Tobject_t { 
  tObjectDataRecord,
  tObjectDataSection,
  tObjectDataSegment,
  tObjectDataElement,
  tObject1DHistogram,
  tObject2DHistogram,
  tObjectAppendGraph,
  tObjectSubstituteGraph,
  tObjectNtuple,
  tNumberOfObjectTypes,
  tObjectUnknown = -1
};

enum Telement_t {
  tTypeInt,
  tTypeString,
  tTypeDouble,
  tTypeObject,
  tTypeFloat,
  tTypeUnsignedShort,
  tTypeShort,
  tTypeWord,
  tTypeLong,
  tTypeUnsignedLong,
  tTypeUnsignedInt,
  tNumberOfElementTypes,
  tTypeUnknown = -1
};

enum Tstream_t { 
  tFileStream,
  tSocketStream,
  tSharedMemoryStream,
  tNumberOfStreamTypes,
  tUnknownStream = -1
};

enum Trandom_t {
  tRandomExponential,
  tRandomGaussian,
  tRandomChiSquare,
  tRandomLandau,
  tRandomGamma,
  tRandomPoisson,
  tNumberOfRandomTypes,
  tRandomUnknown = -1
};

enum Tstatus_t {
  tStatusStandby,
  tStatusReady,
  tStatusBusy,
  tStatusIdle,
  tStatusWaitingReady,
  tStatusJustTakingEvent,
  tStatusJustRecordingEvent,
  tStatusSleep,
  tStatusDead,
  tNumberOfStatusTypes,
  tStatusUnknown = -1
};

enum TvmeTransfer_t {
  tA16D16,
  tA16D32,
  tA24D16,
  tA24D32,
  tA32D16,
  tA32D32,
  tA24D16dma,
  tA32D16dma,
  tA24D32dma,
  tA32D32dma, 
  tNumberOfVmeTransferModes,
  tTransferModeUnknown = -1
};

enum { 
  tIDunknown = -1
};

const Tstring TunknownID = "unkown ID";


inline static Tstring itostr( Tint i, Tint digits = 6 )
{
  static const Tsize_t _buflen = 0x100;
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  if ( i >= 0 ) {
    os << std::setfill( '0' ) << std::setiosflags( Tios::right ) << std::setw( digits );
    os << i << Tends;
    Tstring s = os.str();
    return s;
  } else {
    os << i << Tends;
    Tstring s = os.str();
    Tint nzero = digits - s.size();
    if ( nzero > 0 ) {
      s.insert( 1, nzero, '0' );
    }
    return s;
  }
}

inline static Tstring ltostr( Tlong l, Tint digits = 6 )
{
  static const Tsize_t _buflen = 0x100;
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  if ( l >= 0 ) {
    os << std::setfill( '0' ) << std::setiosflags( Tios::right ) << std::setw( digits );
    os << l << Tends;
    Tstring s = os.str();
    return s;
  } else {
    os << l << Tends;
    Tstring s = os.str();
    Tint nzero = digits - s.size();
    if ( nzero > 0 ) {
      s.insert( 1, nzero, '0' );
    }
    return s;
  }
}

inline static Tstring ultostr( TUlong ul, Tint digits = 6 )
{
  static const Tsize_t _buflen = 0x100;
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  if ( ul >= 0 ) {
    os << std::setfill( '0' ) << std::setiosflags( Tios::right ) << std::setw( digits );
    os << ul << Tends;
    Tstring s = os.str();
    return s;
  } else {
    os << ul << Tends;
    Tstring s = os.str();
    Tint nzero = digits - s.size();
    if ( nzero > 0 ) {
      s.insert( 1, nzero, '0' );
    }
    return s;
  }
}

inline static Tstring dtostr( Tdouble d, Tint precision = 6 )
{
  static const Tsize_t _buflen = 0x100;
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  os << std::setprecision( precision ) << d << Tends;
  Tstring s = os.str();
  return s;
}

inline static Tstring ftostr( Tfloat f, Tint precision = 6 )
{
  return dtostr( (Tdouble)f, precision );
}

#include <unistd.h>

inline static Tbool isexist( const Tstring& filename, Tint mode = R_OK|F_OK )
{
  if ( access( filename.c_str(), mode ) == 0 ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

#include <stdlib.h>
inline static Tint strtoi( const Tstring& nptr, Tchar** endptr = 0, Tint base = 0 )
{
  return (Tint)strtol( nptr.c_str(), endptr, base );
}

inline static Tdouble strtod( const Tstring& nptr, Tchar** endptr )
{
  return strtod( nptr.c_str(), endptr );
}

#include <libgen.h>
inline static Tstring basename( const Tstring& path )
{
  const Tsize_t len = path.size() + 1;
  Tchar* copy = new Tchar[ len ];
  //path.copy( copy, path.size() ); // std::string::copy has bugs.
  strncpy( copy, path.c_str(), len );
  Tchar* b = basename( copy );
  Tstring base( b );
  delete [] copy;
  return base;
}

inline static Tstring dirname( const Tstring& path )
{
  const Tsize_t len = path.size() + 1;
  Tchar* copy = new Tchar[ len ];
  //path.copy( copy, path.size() ); // std::string::copy has bugs.
  strncpy( copy, path.c_str(), len );
  Tchar* d = dirname( copy );
  Tstring dir( d );
  delete [] copy;
  return dir;
}


#define CLDAQ_DEBUG(m) \
if ( strlen(m) ) {\
  Tcout << "[CLDAQ:DEBUG]: " << m << " in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
} else {\
  Tcout << "[CLDAQ:DEBUG]: in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
}
#define CLDAQ_WARN(m) \
if ( strlen(m) ) {\
  Tcerr << "[CLDAQ:WARNIG]: " << m << " in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
} else {\
  Tcerr << "[CLDAQ:WARNIG]: in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
}\
perror( "[CLDAQ:WARNING]" );
#define CLDAQ_EMERG(m) \
if ( strlen(m) ) {\
  Tcerr << "[CLDAQ:EMERG]: " << m << " in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
} else {\
  Tcerr << "[CLDAQ:EMERG]: in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
}\
perror( "[CLDAQ:EMERG]" );\
abort();
#define CLDAQ_ABORT(m) CLDAQ_EMERG(m)
#define CLDAQ_EXIT(m) \
if ( strlen(m) ) {\
  Tcerr << "[CLDAQ:EXIT]: " << m << " in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
} else {\
  Tcerr << "[CLDAQ:EXIT]: in \"" << __PRETTY_FUNCTION__ << "\" at " << __FILE__ << " line " << __LINE__ << "." << Tendl;\
}\
perror( "[CLDAQ:EXIT]" );\
exit(EXIT_SUCCESS);


using namespace std;

#endif
