// ============================================================================
//  $Id: TOption.cc,v 1.2 2004/03/07 10:30:34 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TOption.cc,v $
//  Revision 1.2  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.1  2003/10/06 16:32:25  goiwai
//  GNUスタイルの引数を簡単にかつ直感的に解釈するための部品です.
//
// ============================================================================
#include "TOption.hh"

static const Tstring _nodesc = "no description";

TOption::TOption( const Tstring& longoption, const Tstring& shortoption, Tint argstyle, const Tstring& desc )
  : theLongOption( longoption ),
    theShortOption( shortoption ),
    theArgumentStyle( argstyle ),
    theDescription( desc )
{
  initialize();
}

TOption::TOption( const Tstring& longoption, Tint argstyle, const Tstring& shortoption, const Tstring& desc )
  : theLongOption( longoption ),
    theShortOption( shortoption ),
    theArgumentStyle( argstyle ),
    theDescription( desc )
{
  initialize();
}

TOption::TOption( const TOption& right )
  : theLongOption( right.theLongOption ),
    theShortOption( right.theShortOption ),
    theArgumentStyle( right.theArgumentStyle ),
    theDescription( right.theDescription )
{
  initialize();
}

TOption::~TOption()
{;}

const TOption& TOption::operator=( const TOption& right )
{
  theLongOption = right.theLongOption;
  theShortOption = right.theShortOption;
  theArgumentStyle = right.theArgumentStyle;
  theDescription = right.theDescription;
  initialize();
  return *this;
}

Tbool TOption::operator==( const Tstring& right ) const
{
  if ( right.empty() ) {
    return Tfalse;
  } else if ( right.size() == 1 && theShortOption == right ) {
    return Ttrue;
  } else if ( theLongOption == right ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TOption::operator==( const TOption& right ) const
{
  // どっちかが等しければ重複とする
  if ( theLongOption == right.theLongOption || theShortOption == right.theShortOption ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TOption::operator!=( const Tstring& right ) const
{
  if ( right.empty() ) {
    return Tfalse;
  } else if ( right.size() == 1 && theShortOption != right ) {
    return Ttrue;
  } else if ( theLongOption != right ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TOption::operator!=( const TOption& right ) const
{
  // どちらかひとつでも等しければ重複とされる
  if ( theLongOption != right.theLongOption && theShortOption != right.theShortOption ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tvoid TOption::initialize()
{
  if ( theLongOption.size() < 2 ) {
    CLDAQ_EXIT( "size of long option must be greater than 2" );
  }

  if ( theShortOption.size() == 0 || theShortOption.empty() ) {
    theShortOption = theLongOption[ 0 ];
  } else if ( theShortOption.size() != 1 ) {
    CLDAQ_EXIT( "size of short option must be 1" );
  }

  if ( theArgumentStyle < tNeedNot || theArgumentStyle > tEither ) {
    CLDAQ_EXIT( "unexpected argument style" );
  }

  if ( theDescription.size() == 0 || theDescription.empty() ) {
    theDescription = _nodesc;
  }

  return;
}

Tostream& operator<<( Tostream& tos, const TOption& right )
{
  tos << "  -" << right.theShortOption << ", --" << right.theLongOption << Tendl;
  switch ( right.theArgumentStyle ) {
    case TOption::tNeedNot:
      tos << Ttab << "need not a parameter" << Tendl;
      break;
    case TOption::tNeed:
      tos << Ttab << "need a parameter" << Tendl;
      break;
    case TOption::tEither:
      tos << Ttab << "either give or not a parameter" << Tendl;
      break;
    default:
      tos << Ttab << "unexpected argument style" << Tendl;
      break;
  }
  tos << Ttab << right.theDescription << Tflush;

  return tos;
}

Tbool TOption::NeedParameter() const
{
  if ( theArgumentStyle == tNeed ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TOption::NeedNotParameter() const
{
  if ( theArgumentStyle == tNeedNot ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TOption::EitherNeedOrNot() const
{
  if ( theArgumentStyle == tEither ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TOption)
#endif
