//
//
//
#define  START_DIRECTORY  "/dat1"
#define S_ISDIR(m) (((m)&(0170000)) == (0040000))  

#include <TApplication.h>
#include <TGMsgBox.h>

#include "MainFrameSimone.hxx"



MainFrameSimone::MainFrameSimone(const TGWindow *p, UInt_t w, UInt_t h)
    : TGMainFrame(p, w, h)
{
  sprintf (fInputPath, "\0" ) ; 
  fNumEvents = 0 ; 
  
  fNtup = new TNtuple ("fNtup", "Ntuple with Run distributions", 
		       "PartID:Energy:CoreX:CoreY") ; 
  //
  // Create a main frame with a number of different buttons.
  //

  //
  // First create the MenuBar. 
  //

  fLayMenuBar = new TGLayoutHints ( kLHintsTop | kLHintsLeft | kLHintsExpandX,
				    2, 2, 2, 2 ) ; 
  fLayMenuItem = new TGLayoutHints ( kLHintsTop | kLHintsLeft ,
				     0, 4, 0, 0 ) ; 

  
  fFileMenu = new TGPopupMenu ( fClient->GetRoot() ) ; 
  fFileMenu->AddEntry ("Exit", M_FILE_EXIT ) ; 

  //
  //  the button messages are handled by main frame (this) 
  //
  fFileMenu->Associate(this) ; 


  fMenuBar = new TGMenuBar ( this, 1, 1, kHorizontalFrame ) ; 
  fMenuBar->AddPopup("File", fFileMenu, fLayMenuItem ) ; 
  
  AddFrame(fMenuBar, fLayMenuBar ) ; 


  //
  // create the Tab 
  //

  fFrame = new TGCompositeFrame (this, 300,300, kHorizontalFrame ) ; 
  
  fLayTab = new TGLayoutHints ( kLHintsTop | kLHintsLeft | kLHintsExpandX  , 5, 5, 5, 5 ) ; 
  fTab = new TGTab ( fFrame, 400, 400 ) ; 
  
  TGCompositeFrame *tf = fTab->AddTab("Input") ; 
  fTabF1 = new TGCompositeFrame (tf, 100, 100, kHorizontalFrame) ; 

  tf->AddFrame(fTabF1, fLayTab ) ; 

  fTabF1a = new TGCompositeFrame (tf, 100, 100, kHorizontalFrame) ; 
  tf->AddFrame(fTabF1a,  new TGLayoutHints ( kLHintsTop | kLHintsLeft | kLHintsExpandX, 5, 5, 5, 5 ) ) ; 

  fTabF1b = new TGCompositeFrame (tf, 100, 100, kVerticalFrame) ; 
  tf->AddFrame(fTabF1b,  new TGLayoutHints ( kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY  , 5, 5, 5, 5 ) ) ; 

  fDir = new TGListBox(fTabF1, -1) ; 
  fDir->Resize(350,20) ; 
  char temp[100] ; 
  //  sprintf ( temp, "%s", START_DIRECTORY ) ; 
  sprintf ( temp, "%s", gSystem->WorkingDirectory()  ) ; 
  fDir->AddEntry(temp, 1) ; 
  fTabF1->AddFrame( fDir, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 5, 5, 5, 5 ) ) ; 


  fPicCdup = fClient->GetPicture("tb_uplevel.xpm") ; 
  fCdup = new TGPictureButton(fTabF1, fPicCdup, M_CDIR_UP ) ; 
  fCdup->SetToolTipText("One Level up!") ; 
  fCdup->Associate(this) ; 
  fTabF1->AddFrame (fCdup, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 5, 5, 5) ) ; 

  fPicList = fClient->GetPicture("tb_list.xpm") ; 
  fListMode = new TGPictureButton(fTabF1, fPicList, M_LIST_MODE ) ; 
  fListMode->SetToolTipText("List Mode") ; 
  fListMode->Associate(this) ; 
  fListMode->SetState(kButtonUp) ; 
  fListMode->AllowStayDown(kTRUE) ; 
  fTabF1->AddFrame (fListMode, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 5, 5, 5) ) ; 

  fPicDetail = fClient->GetPicture("tb_details.xpm") ; 
  fDetail = new TGPictureButton(fTabF1, fPicDetail, M_DETAIL_MODE ) ; 
  fDetail->SetToolTipText("Details Mode") ; 
  fDetail->Associate(this) ; 
  fDetail->SetState(kButtonEngaged) ; 
  fDetail->AllowStayDown(kTRUE) ; 
  fTabF1->AddFrame (fDetail, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 5, 5, 5) ) ; 

  
  fSelectButton = new TGTextButton(fTabF1b, "Select", M_BUTTON_SELECT );
  fSelectButton->SetToolTipText("To select a path with Mmcs data files!");
  fSelectButton->SetState(kButtonDisabled); 
  fSelectButton->Associate(this) ; 

  fTabF1b->AddFrame(fSelectButton,
		    new TGLayoutHints(kLHintsTop | kLHintsCenterX, 5, 5, 5, 5) ) ; 
  
  fFileView = new TGListView(fTabF1b, 540, 380 ) ; 
  fFileCont = new TGFileContainer(fFileView->GetViewPort(), 100, 100,
				  kVerticalFrame, fgWhitePixel) ; 

  fFileCont->Associate(this) ; 
  fFileView->GetViewPort()->SetBackgroundColor(fgWhitePixel) ; 
  fFileView->SetContainer(fFileCont) ; 
  fFileCont->SetFilter("*") ; 
  //  fFileCont->ChangeDirectory(START_DIRECTORY) ; 
  fFileCont->ChangeDirectory(gSystem->WorkingDirectory()) ; 
  fFileView->SetViewMode(kLVDetails); 
  fFileCont->Sort(kSortByName) ; 
  
  fTabF1b->AddFrame(fFileView, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 5, 5, 5, 5) ) ; 

  //
  //  create Tab 2 
  //

  tf = fTab->AddTab("Run Dist") ; 
  fTabF2 = new TGCompositeFrame (tf, 100, 100, kVerticalFrame) ; 
  
  tf->AddFrame(fTabF2,  new TGLayoutHints(kLHintsTop | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5)) ; 

  //  create the vertical subframes

  fTabF2a = new TGCompositeFrame (fTabF2, 100, 100, kHorizontalFrame) ; 
  fTabF2->AddFrame(fTabF2a, fLayTab ) ; 

  fTabF2b = new TGCompositeFrame (fTabF2, 300, 300, kHorizontalFrame) ; 
  fTabF2->AddFrame(fTabF2b, 
		   new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX |kLHintsExpandY, 5, 5, 5, 5 ) ) ; 

  fTabF2c = new TGCompositeFrame (fTabF2, 100, 100, kHorizontalFrame) ; 
  fTabF2->AddFrame(fTabF2c,new TGLayoutHints(kLHintsBottom | kLHintsLeft | kLHintsExpandX, 5, 5, 5, 5 )  ) ; 

  //  create the entries in first subframe

  fLabelInput = new TGLabel(fTabF2a, new TGString("Title:") );       
  fTabF2a->AddFrame( fLabelInput, new TGLayoutHints(kLHintsTop | kLHintsLeft , 5, 5, 5, 5 ) ) ;   

  fDir2 = new TGListBox(fTabF2a, -1) ; 
  fDir2->Resize(350,20) ; 
  sprintf ( temp, "%s", fInputPath ) ; 
  fDir2->AddEntry(temp, 1) ; 
  fTabF2a->AddFrame( fDir2, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5 ) ) ; 
  
  fLabelNumEvts = new TGLabel(fTabF2a, new TGString("Number of Events:") );       
  fTabF2a->AddFrame( fLabelNumEvts, new TGLayoutHints(kLHintsTop | kLHintsLeft , 5, 5, 5, 5 ) ) ;   
  
  fDirNum = new TGListBox(fTabF2a, -1) ; 
  fDirNum->Resize(50,20) ; 
  fTabF2a->AddFrame( fDirNum, 
		     new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5 ) ) ;

  fButtonPlot = new TGTextButton(fTabF2a, "PLOT", M_BUTTON_PLOT );
  fButtonPlot->Associate(this) ;   
  fTabF2a->AddFrame (fButtonPlot, new TGLayoutHints(kLHintsTop | kLHintsLeft, 50, 50, 5, 5) );

  //  create the entries in the second subframe
  
  fCanvasRun = new TRootEmbeddedCanvas("fCanvasRun", fTabF2b, 300, 300 ) ; 
  fTabF2b->AddFrame(fCanvasRun, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY | kLHintsExpandX, 5, 5, 5, 5 ) ) ; 

  //  create the entries in the second subframe

  fButtonPartID = new TGTextButton(fTabF2c, "PartId", M_BUTTON_PARTID );
  fButtonPartID->Associate(this) ;
  fTabF2c->AddFrame (fButtonPartID, new TGLayoutHints(kLHintsBottom | kLHintsLeft, 2, 2, 2, 2) );

  fButtonEnergy = new TGTextButton(fTabF2c, "Energy", M_BUTTON_ENERGY );
  fButtonEnergy->Associate(this) ;
  fTabF2c->AddFrame (fButtonEnergy, new TGLayoutHints(kLHintsBottom | kLHintsLeft, 2, 2, 2, 2) );

  fButtonCore = new TGTextButton(fTabF2c, "CoreX", M_BUTTON_CORE );
  fButtonCore->Associate(this) ;
  fTabF2c->AddFrame (fButtonCore, new TGLayoutHints(kLHintsBottom | kLHintsLeft, 2, 2, 2, 2) );

  //
  //  create Tab 3 
  //

  tf = fTab->AddTab("Control") ; 
  fTabF3 = new TGCompositeFrame (tf, 100, 100, kVerticalFrame) ; 
  
  
  fButton1 = new TGTextButton(fTabF3, "&Exit", M_CTRL_EXIT);
  fButton2 = new TGTextButton(fTabF3, "Working Directory", M_CTRL_PWD);
  fButton3 = new TGTextButton(fTabF3, "Input Path", M_CTRL_PATH);

  fButton1->Associate(this) ; 
  fButton2->Associate(this) ; 
  fButton3->Associate(this) ; 
  
  fLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 10, 10, 10, 10);
  
  fTabF3->AddFrame (fButton1, fLayout ) ; 
  fTabF3->AddFrame (fButton2, fLayout ) ; 
  fTabF3->AddFrame (fButton3, fLayout ) ; 
  
  tf->AddFrame(fTabF3, fLayTab) ; 

  fFrame->AddFrame ( fTab, new TGLayoutHints(kLHintsBottom | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5) ); 

  AddFrame(fFrame, new TGLayoutHints (kLHintsExpandX|kLHintsExpandY) ) ; 



  //
  //
  //

  MapSubwindows();
  
  Layout();
  
  SetWindowName("MainSimone");
  SetIconName("MainSimone");
  
  MapWindow();
}
 
