#include "TMConfigureSuppressErrors.h"
#include "TMConfig.h"
#include "TMAbout.h"
#include "SPDMood.h"
#include "AliITSRawStreamSPD.h"
#include "AliITSRawStreamSPDErrorLog.h"

ClassImp(TMConfigureSuppressErrors)

//___________________________________________________________________________________
TMConfigureSuppressErrors::TMConfigureSuppressErrors(const TGWindow *p, const TGWindow *main) : TGTransientFrame(gClient->GetRoot(), main, 500, 400, kVerticalFrame)
{
  // Constructor.
  fSPD = main;

  fLayout  = new TGLayoutHints(kLHintsCenterY | kLHintsExpandX,1,1,1,1);
  fLayout2 = new TGLayoutHints(kLHintsBottom | kLHintsExpandX,1,1,1,1);
  fLayout3 = new TGLayoutHints(kLHintsCenterY,10,10,10,10);
  fLayout4 = new TGLayoutHints(kLHintsBottom | kLHintsExpandX,10,10,10,10);
  fLayout5 = new TGLayoutHints(kLHintsExpandY | kLHintsExpandX,10,10,10,10);

  fTop = new TGGroupFrame(this, "Which errors should be suppressed:", kHorizontalFrame | kFixedSize);
  fTop->SetWidth(600);
  fTop->SetHeight(600);
  fTop->SetTitlePos(TGGroupFrame::kCenter);
  this->AddFrame(fTop, fLayout);

  UInt_t nrErrorCodes = AliITSRawStreamSPDErrorLog::GetNrErrorCodes();
  Int_t nr_cols=2;
  Int_t nr_rows = nrErrorCodes/nr_cols;
  if (nrErrorCodes%nr_cols>0) nr_rows++;
  fCheck = new TGCheckButton*[nrErrorCodes];
  fFrameCheck = new TGCompositeFrame*[nr_cols];
  UInt_t i=0;
  TGFrame* dummyFrame = NULL;
  if (nr_cols*nr_rows>(Int_t)nrErrorCodes) {
    dummyFrame = new TGFrame();
  }
  for (Int_t coli=0; coli<nr_cols; coli++) {
    fFrameCheck[coli] = new TGCompositeFrame(this, 10,10, kVerticalFrame);
    fTop->AddFrame(fFrameCheck[coli], fLayout5);
    for (Int_t rowi=0; rowi<nr_rows; rowi++) {
      if (i<nrErrorCodes) {
	UInt_t id = CHECK_0+i;
	TString label = Form("%d. %s",i,AliITSRawStreamSPD::GetErrorName(i));
	fCheck[i] = new TGCheckButton(fFrameCheck[coli], label.Data(), id);
	if (((TMConfig::Instance()->GETerrorSuppr()) >> i) & 0x1 == 0x1) fCheck[i]->SetState(kButtonDown);
	else fCheck[i]->SetState(kButtonUp);
	fFrameCheck[coli]->AddFrame(fCheck[i], fLayout5);
      }
      else {
	fFrameCheck[coli]->AddFrame(dummyFrame, fLayout5);
      }
      i++;
    }
  }



  fFrameButtons[0] = new TGCompositeFrame(this, 100, 100, kHorizontalFrame);
  this->AddFrame(fFrameButtons[0], fLayout);
  fTextBall[0] = new TGTextButton(fFrameButtons[0], "Set All", BUTTON_SETALL);
  fTextBall[0]->Associate(this);
  fTextBall[1] = new TGTextButton(fFrameButtons[0], "Clear All", BUTTON_CLEARALL);
  fTextBall[1]->Associate(this);
  fFrameButtons[0]->AddFrame(fTextBall[0], fLayout2);
  fFrameButtons[0]->AddFrame(fTextBall[1], fLayout2);

  fFrameButtons[1] = new TGCompositeFrame(this, 100, 100, kHorizontalFrame);
  this->AddFrame(fFrameButtons[1], fLayout);
  fTextB[0] = new TGTextButton(fFrameButtons[1], "Apply", BUTTON_APPLY);
  fTextB[0]->Associate(this);
  fTextB[1] = new TGTextButton(fFrameButtons[1], "Close", BUTTON_CANCEL);
  fTextB[1]->Associate(this);
  fTextB[2] = new TGTextButton(fFrameButtons[1], "Help", BUTTON_HELP);
  fTextB[2]->Associate(this);
  fFrameButtons[1]->AddFrame(fTextB[0], fLayout2);
  fFrameButtons[1]->AddFrame(fTextB[1], fLayout2);
  fFrameButtons[1]->AddFrame(fTextB[2], fLayout2);




  fLetUserCloseWindow = kFALSE;

  SetWindowName("Suppress Errors");
  MapSubwindows();
  Resize();
  MapWindow();
}

//___________________________________________________________________________________
TMConfigureSuppressErrors::~TMConfigureSuppressErrors()
{
  // Destructor.
  delete fTop;
  delete fLayout;
  delete fLayout2;
  delete fLayout3;
  delete fLayout4;
  delete fLayout5;
  delete[] fCheck;
  delete[] fFrameCheck;
  delete[] fTextB;
  delete[] fTextBall;
}

//___________________________________________________________________________________
void TMConfigureSuppressErrors::MakeAssignment() {
  Int_t value = 0;
  for (UInt_t i=0; i<AliITSRawStreamSPDErrorLog::GetNrErrorCodes(); i++) {
    if (kButtonDown == fCheck[i]->GetState()) { 
      value += (0x1 << i);
    }
  }
  TMConfig::Instance()->SETerrorSuppr(value);
}

//___________________________________________________________________________________
void TMConfigureSuppressErrors::CloseWindow()
{
  // Prevents usage of window manager close button.

  if (fLetUserCloseWindow == kFALSE)
    DontCallClose();
  else
    //DestroyWindow();
    UnmapWindow();
}

//___________________________________________________________________________________
Bool_t TMConfigureSuppressErrors::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
{
  // Event handler function.

  switch(GET_MSG(msg)) {
  case kC_COMMAND :
    switch (GET_SUBMSG(msg)) {
    case kCM_BUTTON :
      switch (parm1) {
      case BUTTON_APPLY :
	{
	  MakeAssignment();
	  fLetUserCloseWindow = kTRUE;
	  SendMessage(fSPD, MK_MSG(kC_COMMAND,kCM_BUTTON), UPDATE_SUPPRERROR, 0);
	  CloseWindow();
	  break;
	}
      case BUTTON_CANCEL :
	{
	  fLetUserCloseWindow = kTRUE;
	  CloseWindow();
	  break;
	}
      case BUTTON_HELP :
	{
	  new TMAbout(gClient->GetRoot(), this, "README");
	  break;
	}
      case BUTTON_SETALL :
	{
	  for (UInt_t i=0; i<AliITSRawStreamSPDErrorLog::GetNrErrorCodes(); i++) {
	    fCheck[i]->SetState(kButtonDown);
	  }
	  break;
	}
      case BUTTON_CLEARALL :
	{
	  for (UInt_t i=0; i<AliITSRawStreamSPDErrorLog::GetNrErrorCodes(); i++) {
	    fCheck[i]->SetState(kButtonUp);
	  }
	  break;
	}
      }
      break;
    }
  }
  return kTRUE;
}
