// cspamNode.h
//
// This node contains all of the cspam register information.
//
// There are 4 patterns of 10 words.
// patternHi1 and Hi0 contain the high threshold data for the combined tank ends
// patternLo1 and Lo0 contain the Low threshold data for the combined tank ends
//
// The Hi threshold data corresponds to the HIPT which has a 10usec window
// The Lo threshold data corresponds to both the CSPAM trigger, and FMT
// (the cspam has a coincidence windo of 1usec,
//  the FMT has a coincidence window of 10usec, and is vetoed on the CSPAM)
//
// To figure out what is what (particularly to figure out which trigger
// read out which waveforms, you also need additional data, like the 
// SPU or TPU
//
// VER 2: The SPU node only had the first of 3 equip 32 words
//        and the HIP hit info is in the 2nd word 
//        So I have added trigger info for HIP, FMT, CSPAM
//        CMO, Jun23,1996

#include <BitString.h>

extern short BitStringtoshort(BitString);
static F_NodeType cspamType = "CSPM";
static int iSM;
static const int CSPAM=0;
static const int FMT=1;
static const int HIP=2;

class cspamNode : public F_Node {

public:

  cspamNode() { type = cspamType; version = 2;}
  
  unsigned char version;
  BitString patternHi1[10]; // indices 0-5 are info for each SM
  BitString patternHi0[10]; // indices 6-10 are the inter-SM data
  BitString patternLo1[10];
  BitString patternLo0[10];
  short shortHi1[10];
  short shortHi0[10];
  short shortLo1[10];
  short shortLo0[10];

  // the new patterns are defined like this:
  // bit 0: SM12
  // bit 1: SM23 as seen by mvax1
  // bit 2: SM23 as seen by mvax2
  // bit 3: SM34
  // bit 4: SM45 as seen by mvax2
  // bit 5: SM45 as seen by mvax3
  // bit 6: SM56