// ======================================================================
// ======================================================================

MainFrameSimone::~MainFrameSimone() {
  
  delete fButton1 ; 
  delete fButton2 ; 
  delete fFrame, fTab, fTabF1, fTabF2, fTabF3 ; 
  delete fTabF1a, fTabF1b ; 
  delete fDir, fCdup, fListMode, fDetail ; 
  delete fFileCont, fFileView ;
  delete fFileMenu, fMenuBar; 
  delete fLayout, fLayMenuBar, fLayMenuItem, fLayTab ; 
 
  delete  fPicCdup, fPicList, fPicDetail ; 
  
}

// ======================================================================
// ======================================================================
 
void MainFrameSimone::CloseWindow()
{
   // Got close message for this MainFrame. Calls parent CloseWindow()
   // (which destroys the window) and terminate the application.
   // The close message is generated by the window manager when its close
   // window menu item is selected.

   TGMainFrame::CloseWindow();
   gROOT->GetApplication()->Terminate(0)  ; 

}

// ======================================================================
// ======================================================================

Bool_t MainFrameSimone::CerFileExist(Char_t *dir)
{
  Char_t testfile[110] ;
  FILE *unit ; 
  
  sprintf (testfile, "%s/%s/cer000001", 
	    	     gSystem->WorkingDirectory(), dir  ) ; 
  //
  //   try to open the testfile
  //

  if ( (unit = fopen (testfile, "r" )) == 0 ) {
    //
    //  doesn't exist --> kFALSE
     return (kFALSE) ; 
  }
  else {
    fclose ( unit ) ; 
    
    return ( kTRUE ) ; 
  }
  
  return (kFALSE) ; 
}

