#include "TMConfigureDate.h"
#include "SPDMood.h"
#include "TMAbout.h"
#include <TGFileDialog.h>

ClassImp(TMConfigureDate)

//___________________________________________________________________________________
TMConfigureDate::TMConfigureDate(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,1,1,1,1);
  fLayout4 = new TGLayoutHints(kLHintsBottom | kLHintsExpandX,10,10,10,10);
  fLayout5 = new TGLayoutHints(kLHintsTop | kLHintsExpandX,10,10,10,10);

  EEvents dateIDs[] = {CONF_DECLARE, CONF_SWAP16, CONF_SWAP32, CONF_NOWAIT };
  Char_t *dateLabels[] = {"Declare M.P.","SwAp 16-Bit","SwAp 32-Bit","Set NoWait"};
	
  fTop = new TGGroupFrame(this, "DATE Configuration", kHorizontalFrame);
  fTop->SetTitlePos(TGGroupFrame::kCenter);

  fFpart[0] = new TGCompositeFrame(fTop, 500,100, kVerticalFrame);
  fFpart[1] = new TGCompositeFrame(fTop, 100,100, kVerticalFrame);
  fTop->AddFrame(fFpart[0], fLayout5);
  fTop->AddFrame(fFpart[1], fLayout5);
  this->AddFrame(fTop, fLayout);

  fF0[0] = new TGButtonGroup(fFpart[0],"Event Type",kHorizontalFrame);
  fRadio[0]=new TGRadioButton(fF0[0], "PHY", CONF_PHYS);
  fRadio[1]=new TGRadioButton(fF0[0], "CAL", CONF_CALIB);
  fF0[0]->Show();
  fFpart[0]->AddFrame(fF0[0], fLayout);

  fF0[1] = new TGButtonGroup(fFpart[0],"Monitoring Policy",kHorizontalFrame);
  fRadio[2]=new TGRadioButton(fF0[1], "all", CONF_ALL);
  fRadio[3]=new TGRadioButton(fF0[1], "yes", CONF_YES);
  fF0[1]->Show();
  fFpart[0]->AddFrame(fF0[1], fLayout);

  for (Int_t i=0 ; i<4 ; i++) {
    fF[i] = new TGCompositeFrame(fFpart[1], 100,100, kHorizontalFrame);
    fFpart[1]->AddFrame(fF[i], fLayout);
    fCheck[i] = new TGCheckButton(fF[i], dateLabels[i], dateIDs[i]);
    fF[i]->AddFrame(fCheck[i], 0);
  }

  fRadio[0]->SetState(kButtonUp);
  fRadio[1]->SetState(kButtonUp);
  switch (o.eventType) {
  case 6:
    fRadio[0]->SetState(kButtonDown);
    break;
  case 7:
    fRadio[1]->SetState(kButtonDown);
    break;
  default:
    fRadio[0]->SetState(kButtonDown);
    break;
  }

  fRadio[2]->SetState(kButtonUp);
  fRadio[3]->SetState(kButtonUp);
  switch (o.monitoringPolicy) {
  case 0:
    fRadio[2]->SetState(kButtonDown);
    break;
  case 1:
    fRadio[3]->SetState(kButtonDown);
    break;
  default:
    fRadio[2]->SetState(kButtonDown);
    break;
  }
  
  if (o.declareMonitor == kTRUE) fCheck[0]->SetState(kButtonDown);
  else fCheck[0]->SetState(kButtonUp);
  if (o.swap16         == kTRUE) fCheck[1]->SetState(kButtonDown);
  else fCheck[1]->SetState(kButtonUp);
  if (o.swap32         == kTRUE) fCheck[2]->SetState(kButtonDown);
  else fCheck[2]->SetState(kButtonUp);
  if (o.setNowait      == kTRUE) fCheck[3]->SetState(kButtonDown);
  else fCheck[3]->SetState(kButtonUp);

  fF[6] = new TGCompositeFrame(this, 10,10, kHorizontalFrame);
  this->AddFrame(fF[6], fLayout);
  fF[7] = new TGCompositeFrame(this, 10,10, kHorizontalFrame);
  this->AddFrame(fF[7], fLayout);

  fText[0] = new TGTextEntry(fF[7], o.dataSourceFullPath.Data(), CONF_TEXT0);
  fText[0]->Associate(this);
  fText[1] = new TGTextEntry(fF[6], o.nameOfMp, CONF_TEXT1);
  fText[1]->Associate(this);
  fButton = new TGPictureButton(fF[7], fClient->GetPicture("folder_t.xpm"), BUTTON_CONF);
  fButton->SetToolTipText("Data file full path for OFF-LINE.", 0);
  fButton->Associate(this);
  Char_t questionMarkPath[300];
  sprintf(questionMarkPath, "%s/src/images/question.xpm", getenv("SPDMOOD_SITE"));
  fButtonInfo = new TGPictureButton(fF[7],questionMarkPath , BUTTON_INFO);
  fButtonInfo->SetToolTipText("Syntax of defining a remote monitoring source.", 0);
  fButtonInfo->Associate(this);
  Char_t downPath[300];
  sprintf(downPath, "%s/src/images/arrowdown.xpm", getenv("SPDMOOD_SITE"));
  fBSourceDown = new TGPictureButton(fF[7],downPath , B_SOURCE_DOWN);
  fBSourceDown->SetToolTipText("Decrease...", 0);
  fBSourceDown->Associate(this);
  Char_t upPath[300];
  sprintf(upPath, "%s/src/images/arrowup.xpm", getenv("SPDMOOD_SITE"));
  fBSourceUp = new TGPictureButton(fF[7],upPath , B_SOURCE_UP);
  fBSourceUp->SetToolTipText("Increase...", 0);
  fBSourceUp->Associate(this);
  fF[7]->AddFrame(fButton, fLayout3);
  fF[7]->AddFrame(fButtonInfo, fLayout3);
  fF[7]->AddFrame(fText[0], fLayout);
  fF[7]->AddFrame(fBSourceDown, fLayout3);
  fF[7]->AddFrame(fBSourceUp, fLayout3);

  fLabel = new TGLabel(fF[6], "Declare Session as : ");
  fF[6]->AddFrame(fLabel, fLayout);
  fF[6]->AddFrame(fText[1], fLayout);

  fF[9] = new TGCompositeFrame(this, 10,10, kHorizontalFrame);
  this->AddFrame(fF[9], fLayout);
  fMultiple = new TGButtonGroup(fF[9],"Include following run segment files?",kHorizontalFrame);
  fRadioMult[0]=new TGRadioButton(fMultiple, "yes", CONF_MULT0);
  fRadioMult[1]=new TGRadioButton(fMultiple, "no", CONF_MULT1);
  fMultiple->Show();
  fF[9]->AddFrame(fMultiple, fLayout);
  fRadioMult[0]->SetState(kButtonUp);
  fRadioMult[1]->SetState(kButtonUp);
  switch (o.multipleFiles) {
  case kTRUE:
    fRadioMult[0]->SetState(kButtonDown);
    break;
  case kFALSE:
    fRadioMult[1]->SetState(kButtonDown);
    break;
  default:
    fRadioMult[0]->SetState(kButtonDown);
    break;
  }

  fF[10] = new TGCompositeFrame(this, 10,10, kHorizontalFrame);
  this->AddFrame(fF[10], fLayout);
  fMultipleType = new TGButtonGroup(fF[10],"Type of files",kVerticalFrame);
  fRadioMultType[0]=new TGRadioButton(fMultipleType, "08000031156003.10.date", CONF_MULTTYPE0);
  fRadioMultType[1]=new TGRadioButton(fMultipleType, "run31156.000", CONF_MULTTYPE1);
  fMultipleType->Show();
  fF[10]->AddFrame(fMultipleType, fLayout);
  fRadioMultType[0]->SetState(kButtonUp);
  fRadioMultType[1]->SetState(kButtonUp);
  switch (o.multipleFileType) {
  case kTRUE:
    fRadioMultType[0]->SetState(kButtonDown);
    break;
  case kFALSE:
    fRadioMultType[1]->SetState(kButtonDown);
    break;
  default:
    fRadioMultType[0]->SetState(kButtonDown);
    break;
  }
    
  fF[8] = new TGCompositeFrame(this, 100, 100, kHorizontalFrame);
  this->AddFrame(fF[8], fLayout);
  fTextB[0] = new TGTextButton(fF[8], "Apply", BUTTON_APPLY);
  fTextB[0]->Associate(this);
  fTextB[1] = new TGTextButton(fF[8], "Close", BUTTON_CANCEL);
  fTextB[1]->Associate(this);
  fTextB[2] = new TGTextButton(fF[8], "Help", BUTTON_HELP);
  fTextB[2]->Associate(this);
  fF[8]->AddFrame(fTextB[0], fLayout2);
  fF[8]->AddFrame(fTextB[1], fLayout2);
  fF[8]->AddFrame(fTextB[2], fLayout2);






  


  fLetUserCloseWindow = kFALSE;
    
  SetWindowName("DATE Configuration");
  MapSubwindows();
  Resize();
  MapWindow();
}