  short fmtHitPattern;
  short hipHitPattern;
  short cspamHitPattern;
  virtual inline void print(ostream& o)
  {
    BitString trigFmt=shorttoBitString(fmtHitPattern);
    BitString trigHip=shorttoBitString(hipHitPattern);
    BitString trigCspam=shorttoBitString(cspamHitPattern);
    o << "Cspam Node   version:" << (short) version << endl << endl;
    o << "Trigger Patterns:" << endl;
    o << "      1223445C" << endl;
    o << "      2334556M" << endl;
    o << "==============" << endl;
    o << "  FMT|";
    trigFmt.printon(o,' ','*');
    o<< endl;
    o << "  HIP|";
    trigHip.printon(o,' ','*');
    o<< endl;
    o << "CSPAM|";
    trigCspam.printon(o,' ','*');
    o<< endl;
    o << "High Trigger Data                       Low Trigger Data" << endl;
    o << "0H bBcCtTwWeEnN    |1H bBcCtTwWeEnN    |";
    o << "0L bBcCtTwWeEnN    |1L bBcCtTwWeEnN     " << endl;
    o << "===================|===================|";
    o << "===================|===================" << endl;
    for (iSM=0; iSM<10; iSM++)
    {
      patternHi1[iSM] = shorttoBitString(shortHi1[iSM]);
      patternHi0[iSM] = shorttoBitString(shortHi0[iSM]);
      patternLo1[iSM] = shorttoBitString(shortLo1[iSM]);
      patternLo0[iSM] = shorttoBitString(shortLo0[iSM]);

      if(iSM<6)
      {
	o << iSM+1 << "  ";
	patternHi0[iSM].printon(o,' ','*');
	o << "| " << "  ";
	patternHi1[iSM].printon(o,' ','*');
	o << "| " << "  ";
	patternLo0[iSM].printon(o,' ','*');
	o << "| " << "  ";
	patternLo1[iSM].printon(o,' ','*');
	o << endl;
      }
      if(iSM==6)
      {
	o << "Inter Super Module Data" << endl;
	o << "0H bBcCtTwWeE      |1H bBcCtTwWeE      |";
	o << "0L bBcCtTwWeE      |1L bBcCtTwWeE    " << endl;
	o << "===================|===================|";
	o << "===================|=================" << endl;
      }
      if(iSM>=6)
      {
	o << iSM-4 << "  ";
	patternHi0[iSM].printon(o,' ','*');
	o << "| " << "  ";
	patternHi1[iSM].printon(o,' ','*');
	o << "| " << "  ";
	patternLo0[iSM].printon(o,' ','*');
	o << "| " << "  ";
	patternLo1[iSM].printon(o,' ','*');
	o << endl;
      }
    }
    cout << endl;
  }
  virtual inline int fmtHit(int unit)
  {
    // send either 0-7 as described above for the patterns,
    // or send 12,23, etc.
    if(unit<0)return 0;
    if(unit<8)
    {
      return (fmtHitPattern&(1<<unit));
    }
    if(unit==12)return (fmtHitPattern&0x1);
    if(unit==23)return (fmtHitPattern&0x2 || fmtHitPattern&0x4);
    if(unit==34)return (fmtHitPattern&0x8);
    if(unit==45)return (fmtHitPattern&0x10 || fmtHitPattern&0x20);
    if(unit==56)return (fmtHitPattern&0x40);
    return 0;
  }
  virtual inline int hipHit(int unit)
  {
    // send either 0-7 as described above for the patterns,
    // or send 12,23, etc.
    if(unit<0)return 0;
    if(unit<8)
    {
      return (hipHitPattern&(1<<unit));
    }
    if(unit==12)return (hipHitPattern&0x0001);
    if(unit==23)return (hipHitPattern&0x0002 || hipHitPattern&0x0004);
    if(unit==34)return (hipHitPattern&0x0008);
    if(unit==45)return (hipHitPattern&0x0010 || hipHitPattern&0x0020);
    if(unit==56)return (hipHitPattern&0x0040);
    return 0;
  }
  virtual inline int cspamHit(int unit)
  {
    // send either 0-7 as described above for the patterns,
    // or send 12,23, etc.
    if(unit<0)return 0;
    if(unit<8)
    {
      return (cspamHitPattern&(1<<unit));
    }
    if(unit==12)return (cspamHitPattern&0x1);
    if(unit==23)return (cspamHitPattern&0x2 || cspamHitPattern&0x4);
    if(unit==34)return (cspamHitPattern&0x8);
    if(unit==45)return (cspamHitPattern&0x10 || cspamHitPattern&0x20);
    if(unit==56)return (cspamHitPattern&0x40);
    return 0;
  }
protected:
  
  virtual inline void IOData(iostream& file, F_inout choice,
			     F_length& nodeLength)
  {
    F_IORec(file,version,choice,nodeLength);
    for (iSM = 0; iSM < 10; iSM++)
    {
      // this is included because dreamMake uses only bitstrings
      if (choice==out)
      {
	shortHi0[iSM]=BitStringtoshort(patternHi0[iSM]);
	shortHi1[iSM]=BitStringtoshort(patternHi1[iSM]);
	shortLo0[iSM]=BitStringtoshort(patternLo0[iSM]);
	shortLo1[iSM]=BitStringtoshort(patternLo1[iSM]);
      }
      
      F_IORec(file,shortHi0[iSM],choice,nodeLength);
      F_IORec(file,shortHi1[iSM],choice,nodeLength);
      F_IORec(file,shortLo0[iSM],choice,nodeLength);
      F_IORec(file,shortLo1[iSM],choice,nodeLength);
      
      if(choice==in)
      {
	patternHi1[iSM] = shorttoBitString(shortHi1[iSM]);
	patternHi0[iSM] = shorttoBitString(shortHi0[iSM]);
	patternLo1[iSM] = shorttoBitString(shortLo1[iSM]);
	patternLo0[iSM] = shorttoBitString(shortLo0[iSM]);
      }
    }
    if(version>1)
    {
      F_IORec(file,fmtHitPattern,choice,nodeLength);
      F_IORec(file,hipHitPattern,choice,nodeLength);
      F_IORec(file,cspamHitPattern,choice,nodeLength);
    }      
  }
  
};

  inline F_Node* newCspamNode() {return new cspamNode;}
  static F_classDeclare declareCSPM(cspamType,newCspamNode);
