// =====================================================================
//  $Id: TSoftwareScalerModule.hh,v 1.1.1.1 2003/06/27 02:56:41 goiwai Exp $
//  $Name: CLDAQ-1-06-02 $
// =====================================================================
#ifndef __TSOFTWARESCALERMODULE_HH
#define __TSOFTWARESCALERMODULE_HH

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

class TDataSegment;
class TDataElement;

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 );

};

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
