// -*- Mode: c++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil -*-
// NOTE: the first line of this file sets up source code indentation rules
// for Emacs; it is also a hint to anyone modifying this file.

// File         : the_main_window.hxx
// Author       : Paul A. Koshevoy
// Created      : Mon Apr 12 20:05:00 MDT 2004
// Copyright    : (C) 2004
// License      : GPL.
// Description  : main application window widget

#ifndef THE_MAIN_WINDOW_HXX_
#define THE_MAIN_WINDOW_HXX_

// system includes:
#include <list>

// Qt includes:
#include <QtGui>
#include <QGridLayout>
#include <QMainWindow>
#include <QTimer>

// local includes:
#include "ui_the_main_window.h"
#include "ui_AboutDialog.h"
#include "PreferencesDialog.h"

// thelib includes:
#include <ui/the_document_ui.hxx>
#include <doc/the_document.hxx>
#include <utils/instance_method_call.hxx>
#include <Qt/the_qt_trail.hxx>

// forward declarations:
class the_curve_proc_ui_t;


//----------------------------------------------------------------
// the_main_window_t
// 
class the_main_window_t : public QMainWindow,
			  public Ui::main_window,
			  public the_document_ui_t
{
  Q_OBJECT
  
public:
  the_main_window_t();
  ~the_main_window_t();
  
  void file_load(const QString & filename);
  bool file_save(bool save_as = false);
  
public slots:
  // reparent the views:
  void view_tab_changed(int tab);
  
  // the file menu:
  void file_new();
  void file_open();
  bool file_save_as();
  void file_auto_save(bool on);
  void file_exit();
  
  // the edit menu:
  void edit_undo();
  void edit_redo();
  void edit_preferences();
  
  // the view menu:
  void view_antialias();
  void view_fog();
  void view_perspective();
  void view_fullscreen();
  void view_stereoscopic();
  void exit_fullscreen();
  void orientation_restore();
  
  // the view orientation menu:
  void orientation_left()
  { set_view_orientation(THE_LEFT_VIEW_E); }
  
  void orientation_right()
  { set_view_orientation(THE_RIGHT_VIEW_E); }
  
  void orientation_top()
  { set_view_orientation(THE_TOP_VIEW_E); }
  
  void orientation_bottom()
  { set_view_orientation(THE_BOTTOM_VIEW_E); }
  
  void orientation_front()
  { set_view_orientation(THE_FRONT_VIEW_E); }
  
  void orientation_back()
  { set_view_orientation(THE_BACK_VIEW_E); }
  
  void orientation_isometric()
  { set_view_orientation(THE_ISOMETRIC_VIEW_E); }
  
  void orientation_xy()
  { set_view_orientation(THE_XY_VIEW_E); }
  
  // the tools menu:
  void tool_curve();
  void tool_surface();
  
  // the help menu:
  void help_about();
  
  // timer slot:
  bool auto_save();
  
public:
  // virtual: ui update mechanism:
  void sync_ui();
  
  // virtual:
  void kill_ui();
  
  // shortcut:
  inline the_document_t * document() const
  { return doc_so().document(); }
  
  // collect the visible views:
  void get_visible_views(std::vector<the_view_t *> & views) const;
  
  // if in single view mode, return the view:
  the_view_t * single_view() const;
  
  // preference accessor:
  inline PreferencesDialog & preferences()
  { return preferences_ui_; }
  
  inline QTimer & autosave()
  { return autosave_; }
  
protected:
  // virtual:
  void closeEvent(QCloseEvent * e);
  void moveEvent(QMoveEvent * e);
  void resizeEvent(QResizeEvent * e);
  
  // helper:
  void set_view_orientation(const the_view_mgr_orientation_t & orientation);

  // helper:
  bool save_file();
  
  // helper:
  void layout_view_tab();
  
  // the layouts used for each tab:
  QGridLayout * layout_[5];
  
  // the procedure ui:
  the_curve_proc_ui_t * curve_proc_ui_;
  
  // the preferences ui:
  PreferencesDialog preferences_ui_;
  
  // AutoSave timer:
  QTimer autosave_;
  
  // full screen window:
  QWidget fullscreen_;
  QLayout * fullscreen_layout_;
  QWidget * fullscreen_tab_;
  
  DECLARE_INSTANCE(the_main_window_t, instance_);
};


//----------------------------------------------------------------
// AboutDialog
// 
class AboutDialog : public QDialog,
		    public Ui::AboutDialog
{
  Q_OBJECT
  
public:
  AboutDialog(QWidget * parent = 0, Qt::WFlags f = 0):
    QDialog(parent, f),
    Ui::AboutDialog()
  {
    Ui::AboutDialog::setupUi(this);
  }
};


#endif // THE_MAIN_WINDOW_HXX_

