#include "BDSwicMaskAccessor.h"

#include "BeamMonSwicMask.h"
#include "BeamMonSwicRel.h"


#include <DatabaseInterface/DbiResultKey.h>

#include <MessageService/MsgService.h>
CVSID("$Id: BDSwicMaskAccessor.cxx,v 1.4 2005/12/14 21:03:20 bv Exp $");


#include <DatabaseInterface/DbiResultPtr.tpl>
template class  DbiResultPtr<BeamMonSwicMask>;
template class  DbiResultPtr<BeamMonSwicRel>;

using namespace std;

BDSwicMaskAccessor::BDSwicMaskAccessor()
    : fMaskResPtr(new DbiResultPtr<BeamMonSwicMask>)
    , fRelResPtr(new DbiResultPtr<BeamMonSwicRel>)
    , fMaskResKey(0), fRelResKey(0)
{
}
BDSwicMaskAccessor::~BDSwicMaskAccessor()
{
    if (fMaskResPtr) delete fMaskResPtr;
    if (fRelResPtr)  delete fRelResPtr;
    fMaskResPtr = 0;
    fRelResPtr = 0;
    fMaskResKey = fRelResKey = 0;
}

void BDSwicMaskAccessor::AddDevice(const char* device_name)
{
    if (fSwicMap.find(device_name) != fSwicMap.end()) return;

    Device dev;
    dev.mask = vector<double>(96,1);
    dev.rel  = vector<double>(96,1);
    dev.prod  = vector<double>(96,1);
    fSwicMap[device_name] = dev;
}


void BDSwicMaskAccessor::Reset()
{
    SwicMap::iterator it, done = fSwicMap.end();
    for (it=fSwicMap.begin(); it != done; ++it) {
	it->second.mask = vector<double>(96,1);
	it->second.rel  = vector<double>(96,1);
	it->second.prod = vector<double>(96,1);
    }
}


bool BDSwicMaskAccessor::SetSpillTime(VldContext vc)
{

    bool tf1 = true;		// db hit?
    int nrows1 = fMaskResPtr->NewQuery(vc,0,true);
    const DbiResultKey* result_key1 = fMaskResPtr->GetKey();
    if (fMaskResKey && result_key1->IsEqualTo(fMaskResKey)) tf1=false;

    bool tf2 = true;		// db hit?
    int nrows2 = fRelResPtr->NewQuery(vc,0,true);
    const DbiResultKey* result_key2 = fRelResPtr->GetKey();
    if (fRelResKey && result_key2->IsEqualTo(fRelResKey)) tf2=false;

    if (!tf1 && !tf2) return false;


    fMaskResKey = result_key1;
    fRelResKey = result_key2;

    this->Reset();

    if (tf1) {
	for (int row=0; row<nrows1; ++row) {
	    const BeamMonSwicMask* mask = fMaskResPtr->GetRow(row);
	    string name = mask->GetDeviceName();
	    SwicMap::iterator it = fSwicMap.find(name);
	    if (it == fSwicMap.end()) {
		MSG("BD",Msg::kDebug) << "No Device for "
				      << name << ", continuing\n";
		continue;
	    }
	    int ind = mask->GetOffset();
	    it->second.mask[ind] = mask->GetMask();
	}
    }
    if (tf2) {
	for (int row=0; row<nrows2; ++row) {
	    const BeamMonSwicRel* rel = fRelResPtr->GetRow(row);
	    string name = rel->GetDeviceName();
	    SwicMap::iterator it = fSwicMap.find(name);
	    if (it == fSwicMap.end()) {
		MSG("BD",Msg::kDebug) << "No Device for " 
				      << name << ", continuing\n";
		continue;
	    }
	    it->second.rel = rel->GetChannelsAsDoubles();
	}
    }

    SwicMap::iterator it, done = fSwicMap.end();
    for (it=fSwicMap.begin(); it != done; ++it)
	for (int ind=0; ind<96; ++ind)
	    it->second.prod[ind] = it->second.mask[ind]*it->second.rel[ind];
    
    return true;
}

const vector<double>& BDSwicMaskAccessor::GetMask(const char* device_name) const
{
    static vector<double> looser;

    SwicMap::const_iterator it = fSwicMap.find(device_name);
    if (it == fSwicMap.end()) return looser;

    return it->second.prod;
}