//___________________________________________________________________________________
TMConfigureDate::~TMConfigureDate() {
  // Destructor.
  delete fTop;
  delete[] fF;
  delete[] fF0;
  delete fMultiple;
  delete fMultipleType;
  delete[] fFpart;
  delete[] fCheck;
  delete[] fRadio;
  delete[] fRadioMult;
  delete[] fRadioMultType;
  delete[] fText;
  delete fButton;
  delete fBSourceUp;
  delete fBSourceDown;
  delete fButtonInfo;
  delete fLayout;
  delete fLayout2;
  delete fLayout3;
  delete fLayout4;
  delete fLayout5;
  delete fLabel;
  delete[] fTextB;
}
//___________________________________________________________________________________
void TMConfigureDate::MakeAssignment() {
  // Sets globals.
  if (kButtonDown == fRadio[0]->GetState())
    o.eventType = 6;
  else if (kButtonDown == fRadio[1]->GetState())
    o.eventType = 7;
  else 
    o.eventType = 6;
    
  if (kButtonDown == fRadio[2]->GetState())
    o.monitoringPolicy = 0;
  else if (kButtonDown == fRadio[3]->GetState())
    o.monitoringPolicy = 1;
  else 
    o.monitoringPolicy = 0;

  if (kButtonDown == fRadioMult[0]->GetState())
    o.multipleFiles = kTRUE;
  else if (kButtonDown == fRadioMult[1]->GetState())
    o.multipleFiles = kFALSE;
  else 
    o.multipleFiles = kFALSE;

  if (kButtonDown == fRadioMultType[0]->GetState())
    o.multipleFileType = kTRUE;
  else if (kButtonDown == fRadioMultType[1]->GetState())
    o.multipleFileType = kFALSE;
  else 
    o.multipleFileType = kFALSE;

  if (kButtonDown == fCheck[0]->GetState()) 
    o.declareMonitor = kTRUE;
  else 
    o.declareMonitor = kFALSE;
    
  if (kButtonDown == fCheck[1]->GetState()) 
    o.swap16 = kTRUE;
  else 
    o.swap16 = kFALSE;
    
  if (kButtonDown == fCheck[2]->GetState()) 
    o.swap32 = kTRUE;
  else 
    o.swap32 = kFALSE;
    
  if (kButtonDown == fCheck[3]->GetState()) 
    o.setNowait = kTRUE;
  else 
    o.setNowait = kFALSE;
    
  o.dataSourceFullPath = Form("%s", fText[0]->GetText());
  o.nameOfMp = Form("%s", fText[1]->GetText());

  //  gSTATUS->SetText(o.nameOfMp, 2);
}

