#include <RAT/FitValidityCutProc.hh>
#include <RAT/DS/Entry.hh>
#include <RAT/DS/FitVertex.hh>

using namespace RAT;
using namespace std;


void FitValidityCutProc::SetS( const string& param, const string& value )
{

  if( param == "parameter" )
    if( value == "position" || value == "direction" || value == "energy"
        || value == "time" )
      fFitParameter = value;
    else
      throw ParamInvalid( param, "must relate to a FitResult parameter" );
  else if( param == "fitName" )
    fFitName = value;
  else
    throw ParamUnknown( param );

}

Processor::Result FitValidityCutProc::DSEvent( DS::Run& , DS::Entry& ds )
{

  if( ds.GetEVCount() != 1 )
    return Processor::OKFALSE;

  bool valid = true;

  try
    {
      const DS::FitResult& result = ds.GetEV( 0 ).GetFitResult( fFitName );

      if( result.GetVertexCount() == 0 )
        return Processor::OKFALSE;

      for( size_t iVertex = 0; iVertex < result.GetVertexCount(); iVertex++ )
        {
          const DS::FitVertex& vertex = result.GetVertex( iVertex );

          // bitwise "AND" assignments; if either current valid value is false
          // or vertex.ValidXXX() is false, valid set to false.
          if( fFitParameter == "position" )
            valid &= vertex.ValidPosition();
          else if( fFitParameter == "time" )
            valid &= vertex.ValidTime();
          else if( fFitParameter == "direction" )
            valid &= vertex.ValidDirection();
          else if( fFitParameter == "energy" )
            valid &= vertex.ValidEnergy();
          else
            throw ParamUnknown( fFitParameter );
        }
    }
  catch( DS::DataNotFound& )
    {
      return Processor::FAIL;
    }

  if( valid )
    return Processor::OKTRUE;
  else
    return Processor::OKFALSE;

}