/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
!   Author(s): Thomas Bretz  12/2000 (tbretz@uni-sw.gwdg.de)
!
!   Copyright: MAGIC Software Development, 2000-2001
!
!
\* ======================================================================== */

#include "MGDisplayAdc.h"

#include <TGButton.h>            // TGTextButton
#include <TCanvas.h>             // TCanvas.h
#include <TGMsgBox.h>            // TGMsgBox
#include <TRootEmbeddedCanvas.h> // TRootEmbeddedCanvas

enum ComIdentDisplayAdc {
	M_BUTTON_SAVE,
		M_BUTTON_PRINT,
		M_BUTTON_PRINTALL,
		M_BUTTON_CLOSE , 
		
		M_BUTTON_PREV, 
		M_BUTTON_NEXT,

		M_LIST_HISTO,
		M_RADIO_HIGH,
		M_RADIO_LOW,
		M_RADIO_LH,
		M_BUTTON_RESET,
		M_VSId1
} ; 

MGDisplayAdc::MGDisplayAdc ( MHFadcCam *histos,
			    const TGWindow *p, const TGWindow *main, 
			    UInt_t w, UInt_t h, 
			    UInt_t options) 
	: TGTransientFrame(p, main, w, h, options ) 
{
    //
    //   default constructor
    //

    //
    // NEVER try to delete them in the destructor!
    //
    fHists = histos ;

    //
    //   the top frame for the list and some buttons and the Canvas
    //
    fFrameTop = new TGHorizontalFrame (this, 60,20,  kFitWidth ) ;

    //
    //    left part of top frame
    //
    fFT1 =  new TGVerticalFrame (fFrameTop, 80,300,  kFitWidth ) ;

    fHistoList = new TGListBox ( fFT1, M_LIST_HISTO ) ;
    fHistoList->Associate( this ) ;
    fFT1->AddFrame ( fHistoList, new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 10, 10 ) )  ;
	
    fHistoList->Resize(80, 405 ) ;

    fFrameTop->AddFrame (fFT1, new TGLayoutHints ( kLHintsTop , 10, 10, 10, 10 ) ) ;

    //
    //    middle part of top frame
    //
    fFT2 =  new TGVerticalFrame (fFrameTop, 80,20,  kFitWidth ) ;

    fButtonPrev = new TGTextButton ( fFT2, "Prev Histo", M_BUTTON_PREV ) ;
    fButtonPrev->Associate (this) ;
    fFT2->AddFrame ( fButtonPrev, new TGLayoutHints (kLHintsLeft | kLHintsTop,10, 10, 0, 10 ) )  ;


    fVslider1 = new TGVSlider (fFT2, 250, kSlider1 | kScaleBoth, M_VSId1);

    fVslider1->Associate(this);
    fVslider1->SetRange(0, 576);
    fFT2->AddFrame(fVslider1);

    fButtonNext = new TGTextButton ( fFT2, "Next Histo", M_BUTTON_NEXT ) ;
    fButtonNext->Associate (this) ;
    fFT2->AddFrame ( fButtonNext, new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 10, 5 ) )  ;

    fFrameTop->AddFrame (fFT2, new TGLayoutHints ( kLHintsTop , 10, 10, 10, 10 ) ) ;

    //
    // Radio buttons, used to select the high, low anh high/low display
    //
    fRadio[0] = new  TGRadioButton(fFT2, "&High Gain", M_RADIO_HIGH);
    fFT2->AddFrame ( fRadio[0], new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 10, 5 ) )  ;
    fRadio[0]->Associate(this);
    fRadio[0]->SetState(kButtonDown);
    fHistoLock = kFALSE;
    fHistoType=1;

    fRadio[1] = new  TGRadioButton(fFT2, "&Low Gain", M_RADIO_LOW);
    fFT2->AddFrame ( fRadio[1], new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 10, 5 ) )  ;
    fRadio[1]->Associate(this);

    fRadio[2] = new  TGRadioButton(fFT2, "H&igh/Low Gain", M_RADIO_LH);
    fFT2->AddFrame ( fRadio[2], new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 10, 5 ) )  ;
    fRadio[2]->Associate(this);

    //
    //    right part of top frame
    //
    fFT3 =  new TGVerticalFrame (fFrameTop, 60, 60,  kFitWidth ) ;

    fECanv = new TRootEmbeddedCanvas("fECanv", fFT3, 400, 400 ) ;

    fFT3->AddFrame( fECanv, new TGLayoutHints ( kLHintsCenterX | kLHintsCenterY | kLHintsExpandX | kLHintsExpandY , 10, 10, 10, 10 ) ) ;

    //
    //the button for reseting the histogram
    //
    fButtonReset = new TGTextButton ( fFT3, "Reset histo", M_BUTTON_RESET ) ;
    fButtonReset->Associate (this) ;
    fFT3->AddFrame ( fButtonReset, new TGLayoutHints (kLHintsCenterX | kLHintsTop,10, 10, 0, 10 ) )  ;
	
    fCanv = fECanv->GetCanvas() ;

    fFrameTop->AddFrame (fFT3, new TGLayoutHints ( kLHintsCenterX | kLHintsCenterY | kLHintsExpandX | kLHintsExpandY , 10, 10, 10, 10 ) ) ;

    AddFrame ( fFrameTop, new TGLayoutHints ( kLHintsTop | kLHintsExpandX , 10, 10, 10, 10 ) ) ;

    //
    //   the low frame for the control buttons
    //
    fFrameLow = new TGHorizontalFrame (this, 60,20, kFixedWidth ) ;

    fButtonSave = new TGTextButton ( fFrameLow, "Save", M_BUTTON_SAVE ) ;
    fButtonSave->Associate (this) ;
    fFrameLow->AddFrame ( fButtonSave, new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 5, 5 ) )  ;

    fButtonPrint = new TGTextButton ( fFrameLow, "Print", M_BUTTON_PRINT ) ;
    fButtonPrint->Associate (this) ;
    fFrameLow->AddFrame ( fButtonPrint, new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 5, 5 ) )  ;

    fButtonPrintAll = new TGTextButton ( fFrameLow, "PrintAll", M_BUTTON_PRINTALL ) ;
    fButtonPrintAll->Associate (this) ;
    fFrameLow->AddFrame ( fButtonPrintAll, new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 5, 5 ) )  ;
  
    fButtonClose = new TGTextButton ( fFrameLow, "Close", M_BUTTON_CLOSE ) ;
    fButtonClose->Associate (this) ;
    fFrameLow->AddFrame ( fButtonClose, new TGLayoutHints (kLHintsLeft | kLHintsTop, 10, 10, 5, 5 ) )  ;
    AddFrame ( fFrameLow, new TGLayoutHints ( kLHintsBottom | kLHintsExpandX , 10, 10, 10, 10 ) ) ;
	
    //
    //
    //
    BuildHistoList() ;

    MapSubwindows();

    Layout();

    SetWindowName("ADC Spectra");
    SetIconName("ADC Spectra");

    //
    // Here the initial display is set to hitogram 0
    //
    fHistoList->Select(1, kTRUE);
    DrawSelectedHi() ;
    SetSelectedTopEntry();
    fCanv->Modified() ;
    fCanv->Update() ;
    SetSelectedPos();

    MapWindow();
    SetWMSizeHints(550, 550, 1000, 1000, 1, 1);
}  