//___________________________________________________________________________________
void TMConfigureDate::CloseWindow() {
  // Prevents usage of window manager close button.
  if (fLetUserCloseWindow == kFALSE) DontCallClose();
  else UnmapWindow();
}
//___________________________________________________________________________________
Bool_t TMConfigureDate::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_INFO :
	{
	  new TMAbout(gClient->GetRoot(), this, "REMOTESOURCE");
	  break;
	}
      case BUTTON_APPLY :
	{
	  MakeAssignment();
	  fLetUserCloseWindow = kTRUE;
	  SendMessage(fSPD, MK_MSG(kC_COMMAND,kCM_BUTTON), B_LOGIN2, 0);
	  CloseWindow();
	  break;
	}
      case BUTTON_CANCEL :
	{
	  fLetUserCloseWindow = kTRUE;
	  CloseWindow();
	  break;
	}
      case BUTTON_HELP :
	{
	  new TMAbout(gClient->GetRoot(), this, "README");
	  break;
	}
      case BUTTON_CONF :
	{
	  TGFileInfo fi;
	  const Char_t *filetypesMO[] = {
	    "DATE Files",               "*.date",
	    "Root Files",               "*.root",
	    "Raw Files",                "*.raw",
	    "All Files",                "*.*",
	    0,                          0
	  };
	  fi.fFileTypes = filetypesMO;
	  new TGFileDialog(fClient->GetRoot(), this, kFDOpen, &fi);
	  fText[0]->Clear();
	  Char_t fileName[100];
	  snprintf(fileName, sizeof(fileName), "%s", fi.fFilename);
	  fText[0]->SetText(fileName);
	  break;
	}
      case B_SOURCE_UP :
	{
	  IncrDataSource(1);
	  break;
	}
      case B_SOURCE_DOWN :
	{
	  IncrDataSource(-1);
	  break;
	}
      }
      break;
    }
  }
  return kTRUE;
}

