#ifndef LANDED_GUI
#define LANDED_GUI

#include <QObject>
#include <QWidget>
#include <QRadioButton>
#include <QPushButton>
#include <QProgressBar>
#include <QMenuBar>
#include <QMenu>
#include <QLabel>
#include <QSplitter>
#include <QImage>
#include <QTableWidget>
#include <QEvent>
#include <QLineEdit>
#include <QTabWidget>
#include <QScrollBar>
#include <QBoxLayout>
#include <QTableWidgetItem>
#include <QCloseEvent>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QSpinBox>
#include <QComboBox>
#include <QSettings>
#include <QLocalServer>
#include <QLocalSocket>
#include <QNetworkReply>
#include <QFont>

#include <vector>
#include <deque>
#include <map>

#include "viewer3d.hh"
#include "projection.hh"
#include "dialogs.hh"
#include "movie.hh"
#include "helpers.hh"

class FullHit : public Hit
{
 public:
  FullHit(void):
    Hit()
  {}

 public:
  double ne;
  int track;

};

class Vertex : public ThreeVector
{
 public:
  Vertex(void):
    ThreeVector()
  {
    id=0;
  }

 public:
  int pdgcode;
  int id;
  double value;

};

//main ui window
class Gui : public QWidget
{
Q_OBJECT

public:
  Gui(void);

private:
  //settings
  QSettings settings_;
  //map from PDG particle id code to string describing particle
  //PDGMap pdg_;
  //buffer vrml shapes here, but store them in World
  //  glShapeCollection tmpshapes;
  //main menu
  //behaviour slighly different on macs from others
  //watch out for this
  QMenuBar menu_;
  //top level menu widgets
  QMenu* mnuFile_;
  #ifdef __APPLE__
  QAction* actNew_;
#endif
  QAction* actOpen_;
  QMenu* mnuRecent_;
  QAction* actQuit_;
  QAction* actServer_;
  QMenu* mnuRecord_;
  QAction* actPrev_;
  QAction* actNext_;
  QMenu* mnuNav_;
  QAction* actReset_;
  QAction* actMove_;
  QAction* actPan_;
  QAction* actZoom_;
  QAction* actCentre_;
  QMenu* mnuProj_;
  QAction* actAuto_;
  QAction* actZoomIn_;
  QAction* actZoomOut_;
  QAction* actLeft_;
  QAction* actRight_;
  QAction* actUp_;
  QAction* actDown_;
  QMenu* mnuCapture_;
  QAction* actSnapshot_;
  QAction* actMovie_;
  QMenu* mnuView_;
  QAction* actFullScreen_;
  QAction* actWire_;
  QAction* actFullDet_;
  QAction* actTracks_;
  QAction* actHits_;
  QAction* actOpacity_;
  QAction* actBackground_;
  QMenu* mnuHelp_;
  QAction* actManual_;
  QAction* actAbout_;
  //font for lists
  QFont listFont_;
  QFont listFontBig_;
  //initially widgets will be distributed vertically down the main window
  QVBoxLayout layout_;
  //progress bar for things that take more than a few seconds
  QProgressBar bar_;
  QHBoxLayout barLayout_;
  QLabel barLabel_;
  //event selection
  QHBoxLayout boxRecord_;
  QLabel lblRecord_;
  QSpinBox spinRecord_;
  QLabel lblNRecords_;
  QPushButton btnJump_;
  QPushButton btnPrev_; //0x21d0
  QPushButton btnNext_; //0x21d2
  QLabel lblID_;
  LED led_;
  //splitter, creates zones in main window with a slider in-between to 
  //  allow the user to decide how much space to give each zone
  QSplitter sides_;
  //layout for world and buttons below
  //this contains everything on the left of the splitter
  QTabWidget tabView_;
  QWidget left_;
  //the world 3d display widget
  //allow buttons to be placed below the world
  QVBoxLayout boxGL_;
  //the display widget itself
  Viewer3D gl_;
  //2d displays
  Projection xy_;
  Projection xz_;
  Projection yz_;
  //layout for first row of controls below plot
  QHBoxLayout box_;
  //buttons for mouse action in 3d mode
  QButtonGroup grp3d_;
  QRadioButton btnMove_;
  QRadioButton btnZoom_;
  QRadioButton btnPan_;
  QRadioButton btnOrigin_;
  //tabbed thingy
  QTabWidget tabLists_;
  //track scale and track list
  QWidget tracks_;
  QVBoxLayout boxTracks_;
  QHBoxLayout boxTrackScale_;
  QLabel lblTrackScale_;
  QLineEdit txtTrackScale_;
  QScrollBar barTrackScale_;
  QTableWidget lstTracks_;
  //hit scale and hit list
  QWidget hits_;
  QVBoxLayout boxHits_;
  QHBoxLayout boxHitScale_;
  QLabel lblHitScale_;
  QLineEdit txtHitScale_;
  //  QLabel lblHitFilter_;
  //  QComboBox cbxHitFilter_;
  QScrollBar barHitScale_;
  QTableWidget lstHits_;
  //right hand side, lists of particles/tracks
  //this contains everything on the right side of the splitter
  QWidget detector_;
  //I may want to add something above or below the track list
  QVBoxLayout boxDetector_;
  //track list filter
  ClearLineEdit txtFilter_;
  //detector track list
  QTableWidget lstDetector_;
  //flag indicating a file has been loaded
  //bool havefile;
  QSqlDatabase db_;
  //file event numbers
  int record_;
  int numRecords_;
  //movie recorder
  Movie movie_;
  //recent filenames
  std::deque<QString> filenames_;
  //local socket server to exchange information with art
  QLocalServer server_;
  QLocalSocket* socket_;