// ======================================================================
// ======================================================================        
Bool_t MainFrameSimone::CheckNtup()
{
  if ( ! strcmp( fInputPath, "\0")  ) {
    printf ("No InputPath specified!! Do this before!!\n") ; 
    return (kFALSE) ;
  }
  

  if ( ! strcmp ( fInputPath, fNtupPath ) ) {
    return (kTRUE) ; 
  }
  else {
    
    if ( ReadDataToNtup() ) {
      return (kTRUE) ; 
    }
  }
      
  return (kFALSE) ;
}

// ======================================================================
// ======================================================================

Bool_t MainFrameSimone::ReadDataToNtup()
{
  Char_t  cername[256] ; 
  Char_t  datname[256] ;
  
  ifstream   cerfile ; 
  
  COREventHeader Event ;  
  
  printf("readin the input path: %s \n", fInputPath ) ; 
  
  fNtup->Reset() ; 

  for (int i_cer = 1; i_cer <= 100000; i_cer++ ) {
  
    //   create the file names 
    
    sprintf ( cername, "%s/cer%06d", fInputPath, i_cer ) ; 
    sprintf ( datname, "%s/dat%06d", fInputPath, i_cer ) ; 
    
    //   try to open the files
        
    cerfile.open( cername );
    
    if ( cerfile.bad() ) { 

      fNumEvents = i_cer -1 ;
      
      sprintf ( datname, "%d", fNumEvents ) ; 

      fDirNum->RemoveEntry(1) ; 
      fDirNum->AddEntry(datname,1) ; 	    
      fDirNum->MapSubwindows() ; 
      fDirNum->Layout() ;  
      
      break ; 
    }
    
    Event.read( cerfile );

    //
    //   fill Ntuple
    // 
    
    fNtup->Fill( Event.get_primary() ,
		 Event.get_energy() , 
		 Event.get_coreX(), 
		 Event.get_coreY() ) ;  

 
    cerfile.close();
    
  }

  //
  //    set some value of this class
  //
  sprintf ( fNtupPath, "%s", fInputPath) ;  

  return (kTRUE) ; 
}