void TMConfigureDate::IncrDataSource(Int_t amount) {
  TString old = Form("%s",fText[0]->GetText());
  TString newStr = "";

  if (kButtonDown == fRadioMultType[1]->GetState()) {
    Bool_t commafound=kFALSE;
    Int_t digitstart=-1;
    Int_t digitend=-1;
    Int_t i=0;
    while (i<old.Length()) {
      //      printf("%d: %c\n",i,old[i]);
      if (old[i]>=48 && old[i]<=57 && commafound==kFALSE) { // digit
	if (digitstart==-1) {
	  digitstart=i;
	}
      }
      else {
	if (old[i]=='.' && commafound==kFALSE) {
	  commafound=kTRUE;
	  if (digitstart>-1) {
	    digitend=i-1;
	    if (digitend - digitstart < 9) {
	      TString runNum = "";
	      Bool_t noZero=kFALSE;
	      for (Int_t j=digitstart; j<=digitend; j++) {
		if (old[j]==48 && noZero==kFALSE) {
		  newStr.Append(Form("%c",old[j]));
		}
		else {
		  noZero=kTRUE;
		  runNum.Append(Form("%c",old[j]));
		}
	      }
	      Int_t runNumber = atoi(runNum.Data());
	      runNumber+=amount;
	      newStr.Append(Form("%d",runNumber));
	    }
	    else {
	      for (Int_t j=digitstart; j<=digitend; j++) {
		newStr.Append(Form("%c",old[j]));
	      }
	    }
	  }
	}
	else {
	  if (digitstart>-1) {
	    digitend=i-1;
	    for (Int_t j=digitstart; j<=digitend; j++) {
	      newStr.Append(Form("%c",old[j]));
	    }
	  }
	}
	digitstart=-1;
	newStr.Append(Form("%c",old[i]));
      }
      i++;
    }
  }
  else {
    Bool_t commafound=kFALSE;
    Int_t digitstart=-1;
    Int_t digitend=-1;
    Int_t i=0;
    while (i<old.Length()) {
      //      printf("%d: %c\n",i,old[i]);
      if (old[i]>=48 && old[i]<=57 && commafound==kFALSE) { // digit
	if (digitstart==-1) {
	  digitstart=i;
	}
      }
      else {
	if (old[i]=='.' && commafound==kFALSE) {
	  commafound=kTRUE;
	  if (digitstart>-1) {
	    for (Int_t j=digitstart; j<digitstart+2; j++) {
	      newStr.Append(Form("%c",old[j]));
	    }
	    digitstart+=2;
	    digitend=i-4;
	    TString runNum = "";
	    Bool_t noZero=kFALSE;
	    for (Int_t j=digitstart; j<=digitend; j++) {
	      if (old[j]==48 && noZero==kFALSE) {
		newStr.Append(Form("%c",old[j]));
	      }
	      else {
		noZero=kTRUE;
		runNum.Append(Form("%c",old[j]));
	      }
	    }
	    Int_t runNumber = atoi(runNum.Data());
	    runNumber+=amount;
	    newStr.Append(Form("%d",runNumber));
	    if (i-3>=0) {
	      for (Int_t j=i-3; j<i; j++) {
		newStr.Append(Form("%c",old[j]));
	      }
	    }
	  }
	}
	else {
	  if (digitstart>-1) {
	    digitend=i-1;
	    for (Int_t j=digitstart; j<=digitend; j++) {
	      newStr.Append(Form("%c",old[j]));
	    }
	  }
	}
	digitstart=-1;
	newStr.Append(Form("%c",old[i]));
      }
      i++;
    }
  }

  fText[0]->SetText(newStr.Data());

}

