/**
 * \class BDPipeline
 *
 * \ingroup BeamDataUtil
 *
 * \brief A collection of procedures for analyzing Beam Monitoring Data.
 *
 * This object accepts spill data and maintains a pipeline of
 * BDProcessors each of which visits this data and should analyze one
 * specific element of the beam monitoring data and store the result
 * for later use by others.
 *
 * \note It is intended for use in the beam monitoring DBU process the
 * shift Online Monitor shift histogram generator and the ntupler, but
 * may be useful for general analysis of BeamMon RawData files.
 *
 * \author (last to touch it) $Author: minoscvs $
 *
 * \version $Revision: 1.3 $
 *
 * \date $Date: 2005/04/26 20:54:24 $
 *
 * Contact: bv@bnl.gov
 *
 * Created on: Fri Apr 15 09:57:33 2005
 *
 * $Id: BDPipeline.h,v 1.3 2005/04/26 20:54:24 minoscvs Exp $
 *
 */
#ifndef BDPIPELINE_H
#define BDPIPELINE_H

class RawBeamMonBlock;
class RawBeamMonHeaderBlock;

class BDProcessor;

class MomNavigator;

#include <vector>

class BDPipeline {
public:

    BDPipeline();
    ~BDPipeline();

    /// A collection of spill processors
    typedef std::vector<BDProcessor*> ProcessPipeline;

    /// Access the vector of spill processors read-write.  Any
    /// BDProcessors added become owned by the pipeline and will be
    /// delete when this object is destroyed.
    ProcessPipeline& GetProcessPipeline();

    /// Call each processors SetSpill.
    void SetSpill(const RawBeamMonHeaderBlock& rbmhb,
		  const RawBeamMonBlock& rbmb);

    /// Return the first processor of given type or 0 if not found.
    template <class ProcessorType> ProcessorType* GetProcessor();

    /// Return Current Header Block, can be zero.
    const RawBeamMonHeaderBlock* GetHeaderBlock() const;

    /// Return current payload block, can be zero.
    const RawBeamMonBlock* GetPayloadBlock() const;

private:

    ProcessPipeline fPipe;
    const RawBeamMonBlock* fPayloadBlock;
    const RawBeamMonHeaderBlock* fHeaderBlock;
};

template <class ProcessorType> 
ProcessorType* BDPipeline::GetProcessor()
{
    for (size_t ind=0; ind<fPipe.size(); ++ind) {
        ProcessorType* p = dynamic_cast<ProcessorType*>(fPipe[ind]);
        if (p) return p;
    }
    return 0;
}
#endif  //  BDPIPELINE_H