MGDisplayAdc::~MGDisplayAdc ()
{ 
    delete fButtonSave ;
    delete fButtonPrint ; 
    delete fButtonPrintAll ; 
    delete fButtonClose ; 
    
    delete fButtonPrev; 
    delete fButtonNext ; 
    delete fButtonReset ;
    
    delete fVslider1; 
    delete fECanv ;
    
    delete fHistoList ;
    delete fRadio[2];
    delete fRadio[1];
    delete fRadio[0]; 
    delete fFT1 ; 
    delete fFT2 ; 
    delete fFT3 ; 
    delete fFrameLow ; 
    delete fFrameTop ; 
}  

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

void MGDisplayAdc::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.
  // 
  delete this ; 
  //  TGTransientFrame::CloseWindow();
  //  TGMainFrame::CloseWindow();
  //   gROOT->GetApplication()->Terminate(0)  ; 
}



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

Bool_t MGDisplayAdc::BuildHistoList(Int_t type ) 
{
    //
    //   looks in the container of the AdcSpectra and reads in the
    //   Histogramms in there.
    //
    //   In the class MHFadcCam are in fact two lists. One for the high and
    //   one for the low gain. Here we will use only the high gain list!!!
    //   With some special options (settings in the gui) we will also be able
    //   to plot the low gain
    //

    const Int_t nhi = fHists->GetEntries();
    for ( Int_t i=0 ; i < nhi; i++ ) {
        fHistoList->AddEntry(fHists->GetHistHi(i)->GetName(), i+1) ;
    }

    fHistoList->MapSubwindows() ;
    fHistoList->Layout() ;
    return kTRUE ;
} 

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

