// =====================================================================
/*!
//
//  \file TSoftwareScalerModule.hh
//  \brief This file contains the TSoftwareScalerModule class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TSoftwareScalerModule.hh,v 1.6 2004/03/07 10:30:31 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TSoftwareScalerModule.hh,v $
//  Revision 1.6  2004/03/07 10:30:31  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.5  2004/01/19 21:09:41  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.4  2003/11/03 08:35:13  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.3  2003/10/06 17:02:40  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:19:11  goiwai
//  ファイルにコミットログをつけることにしました.
//
*/
// =====================================================================
#ifndef CLDAQ__TSOFTWARESCALERMODULE_HH
#define CLDAQ__TSOFTWARESCALERMODULE_HH

#include "Tglobals.h"
#include "TSoftwareModule.hh"
#include "TChannel.hh"

class TDataSegment;
class TDataElement;


/*!
// \example
//
// If example code exists.
//
*/

/*!
// \class TSoftwareScalerModule
// \brief This is the TSoftwareScalerModule class.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// The TSoftwareScalerModule class detail description.
// Write it down ASAP!
//
// \todo None?
// \bug None?
// \ingroup ModulesCategory
*/
class TSoftwareScalerModule
  : public TSoftwareModule
{

  protected:
    enum { tDefaultChannel = 8 };

  protected:
    TChannel theChannel;

  public:
    TSoftwareScalerModule( Tint nchannel = tDefaultChannel );
    TSoftwareScalerModule( const TSoftwareScalerModule& right );
    virtual ~TSoftwareScalerModule();

  public:
    virtual Tint Clear();
    virtual Tint Update();
    virtual Tint Initialize();
    virtual Tvoid FillData( TDataElement& element, Tint channel );

  public:
    virtual Tint Increase( Tint channel );
    virtual Tint Increase();
    virtual Tint Decrease( Tint channel );
    virtual Tint Decrease();
    virtual Tint GetData( Tint channel ) const;
    virtual Tvoid SetData( Tint channel, Tint data );

  public:
    virtual const TSoftwareScalerModule& operator=( const TSoftwareScalerModule& right );
    virtual Tbool operator==( const TSoftwareScalerModule& right ) const;
    virtual Tbool operator!=( const TSoftwareScalerModule& right ) const;

  public:
    virtual const TChannel& GetChannel() const;
    virtual Tvoid SetChannel( const TChannel& channels );

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TSoftwareScalerModule,0)
#endif

};

inline Tint TSoftwareScalerModule::GetData( Tint channel ) const
{
  if ( channel < 0 || channel >= theNumberOfChannels ) {
    Tcerr << "TSoftwareScalerModule::GetData: invalid ID" << Tendl;
    return -EFAULT;
  } else {
    return theChannel[ channel ];
  }
}

inline Tvoid TSoftwareScalerModule::SetData( Tint channel, Tint data )
{
  if ( channel < 0 || channel >= theNumberOfChannels ) {
    Tcerr << "TSoftwareScalerModule::SetData: invalid ID" << Tendl;
    return;
  } else {
    theChannel[ channel ] = data;
    return;
  }
}

inline const TChannel& TSoftwareScalerModule::GetChannel() const
{
  return theChannel;
}

inline Tvoid TSoftwareScalerModule::SetChannel( const TChannel& channels )
{
  theChannel = channels;
  return;
}

inline Tint TSoftwareScalerModule::Increase( Tint channel )
{
  if ( channel < 0 || channel >= theNumberOfChannels ) {
    Tcerr << "TSoftwareScalerModule::Increase: invalid ID" << Tendl;
    return theStatus = -EFAULT;
  } else {
    Tint data = GetData( channel );
    SetData( channel, ++ data );
    return theStatus = tStatusSuccess;
  }
}

inline Tint TSoftwareScalerModule::Decrease( Tint channel )
{
  if ( channel < 0 || channel >= theNumberOfChannels ) {
    Tcerr << "TSoftwareScalerModule::Decrease: invalid ID" << Tendl;
    return theStatus = -EFAULT;
  } else {
    Tint data = GetData( channel );
    SetData( channel, -- data );
    return theStatus = tStatusSuccess;
  }
}

inline Tint TSoftwareScalerModule::Increase()
{
  Tint ret = tStatusSuccess;
  for ( Tint i = 0; i < theNumberOfChannels; i ++ )
    ret &= Increase( i );
  return ret;
}

inline Tint TSoftwareScalerModule::Decrease()
{
  Tint ret = tStatusSuccess;
  for ( Tint i = 0; i < theNumberOfChannels; i ++ )
    ret &= Decrease( i );
  return ret;
}

inline Tint TSoftwareScalerModule::Clear()
{
  for ( Tint i = 0; i < theNumberOfChannels; i ++ )
    theChannel[ i ] = 0;
  return theStatus = tStatusSuccess;
}

inline Tint TSoftwareScalerModule::Update()
{
  return Increase();
}

inline Tint TSoftwareScalerModule::Initialize()
{
  return Clear();
}

#endif
