#include "BeamMonBaseModule.h"

#include <MessageService/MsgService.h>

#include <RawData/RawRecord.h>
#include <RawData/RawBeamMonBlock.h>
#include <RawData/RawBeamMonHeaderBlock.h>
#include <RawData/RawBeamData.h>

#include <DataUtil/GetRecords.h>
#include <HistMan/HistMan.h>

#include <Conventions/Munits.h>

#include <TGraph.h>
#include <TCanvas.h>

#include <vector>

//ClassImp(BeamMonBaseModule)

using namespace std;

CVSID("$Id: BeamMonBaseModule.cxx,v 1.6 2005/05/31 21:24:01 thosieck Exp $");

BeamMonBaseModule::BeamMonBaseModule()
{
}

BeamMonBaseModule::~BeamMonBaseModule()
{
}

template<class BlockType>
const BlockType* get_block(const RawRecord& rr)
{
    TIter itr = rr.GetRawBlockIter();
    const RawDataBlock* rdb = 0;

    // loop over blocks in record
    while ((rdb = dynamic_cast<RawDataBlock*>(itr()))) {
        const BlockType *block =  dynamic_cast<const BlockType*>(rdb);
        if (block) return block;
    }
    return 0;
}

HistMan BeamMonBaseModule::GetHistMan()
{
    const char* folder = "Monitoring";
    this->GetConfig().Get("folder",folder);
    return HistMan(folder);
}

JobCResult BeamMonBaseModule::Ana(const MomNavigator *mom)
{
    vector<const RawRecord*> rrv = DataUtil::GetRecords<const RawRecord>(mom);
    const RawBeamMonBlock* block = 0;
    const RawBeamMonHeaderBlock* head = 0;

    for (size_t ind=0; ind<rrv.size(); ++ind) {
	const RawRecord* rr = rrv[ind];
        string stream_name = rr->GetTempTags().GetCharString("stream");
	MSG("BD",Msg::kVerbose)
	    << "Found stream: " << stream_name << endl;

	const RawBeamMonBlock* b = get_block<RawBeamMonBlock>(*rr);
	if (b) block=b;
	const RawBeamMonHeaderBlock* h = get_block<RawBeamMonHeaderBlock>(*rr);
	if (h) head=h;
    }
    if (! (block && head)) {
	MSG("BD",Msg::kWarning)
	    << "BeamMonBaseModule::Ana: failed to find both header and payload blocks\n";
	return JobCResult::kFailed;
    }

    this->Fill(*head,*block);

    return JobCResult::kAOK;
}


const Registry& BeamMonBaseModule::DefaultConfig() const
{
    return DefaultConfigWritable();
}

Registry& BeamMonBaseModule::DefaultConfigWritable() const
{
    if (fConfig.Size() == 0) {
	fConfig.Set("folder","Monitoring");
    }
    return fConfig;
}