Bool_t MGDisplayAdc::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
{     
    //
    // Process events generated by the buttons in the frame.
    //
    Int_t   buttons = 4, retval = 0 ;
    //Char_t  wort[100] ;
    //Char_t  extens[5] ;
    //Char_t  command[110] ;

    //TGFileItem *item ;     // to process items in the file view container
    //void *np = NULL ;      // null pointer

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

            switch (parm1)
            {
            case M_BUTTON_SAVE:
                new TGMsgBox(fClient->GetRoot(), this,
                             "WARNING!",
                             "Not implemented yet.",
                             kMBIconExclamation, buttons, &retval);
                break ;

            case M_BUTTON_PRINT:
                break;

            case M_BUTTON_RESET:
                new TGMsgBox(fClient->GetRoot(), this,
                             "WARNING!",
                             "Not implemented yet.",
                             kMBIconExclamation, buttons, &retval);
                break;

            case M_BUTTON_CLOSE:
                CloseWindow() ;
                break ;

                // The selection for "Next Histogram".
                // There is also a link for the sicronisation with the slider
                //
            case M_BUTTON_PREV:
            case M_BUTTON_NEXT:
                if ((parm1==M_BUTTON_PREV && GetSelected()-1 > 0) ||
                    (parm2==M_BUTTON_NEXT && GetSelected()-1 < 576))
                {
                    if (fHistoLock == kTRUE )
                    {
                        fCanvas->cd(1);
                        SelectSelected();
                        DrawSelectedHi() ;
                        fCanvas->cd(2);
                        DrawSelectedLo() ;
                    }
                    else
                    {
                        fCanv->cd();
                        SelectSelected();
                        DrawSelectedHi() ;

                    }
                    SetSelectedTopEntry();
                    fCanv->Modified() ;
                    fCanv->Update() ;
                    SetSelectedPos();

                }
                if (fRadio[1]->GetState() != kButtonDown)
                    break;

                fRadio[0]->SetState(kButtonDown);
                fRadio[1]->SetState(kButtonUp);
                break;

            default:
                break ;
            }
            break;

        case kCM_RADIOBUTTON:

            switch(parm1)
            {
            case M_RADIO_HIGH:
            case M_RADIO_LOW:
                if (parm1 == M_RADIO_HIGH)
                {
                    fRadio[1]->SetState(kButtonUp);
                    fRadio[2]->SetState(kButtonUp);
                    fHistoType=1;
                }
                else
                {
                    fRadio[0]->SetState(kButtonUp);
                    fRadio[2]->SetState(kButtonUp);
                    fHistoType = 2;
                }
                fHistoLock = kFALSE;

                fCanv->cd();
                SelectSelected();
                parm1 == M_RADIO_HIGH ? DrawSelectedHi() : DrawSelectedLo();

                SetSelectedTopEntry();
                fCanv->Modified() ;
                fCanv->Update() ;
                SetSelectedPos();
                break;
				
            case M_RADIO_LH:
                fRadio[0]->SetState(kButtonUp);
                fRadio[1]->SetState(kButtonUp);

                if (fHistoLock == kFALSE)
                {
                    fCanvas = fECanv->GetCanvas();
                    fCanvas->Divide(1,2, 0, 0 ,0);

                    fCanv->Modified() ;
                    fCanv->Update() ;
                    fHistoLock = kTRUE;
                    fHistoType = 3;
                }

                fCanvas->cd(1);

                SelectSelected();
                DrawSelectedHi() ;
                SetSelectedTopEntry();

                fCanvas->cd(2);
                SelectSelected();
                DrawSelectedLo() ;
                SetSelectedTopEntry();

                fCanv->Modified() ;
                fCanv->Update();

            default:
                break;
            }
            break;
        }
		
    case kCM_LISTBOX:
        if (GET_SUBMSG(msg) != M_LIST_HISTO)
            break;

        if (fHistoLock == kTRUE )
        {
            fCanvas->cd(1);
            DrawSelectedHi() ;
            fCanvas->cd(2);
            DrawSelectedLo() ;
        }
        else
        {
            fCanv->cd() ;
            DrawSelectedHi() ;
        }
        fCanv->Modified() ;
        fCanv->Update() ;
        SetSelectedPos();
        break ;

/*
    case kC_CONTAINER:
        switch (GET_SUBMSG(msg))
        {

        case kCT_ITEMDBLCLICK:
            break;

        default:
            break ;
        }
*/

    case kC_VSLIDER:
        if (GET_SUBMSG(msg)!=kSL_POS || parm1!=M_VSId1)
            break;

        // Check for the slider movement and sicronise with TGListBox
        if (parm2<0 || parm2>576)
            break;

        if (fHistoLock==kTRUE)
        {
            fCanvas->cd(1) ;
            DrawHi(parm2) ;
            fHistoList->Select(parm2+1, kTRUE);

            fCanvas->cd(2) ;
            DrawLo(parm2) ;
        }
        else
        {
            fCanv->cd() ;
            DrawHi(parm2) ;
        }

        fHistoList->Select(parm2+1, kTRUE);
        SetSelectedTopEntry();

        fCanv->Modified() ;
        fCanv->Update() ;

        if (fRadio[1]->GetState() != kButtonDown)
            break;

        fRadio[0]->SetState(kButtonDown);
        fRadio[1]->SetState(kButtonUp);

        break;

    }
    return kTRUE;
}
