/*
 * $Header$
 * $Log$
 *
 * The graphical user interface for the Neutron Cross section database
 */

#define __XSGUI_CXX

#include <stdio.h>
#include <stdlib.h>

#include <TROOT.h>
#include <TGraph.h>
#include <TFrame.h>
#include <TCanvas.h>
#include <TSystem.h>
#include <TApplication.h>
#include <Riostream.h>

#include "XSGui.h"
#include "XSVarious.h"
#include "XSElementDlg.h"
#include "XSReactionDlg.h"

//ClassImp(XSGui)

const char *filetypes[] = { "All files", "*",
   "Data file", "*.dat",
   "ENDF files", "*.endf",
   0,    0 };

/* ----- XSGui ----- */
XSGui::XSGui(const TGWindow *p, UInt_t w, UInt_t h)
: TGMainFrame(p, w, h)
{
   // Create the main frame. A TGMainFrame is a top level window.

   // Create menubar and popup menus. The hint objects are used to place
   // and group the different menu widgets with respect to eachother.
   menuBarLayout = new TGLayoutHints(
                                     kLHintsTop | kLHintsLeft | kLHintsExpandX,
                                     0, 0, 1, 1);
   menuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft,
                                         0, 4, 0, 0);
   menuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);

   // Build up the menus
   // First the Main (FILE) menu
   fileMenu = new TGPopupMenu(fClient->GetRoot());
   fileMenu->AddEntry("&Open...", M_FILE_OPEN);
   fileMenu->AddEntry("&Save", M_FILE_SAVE);
   fileMenu->AddEntry("S&ave as...", M_FILE_SAVEAS);
   fileMenu->AddEntry("&Close", M_FILE_CLOSE);
   fileMenu->AddSeparator();
   fileMenu->AddEntry("&Print", M_FILE_PRINT);
   fileMenu->AddEntry("P&rint setup...", M_FILE_PRINT_SETUP);
   fileMenu->AddSeparator();
   fileMenu->AddEntry("E&xit", M_FILE_EXIT);

   fileMenu->DisableEntry(M_FILE_SAVEAS);
   fileMenu->DisableEntry(M_FILE_CLOSE);

   // The database menu and the current elements in graph
   elemMenu = new TGPopupMenu(fClient->GetRoot());
   elemMenu->AddEntry("&Reaction", M_ELEM_REACTION);
   elemMenu->AddEntry("&Modify", M_ELEM_MODIFY);
   elemMenu->AddEntry("&Clear", M_ELEM_CLEAR);
   elemMenu->AddSeparator();
   elemMenu->AddLabel("Current Elements in Graph");

   // The Currently Editing elements menu
   optMenu = new TGPopupMenu(fClient->GetRoot());
   optMenu->AddEntry("&Zoom", -1);
   optMenu->AddEntry("&Options", -1);

   // The Help Menu
   helpMenu = new TGPopupMenu(fClient->GetRoot());
   helpMenu->AddEntry("&About",M_HELP_ABOUT);

   // Menu button messages are handled by the main frame (i.e. "this")
   // ProcessMessage() method.
   fileMenu->Associate(this);
   elemMenu->Associate(this);
   optMenu->Associate(this);
   helpMenu->Associate(this);

   menuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
   menuBar->AddPopup("&File", fileMenu, menuBarItemLayout);
   menuBar->AddPopup("&Element", elemMenu, menuBarItemLayout);
   menuBar->AddPopup("&Options", optMenu, menuBarItemLayout);
   menuBar->AddPopup("&Help", helpMenu, menuBarHelpLayout);

   AddFrame(menuBar, menuBarLayout);

   // Create a ROOT Canvas used for drawing...
   canvasWindow = new TRootEmbeddedCanvas("Canvas",this,
                                          600,400);

   // Initialise the canvas
   canvas = canvasWindow->GetCanvas();
   canvas->SetFillColor(42);
   canvas->SetGrid();
   canvas->GetFrame()->SetFillColor(21);
   canvas->GetFrame()->SetBorderSize(6);
   canvas->SetLogx();
   canvas->SetLogy();
   canvas->Update();

   AddFrame(canvasWindow,
            new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,
                              0, 0, 2, 2));

   statusBar = new TGStatusBar(this, 60, 20);
   AddFrame(statusBar, new TGLayoutHints(kLHintsBottom | kLHintsExpandX,
                                         0, 0, 1, 0));
   statusBar->SetText(PRGNAME);

   SetWindowName(PRGNAME);

   MapSubwindows();

   // we need to use GetDefault...() to initialize the layout algorithm...
   Resize(GetDefaultSize());

   MapWindow();
} // XSGui

/* ----- ~XSGui ----- */
XSGui::~XSGui()
{
   // Delete all created widgets.
   delete menuBarLayout;
   delete menuBarItemLayout;
   delete menuBarHelpLayout;

   delete fileMenu;
   delete elemMenu;
   delete optMenu;
   delete helpMenu;

   delete statusBar;
   delete canvasWindow;
} // ~XSGui

/* ----- CloseWindow ----- */
void
XSGui::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();
   gApplication->Terminate(0);
} // CloseWindow

/* ----- ProcessMenuMessage ----- */
Bool_t
XSGui::ProcessMenuMessage( Long_t param )
{
   switch (param) {
      case M_FILE_OPEN:
      {
         static TString dir(".");
         TGFileInfo fi;
         fi.fFileTypes = filetypes;
         fi.fIniDir    = StrDup(dir);
         new TGFileDialog(fClient->GetRoot(), this, kFDOpen, &fi);
         dir = fi.fIniDir;
      }
      break;

      case M_FILE_SAVE:
      printf("M_FILE_SAVE\n");
      break;

      case M_FILE_EXIT:
      // this also terminates theApp
      CloseWindow();
      break;

      case M_ELEM_REACTION:
      new XSReactionDlg(fClient->GetRoot(), this, 1, 500,600);
      break;

      case M_HELP_ABOUT:
      // About();
      int   retval;
      new TGMsgBox(fClient->GetRoot(), this,
                   "About", "About....",
                   kMBIconAsterisk, kMBOk, &retval );
      break;

      default:
      break;
   }
   return kTRUE;
} // ProcessMenuMessage

/* ----- ProcessMessage ----- */
Bool_t
XSGui::ProcessMessage(Long_t msg, Long_t param1, Long_t)
{
   // Handle messages send to the XSGui object.
   char   str[100];

   switch (GET_MSG(msg)) {

      case kC_COMMAND:
      switch (GET_SUBMSG(msg)) {

         case kCM_BUTTON:
         snprintf(str,100,
                  "Button was pressed, id = %ld\n",
                  param1);
         statusBar->SetText(str);
         break;

         case kCM_MENUSELECT:
         if (param1>=0)
         statusBar->SetText(menuTip[param1]);
         else
         statusBar->SetText("Undefined Menu!");
         break;

         case kCM_MENU:
         ProcessMenuMessage(param1);
         break;

         default:
         break;
      }
      default:
      break;
   }
   return kTRUE;
} // ProcessMessage

//---- Main program ----------------------------------------------------------

TROOT root("GUI", "GUI test environment");

/* ----- main ----- */
int main(int ac, char *av[])
{
   TApplication theApp("App", &ac, av);

   XSGui mainWindow(gClient->GetRoot(), 400, 220);
   
   XSinitialise();
   
   theApp.Run();
   
   XSfinalise();
   return 0;
} // main