// ======================================================================
// ======================================================================

Bool_t MainFrameSimone::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
{
  Int_t retval = 0 ; 
  Char_t  wort[100] ;
  Char_t  testfile[100] ;
  Char_t  extens[5] ;
  Char_t  command[110] ;
 
  TGFileItem *item ;     // to process items in the file view container
  void *np = NULL ;      // null pointer

  TCanvas *canvas =  fCanvasRun->GetCanvas();   
 
  // Process events generated by the buttons in the frame.

  switch (GET_MSG(msg)) {
  case kC_COMMAND:
    switch (GET_SUBMSG(msg)) {
    case kCM_BUTTON:

      switch (parm1) {
      case M_CDIR_UP :
	sprintf ( fInputPath, "\0") ; 
	fSelectButton->SetState(kButtonDisabled) ; 
	fDir2->RemoveEntry(1) ; 
	fDir2->AddEntry(fInputPath,1) ; 
	fDir2->MapSubwindows() ; 
	fDir2->Layout() ;   
	      
	//
	//  goto the parent directory
	//
	gSystem->ChangeDirectory("..") ; 
	fDir->RemoveEntry(1) ; 
	sprintf (wort, "%s", gSystem->WorkingDirectory() ) ; 
	fDir->AddEntry(wort,1) ; 
	fDir->MapSubwindows() ; 
	fDir->Layout() ; 
	fFileCont->ChangeDirectory( wort ) ; 
	fFileCont->DisplayDirectory() ; 
	  
	break ; 

      case M_LIST_MODE:
	fFileView->SetViewMode(kLVList) ; 
	fDetail->SetState(kButtonUp) ; 
	break ; 

      case M_DETAIL_MODE:
	fFileView->SetViewMode(kLVDetails) ; 
	fListMode->SetState(kButtonUp) ; 
	break ; 

      case M_BUTTON_SELECT: 

	if ( fFileCont->NumSelected() == 1 ) {   
	  //
	  //  one file selected
	  //	  
	  item = (TGFileItem *) fFileCont->GetNextSelected(&np) ; 

	  if ( S_ISDIR(item->GetType()) ) {   // file is directory
	    
	    sprintf (fInputPath, "%s/%s",
		     gSystem->WorkingDirectory(), 
		     item->GetItemName()->GetString()) ;

	    fDir2->RemoveEntry(1) ; 
	    fDir2->AddEntry(fInputPath,1) ; 	    
	    fDir2->MapSubwindows() ; 
	    fDir2->Layout() ;   
	      
	  }
	}
	break;

      case M_BUTTON_PARTID: 
	if ( CheckNtup() )  
	  {
	    fNtup->Draw("PartID") ; 
	    canvas->Modified() ; 
	    canvas->Update() ; 
	  }
	else  
	  printf("No Ntuple exist!!\n"); 
	break; 

      case M_BUTTON_ENERGY: 
	if ( CheckNtup() )  
	  {
	    fNtup->Draw("Energy") ; 
	    canvas->Modified() ; 
	    canvas->Update() ; 
	  }
	else  
	  printf("No Ntuple exist!!\n"); 
	break; 

      case M_BUTTON_CORE: 
	if ( CheckNtup() )  
	  {
	    fNtup->Draw("CoreY:CoreX") ; 
	    canvas->Modified() ; 
	    canvas->Update() ; 
	  }
	else  
	  printf("No Ntuple exist!!\n"); 
	break; 

      case M_CTRL_EXIT:
	CloseWindow() ; 
	break; 

      case M_CTRL_PWD: 
	printf ("WorkingDirectory -> %s <- \n", gSystem->WorkingDirectory() ) ;
	break ; 

      case M_CTRL_PATH: 
	printf ("Input Path: -> %s <- \n", fInputPath ) ;
	break ; 
      }

      break; 
      
    case kCM_CHECKBUTTON:

      break;

    case kCM_RADIOBUTTON:
      break;


    case kCM_MENU: 
      switch (parm1) {
      case M_FILE_EXIT: 
	CloseWindow() ;
	break; 
	
      }
      break ; 
	 
    default:
      break;
      
    }

  case kC_CONTAINER: 
    switch (GET_SUBMSG(msg)) {
      
      //      case kCT_ITEMCLICK:
      //        printf ("itemclick\n"); 
      //        break; 

      
    case kCT_ITEMDBLCLICK: 
      //
      //  process the double click in the file view container
      //
      
      if ( parm1 == kButton1) {
	if ( fFileCont->NumSelected() == 1 ) {   
	  //
	  //  one file selected
	  //	  
	  item = (TGFileItem *) fFileCont->GetNextSelected(&np) ; 

	  if ( S_ISDIR(item->GetType()) ) {   // file is directory

	    sprintf (wort, "%s", item->GetItemName()->GetString()) ;
	    
	    //
	    //  check if in this directory the file cer000001 exits
	    //  if it exists, do not open the stuff
	    //

	    if ( CerFileExist( wort ) ) {
	      printf ("Warning: Cer files in directory\n") ; 
	      fSelectButton->SetState(kButtonUp) ; 
	    }  
	    else {
	      sprintf (fInputPath,"\0") ; 
	      fSelectButton->SetState(kButtonDisabled) ;
	      fDir2->RemoveEntry(1) ; 
	      fDir2->AddEntry(fInputPath,1) ;
	      fDir2->MapSubwindows() ; 
	      fDir2->Layout() ;   
	      //
	      //  goto directory 
	      //
	      fFileCont->ChangeDirectory ( wort ) ; 
	      gSystem->ChangeDirectory( wort ) ; 
	      
	      sprintf (wort, "%s", gSystem->WorkingDirectory() ) ; 
	      fDir->RemoveEntry(1) ; 
	      fDir->AddEntry( wort, 1 ) ; 
	      fDir->MapSubwindows() ; 
	      fDir->Layout() ; 
	    }
	    
	  }
	  else {   // item is a file
	    sprintf (testfile, "%s", item->GetItemName()->GetString() ) ; 
	    
	    //
	    //    determine the file type by extensions
	    //
	    
	    for (Int_t i = 0 ; i<5; i++) 
	      extens[i] = '\0' ; 
	    
	    for ( Int_t i=0; testfile[i] != '\0'; i++) {
	      if ( testfile[i] == '.') {
		strncpy (extens, &testfile[i+1], 4 ) ; 
		break ; 
	      }
	    }

	    //
	    //     postscript file
	    //
	    
	    if ( ! strcmp(extens, "ps") ) {
	      sprintf ( command, "gv %s/%s &", 
			gSystem->WorkingDirectory(), 
			testfile ) ; 
	      gSystem->Exec(command) ; 
	      break ; 
	    }
	    
		
	    
	      
	  }
	}
      }      
      else if ( parm1 == kButton3) {  // right mouse double click
	printf ("huschel kButton3\n");  
      }

      break; 
      
    }
    break ;

     
  default:
    break;
  }
  return kTRUE;
}


