// =====================================================================
//  $Id: TAnalyser.cc,v 1.4 2004/03/07 10:30:27 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: TAnalyser.cc,v $
//  Revision 1.4  2004/03/07 10:30:27  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.3  2003/10/06 17:02:36  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:17:10  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TAnalyser.hh"
#include "TExtractor.hh"
#include "TMatrixElement.hh"
#include "TDataElement.hh"
#include "TAnalysisStatus.hh"
#include "TAnalysisManager.hh"

TAnalyser::TAnalyser( const Tstring& id )
  : theAnalyserID( id ), theExtractorList( 0 ), 
    theExtractorListCapacity( 1 ), theNumberOfExtractors( 0 ), 
    theExtractorIndex( 0 )
{
  allocate( theExtractorListCapacity );
}

TAnalyser::~TAnalyser()
{
  Tstring head = "TAnalyser::~TAnalyser: ";
  free();
  Tcout << head << "analyser " << theAnalyserID << " was deleted." << Tendl;
}

Tint TAnalyser::AddExtractor( TExtractor* extractor )
{
  const Tstring& strbuf = extractor -> GetExtractorID();
  for ( Tint i = 0; i < theNumberOfExtractors; i ++ ) {
    if ( theExtractorList[ i ] -> GetExtractorID() == strbuf ) {
      Tcerr << "TAnalyser::AddExtractor: already exist extractor identified as " << strbuf << "." << Tendl;
      return theNumberOfExtractors;
    }
  }
  if ( theNumberOfExtractors >= theExtractorListCapacity )
    ResizeExtractorList( theExtractorListCapacity *= 2 );
  theExtractorList[ theNumberOfExtractors ] = extractor;
  theNumberOfExtractors ++;
  theExtractorIndex = theNumberOfExtractors - 1;
  
  Tstring id = extractor -> GetExtractorID();
  Tobject_t objecttype = extractor -> GetMatrixElement().GetObjectType();
  TAnalysisStatus status( id, objecttype );
  TAnalysisManager* manager = TAnalysisManager::GetAnalysisManager();
  ( manager -> GetStatusTable() ).AddAnalysisStatus( status );
  ( manager -> GetStatusTable() ).SetStatus( id, tStatusStandby );

  return theNumberOfExtractors;
}

Tint TAnalyser::RemoveExtractor( Tint index )
{
  Tstring head = "TAnalyser::RemoveExtractor: ";
  if ( index < 0 || index >= theNumberOfExtractors ) {
    Tcerr << head << "invalid index" << Tendl;
    return 0;
  }
  theExtractorIndex = index;
  Tstring id = theExtractorList[ theExtractorIndex ] -> GetExtractorID();
  delete theExtractorList[ theExtractorIndex ];
  Tcout << head << id << " extractor was deleted." << Tendl;
  for ( Tint i = theExtractorIndex; i < theNumberOfExtractors; i ++ )
    theExtractorList[ i ] = theExtractorList[ i + 1 ];
  theNumberOfExtractors --;

  TAnalysisManager* manager = TAnalysisManager::GetAnalysisManager();
  ( manager -> GetStatusTable() ).RemoveAnalysisStatus( id );

  return theNumberOfExtractors;
}

Tvoid TAnalyser::ClearExtractorList()
{
  Tstring head = "TAnalyser::ClearExtractorList: ";
  for ( Tint i = 0; i < theNumberOfExtractors; i ++ ) {
    if ( theExtractorList[ i ] ) {
      Tstring id = theExtractorList[ i ] -> GetExtractorID();
      delete theExtractorList[ i ];
      Tcout << head << id << " extractor was deleted." << Tendl;      
    }
  }

  TAnalysisManager* manager = TAnalysisManager::GetAnalysisManager();
  ( manager -> GetStatusTable() ).Clear();

  theNumberOfExtractors = 0;
  theExtractorIndex = 0;
  return;
}

Tbool TAnalyser::ResizeExtractorList( Tint capacity )
{
  if ( theNumberOfExtractors >= capacity ) {
    Tcerr << "TAnalyser::ResizeExtractorList: invalid capacity" << Tendl;
    return Tfalse;
  }
  theExtractorListCapacity = capacity;
  TExtractor** newExtractors = new TExtractor* [ theExtractorListCapacity ];
  for ( Tint i = 0; i < theNumberOfExtractors; i ++ )
    newExtractors[ i ] = theExtractorList[ i ];
  delete [] theExtractorList;
  theExtractorList = newExtractors;
  theExtractorIndex = theNumberOfExtractors - 1;
  return Ttrue;
}

TExtractor* TAnalyser::NextExtractor()
{
  if ( theExtractorIndex < 0 || theExtractorIndex >= theNumberOfExtractors )
    return 0;
  return theExtractorList[ theExtractorIndex ++ ];
}

TExtractor* TAnalyser::FindExtractor( const Tstring& id )
{
  Tint indexbuf = theExtractorIndex;
  theExtractorIndex = 0;
  TExtractor* ext = 0;
  while ( ( ext = NextExtractor() ) ) {
    if ( ext -> GetExtractorID() == id ) {
      theExtractorIndex = indexbuf;
      return ext;
    }
  }
  theExtractorIndex = indexbuf;
  return 0;
}

TExtractor* TAnalyser::GetExtractor( Tint index )
{
  if ( index < 0 || index >= theNumberOfExtractors ) {
    Tcerr << "TAnalyser::GetExtractor: invalid index" << Tendl;
    return 0;
  }
  theExtractorIndex = index;
  return theExtractorList[ theExtractorIndex ];
}

TExtractor* TAnalyser::GetExtractor()
{
  return GetExtractor( theExtractorIndex );
}

Tvoid TAnalyser::NotFoundExtractor()
{
  Tint indexbuf = theExtractorIndex;
  TExtractor* ext = 0;
  theExtractorIndex = 0;
  Tcout << "Candidates for extractor identification:";
  while ( ( ext = NextExtractor() ) )
    Tcout << Tspace << ext -> GetExtractorID();
  Tcout << Tendl;
  theExtractorIndex = indexbuf;
  return;
}

Tvoid TAnalyser::free()
{
  Tstring head = "TAnalyser::free: ";
  for ( Tint i = 0; i < theNumberOfExtractors; i ++ ) {
    if ( theExtractorList[ i ] ) {
      Tstring id = theExtractorList[ i ] -> GetExtractorID();
      delete theExtractorList[ i ];
      Tcout << head << id << " extractor was deleted." << Tendl;
    }
  }
  delete [] theExtractorList;

  TAnalysisManager* manager = TAnalysisManager::GetAnalysisManager();
  ( manager -> GetStatusTable() ).Clear();

  theExtractorListCapacity = 0;
  theNumberOfExtractors = 0;
  theExtractorIndex = 0;
  return;
}

Tvoid TAnalyser::allocate( Tint capacity )
{
  theExtractorListCapacity = capacity;
  theExtractorList = new TExtractor* [ theExtractorListCapacity ];
  return;
}

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TAnalyser)
#endif