 public:
  //load a file into memory
  void loadFile(QString);

 private:
  void readVRML(QString);
  //has a file been loaded?
  //  bool hasfile(void);
  //recent files list
  void updateRecent(void);
  //update detector component list
  void detList(void);
  //(re)load event from file
  void loadRecord(int=-1);
  //hit list
  void addHit(const Hit&, double, int, int, int);
  //track list
  void addTrack(const Vertex&, const Vertex&, int);
  //override close event
  void closeEvent(QCloseEvent*);

 private slots:
  void cbVersion(QNetworkReply*);
  //update active display
  void cbRefresh(void);
  //set event number
  void cbSetRecord(int);
  //  it's an opengl thing
  //  void cbUpdateViewerShapes(void);
  //snapshot, saves png image of current display
  void cbSnap(void);
  //movie recording
  void cbMovie(void);
  //void cbMovieFrame(void);



//   //movie recording
//   //movie buffer
//   void cb_movie(void);
//   //timer for movie frame
//   void cb_moviesnap(void);
//   //record movie frame (not really a callback)
//   void movie_shot(void);
  //reset viewpoint
  void cbReset(void);
  //menus
  //file - new window
  void cbNew(void);
  //file - open
  void cbOpen(void);
  //switch mouse action in 3d mode from menu rather than buttons
  void cbMenuMove(void) {
    btnMove_.setChecked(true);
    cbAction(MOVE);
  }
  void cbMenuPan(void) {
    btnPan_.setChecked(true);
    cbAction(PAN);
  }
  void cbMenuZoom(void) {
    btnZoom_.setChecked(true);
    cbAction(ZOOM);
  }
  void cbMenuOrigin(void) {
    btnOrigin_.setChecked(true);
    cbAction(ORIGIN);
  }
  void cbAction(int);
  //view menu
  //full-screen
  void cbFullScreen(void);
  //show detector wire-frame?
  void cbWireFrame(void);
  //show detector surfaces?
  void cbFullDet(void);
  //show tracks?
  void cbTracks(void);
  //show hits
  void cbHits(void);
  //set view menu ticks to match current settings of world
  void viewchecks(void);
  //help
  //open manual
  void cbManual(void);
  void cbAbout(void);
  //change in detector filter
  void cbDetFilter(const QString&);
  //change in detector list
  void cbDetector(QTableWidgetItem*);
  //change in track list
  void cbTrackVis(QTableWidgetItem*);
  //change in hit list
  void cbHitVis(QTableWidgetItem*);
  //navigation mode changed from World
  void cbModeChange(Action);
  //right click on detector list
  void cbDetConf(QPoint);
  //click on item from pop-up menu above
  void cbDetMenu(QAction*);
  //user right clicks on a volume or hit
  void cbSelect(int, THD);
  //user double clicks on a volume
  void cbHide(int);
  //user wants to change opacity, from menu
  void cbOpacity(void);
  void cbOpacitySet(float);
  //user wants to change background colour
  void cbBackground(void);
  void cbBackgroundSet(float, float, float);
  //track scaling
  void cbTrackScale(int);
  //track selection
  void cbTrackSelect(void);
  //jump to track
  void cbTrackJump(int, int);
  //right click on track list
  void cbTrackConf(QPoint);
  //click on item from pop-up menu above
  void cbTrackMenu(QAction*);
  //hit scaling
  void cbHitScale(int);
  //hit selection
  //  void cbHitFilter(void);
  //select hit
  void cbHitSelect(void);
  //jump to hit
  void cbHitJump(int, int);
  //right click on hit list
  void cbHitConf(QPoint);
  //click on item from pop-up menu above
  void cbHitMenu(QAction*);
  //jump to event
  void cbJump(void);
  //previous event
  void cbPrev(void);
  //next event
  void cbNext(void);
  //file clicked on recent menu
  void cbRecent(QAction*);
  //projection
  void cbProjMenu(QAction*);
  //server
  void cbServer(void);
  //connection to server
  void cbConnect(void);
  void cbDisconnect(void);
  void cbSocket(void);

};

#endif //ifndef LANDED_GUI
