#ifndef MARS_MStatusDisplay
#define MARS_MStatusDisplay

#ifndef MARS_MAGIC
#include "MAGIC.h"
#endif

#ifndef ROOT_TGFrame
#include <TGFrame.h>
#endif

#ifndef ROOT_TTimer
#include <TTimer.h>
#endif

class MLog;
class MGList;
class MParContainer;

class TPad;
class TTimer;
class TMutex;
class TCanvas;

class TGTab;
class TGTextView;
class TGStatusBar;
class TGProgressBar;
class TGHProgressBar;
class TGCompositeFrame;
class TRootEmbeddedCanvas;

class MStatusDisplay : public TGMainFrame
{
    friend class MStatusArray;
public:
    typedef enum {
        // kFile
        kFileBrowser, kFileCanvas, kFileOpen, kFileSave, kFileSaveAs, kFileSaveAsPS,
        kFileSaveAsRoot, kFileSaveAsGIF, kFileSaveAsC, kFilePrint,
        kFilePrinterName, kFileClose, kFileExit, kFileReset,
        // kLoop
        kLoopNone, kLoopStop,
        // kTab
        kTabSave, kTabSaveAs, kTabSaveAsPS, kTabSaveAsRoot, kTabSaveAsGIF,
        kTabSaveAsC, kTabPrint, kTabNext, kTabPrevious, kTabRemove,
        // kSize
        kSize640, kSize800, kSize960, kSize1024, kSize1280,
        // kLog
        kLogCopy, kLogClear, kLogSelect, kLogFind, kLogSave, kLogAppend,
        // kPic
        kPicMagic, kPicMars,
        // kGui
        kSearch, kTabs
    } Status_t;

    enum
    {
        // TGMainFrame::kDontCallClose = BIT(14)
        kExitLoopOnExit  = BIT(15),
        kExitLoopOnClose = BIT(16)
     };

protected:
    TString fName;  // status display identifier (name) (gROOT->FindObject())
    TString fTitle; // status display title

    MLog             *fLog;
    MGList           *fList;
    TGCompositeFrame *fUserFrame;

    Bool_t ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2);

private:
    TGHProgressBar   *fBar;
    TGTab            *fTab;
    TGLayoutHints    *fLayCanvas;

    TTimer  fTimer;
    TMutex *fMutex;

    TGStatusBar *fStatusBar;

    Status_t fStatus;

    TString fPrinter;

    Int_t fLogIdx;
    TTimer fLogTimer;
    TGTextView *fLogBox;

    FontStruct_t fFont;

    UInt_t fIsLocked;

    TList *fBatch;          //!

    void AddMenuBar();
    void AddUserFrame();
    void AddTabs();
    void AddProgressBar();
    void AddStatusBar();
    void AddMarsTab();
    void AddLogTab();

    TCanvas *GetCanvas(TGCompositeFrame *f) const;

    Bool_t ProcessMessageCommandMenu(Long_t mp1);
    Bool_t ProcessMessageCommand(Long_t submsg, Long_t mp1, Long_t mp2);
    Bool_t ProcessMessageTextview(Long_t submsg, Long_t mp1, Long_t mp2);
    Bool_t ProcessMessageUser(Long_t submsg, Long_t mp1, Long_t mp2);
    void   CloseWindow();
    Bool_t HandleConfigureNotify(Event_t *);
    Bool_t HandleEvent(Event_t *event);

    Bool_t HandleTimer(TTimer *timer=NULL);
    void UpdateTab(TGCompositeFrame *f);

    void DrawClonePad(TCanvas &newc, const TCanvas &oldc) const;
    void CanvasSetFillColor(TPad &c, Int_t col) const;
    Bool_t Display(const TObjArray &list);

    void AddExtension(TString &name, const TString &ext, Int_t num) const;

    void UpdatePSHeader(const TString &name) const;

    void RemoveTab(int i);

    TRootEmbeddedCanvas *GetEmbeddedCanvas(TGCompositeFrame *cf) const;

public:
     MStatusDisplay(Long_t t=1000);
     virtual ~MStatusDisplay();

     void SetLogStream(MLog *log, Bool_t enable=kFALSE);

     void StartUpdate(Int_t millisec=-1);
     void StopUpdate();
     void SetUpdateTime(Long_t t);

     void SetProgressBarPosition(Float_t p);
     TGProgressBar *GetBar() const { return (TGProgressBar*)fBar; }

     void SetStatusLine1(const char *txt);
     void SetStatusLine2(const char *txt);
     void SetStatusLine2(const MParContainer &cont);

     void SetPrinter(const TString &lpr) { fPrinter = lpr; }

     virtual void SetName(const char *name) { fName = name; }
     virtual void SetTitle(const char *title="") { fTitle = title; }
     virtual const char *GetName() const { return fName.Data(); }
     virtual const char *GetTitle() const { return fTitle.Data(); }

     TCanvas &AddTab(const char *name);
     TGCompositeFrame *AddRawTab(const char *name);

     Bool_t   HasCanvas(const TCanvas *c) const;
     TCanvas *GetCanvas(int i) const;
     TCanvas *GetCanvas(const TString &name) const;
     TVirtualPad *GetFullPad(const Int_t canvas, const Int_t pad);
     
     Int_t Read(const char *name="MStatusDisplay");
     Int_t Write(const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0)
     {
         return Write(-1, name, option, bufsize);
     }
     Int_t Write(Int_t num, const char *name="MStatusDisplay", Int_t option=0, Int_t bufsize=0);

     Bool_t CdCanvas(const TString &name);
     void   Update() { HandleTimer(&fTimer); HandleTimer(&fLogTimer); }

     void SetNoContextMenu(Bool_t flag=kTRUE);

     Int_t  SaveAsPS(TString name="", const TString addon="") { return SaveAsPS(-1, name, addon); }
     Bool_t SaveAsGIF(TString name="") { return SaveAsGIF(-1, name); }
     Bool_t SaveAsC(TString name="") { return SaveAsC(-1, name); }
     Int_t  SaveAsRoot(TString name="") { return SaveAsRoot(-1, name); }
     Int_t  PrintToLpr() { return PrintToLpr(-1); }

     Int_t  SaveAsPS(Int_t num, TString name="", const TString addon="");
     Bool_t SaveAsGIF(Int_t num, TString name="");
     Bool_t SaveAsC(Int_t num, TString name="");
     Int_t  SaveAsRoot(Int_t num, TString name="");
     Int_t  PrintToLpr(Int_t num);

     Int_t  SaveAs(Int_t num=-1);
     Int_t  Open(TString fname, const char *name="MStatusDisplay");
     Int_t  Open();

     Status_t CheckStatus() const { return fStatus; }
     void ClearStatus() { fStatus = kLoopNone; }

     void Lock() { fIsLocked++; }
     void UnLock() { if (fIsLocked>0) fIsLocked--; }

     void Reset();

     Bool_t CheckTabForCanvas(int num) const;

     void EventInfo(Int_t event, Int_t px, Int_t py, TObject *selected);

     ClassDef(MStatusDisplay, 0)   // Window for a status display
};

#endif
