// -*- C++ -*-
// --------------------------------------------------------------------
// AppUi
// --------------------------------------------------------------------
/*

    This file is part of the extensible drawing editor Ipe.
    Copyright (C) 1993-2004  Otfried Cheong

    Ipe is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    As a special exception, you have permission to link Ipe with the
    CGAL library and distribute executables, as long as you follow the
    requirements of the Gnu General Public License in regard to all of
    the software in the executable aside from CGAL.

    Ipe is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with Ipe; if not, you can find it at
    "http://www.gnu.org/copyleft/gpl.html", or write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef APPUI_H
#define APPUI_H

#include "ipebase.h"
#include "ipecolor.h"
#include "ipestyle.h"
#include "ipesnap.h"
#include "ipelet.h"
#include "ipeundo.h"

#include "ipemodel.h"
#include "ipeprefs.h"

#include "ipecanvas.h"
#include "ipeoverlay.h"

#include "master.h"

#include <qmainwindow.h>
#include <qscrollview.h>
#include <qpixmap.h>
#include <qtoolbutton.h>
#include <qtranslator.h>
#include <qspinbox.h>

class IpePage;

class QSpinBox;
class QToolBar;
class QPopupMenu;
class QComboBox;
class QTextBrowser;
class QListBox;
// class QListView;
class QLineEdit;
class QWidgetStack;
class QPushButton;
class QColor;
class QAction;
class QActionGroup;
class QListBoxItem;
class QLabel;

// --------------------------------------------------------------------

// in main.cpp
void StartManual(QString url);

class IpeSpinBox : public QSpinBox {
public:
  IpeSpinBox(QWidget *parent, const char *name,
	     int minValue = 1, int maxValue = 1, int step = 1);
  void Set(int value, int maxValue);
  void Set(int value);
};

class DecimalSpinBox : public QSpinBox {
public:
  DecimalSpinBox(int minValue, int maxValue, int step,
		 int decimals = 1, QWidget *parent = 0);
  void setValueFromAttribute(int value);
protected:
  virtual QString mapValueToText(int value);
  virtual int mapTextToValue(bool *ok);
private:
  int iDecimals;
};

// --------------------------------------------------------------------

class AppUi : public QMainWindow, public IpeCanvasServices,
	      public IpeOverlayServices, public IpeletHelper {
  Q_OBJECT

public:
  enum TCommands { ECmdGroup, ECmdUngroup, ECmdDuplicate, ECmdFront, ECmdBack,
		   ECmdCut, ECmdCopy, ECmdPaste, ECmdDelete, ECmdSelectAll,
		   ECmdNewLayer, ECmdRenameLayer,
		   ECmdSelectLayer, ECmdLineWidth, ECmdDashStyle,
		   ECmdTextSize, ECmdMarkShape, ECmdMarkSize, ECmdUndo,
		   ECmdRedo, ECmdEdit,
		   ECmdSetArrows, ECmdArrowSize, ECmdStroke, ECmdFill,
		   ECmdComposePaths, ECmdJoinPaths, ECmdDecomposePath,
		   ECmdHere, ECmdSetOrigin, ECmdResetOrigin,
		   ECmdSetOriginSnap, ECmdSetDirection, ECmdSetDirectionSnap,
		   ECmdSetLine, ECmdSetLineSnap,
		   ECmdMoveToLayer,
		   ECmdNewLayerNewView, ECmdNewView, ECmdDeleteView,
		   ECmdFirstView, ECmdLastView,
  };

public:
  AppUi(QWidget* parent=0, const char* name=0, WFlags f=0);
  ~AppUi();

  bool Load(QString fileName);
  bool Save(QString fname, bool warnOverwrite);

  void SaveKeys(const QString &fname);

public slots:
  void Cmd(int cmd);
  void UndoCmd(int cmd);
  void SnapCmd(int cmd);

  void Cut();
  void Copy();
  void Paste();

  void NewWindow();

  void About();

  void NewDoc();
  bool Save();
  bool SaveAs();
  void SaveAsBitmap();
  void Load();

  void EditObject();
  void EditDocProps();
  void EditPrefs();
  void Manual();
  bool RunLatex(int);

  void NextView();
  void PreviousView();
  void EditViews();

  void CreatePage();
  void DeletePage();
  void CopyPage(int cut);
  void PastePage();

  void NormalSize();
  void DefaultZoom();
  void FitPage();
  void FitObjects();
  void FitSelection();

  void StyleSheets();

  void FirstPage();
  void LastPage();

  void SetCreator(QAction *action);
  void InsertTextBox();
  void InsertItemBox();

  void RunIpelet(int);

protected:
  void closeEvent(QCloseEvent *ev);

private slots:
  void AboutToShowEditMenu();

  void PageChanged(int);
  void PageChanged();
  void ViewChanged(int);
  void ViewChanged();
  void ResolutionChanged(int);
  void AbsoluteAttributes();
  void AbsoluteSnapping();

  void SetStrokeColor();
  void SetFillColor();
  void SetStrokeColorName(int item);
  void SetFillColorName(int item);

  void LineWidthChanged(int id);
  void AbsLineWidthChanged(int val);
  void DashStyleChanged(int id);
  void TextSizeChanged(int id);
  void AbsTextSizeChanged(int val);
  void MarkShapeChanged(int id);
  void MarkSizeChanged(int id);
  void AbsMarkSizeChanged(int val);
  void ArrowSizeChanged(int id);
  void AbsArrowSizeChanged(int val);
  void ArrowChanged(int id);
  void GridSizeChanged(int id);
  void AbsGridSizeChanged(int val);
  void AngleSizeChanged(int id);
  void AbsAngleSizeChanged(int val);

  void SnapChanged(bool);
  void GridVisible();
  void CoordinatesVisible();
  void LayerRightPress(QListBoxItem *item, const QPoint &);
  void LayerSelectionChanged();
  void BookmarkSelected(int index);

  void PreferencesChanged();

private: // from IpeCanvasServices
  virtual IpeBuffer StandardFont(IpeString fontName);
  virtual void CvSvcRequestOverlay(QMouseEvent *ev);
  virtual void CvSvcSetDrawingMode(bool mode);
  virtual void CvSvcWheelZoom(int delta);
  virtual void CvSvcMousePosition(const IpeVector &pos);

private: // from IpeOverlayServices
  virtual void OvSvcAddObject(IpeObject *obj);
  virtual const IpeAllAttributes &OvSvcAttributes();
  virtual const IpeStyleSheet *OvSvcStyleSheet();
  virtual void OvSvcAddUndoItem(IpePage *page, QString s);
  virtual void OvSvcAddUndoItem(IpePage::iterator it, IpePage *page,
				  const IpePgObject &original, QString s);

private: // from IpeletHelper
  virtual void Message(const char *msg);
  virtual int MessageBox(const char *text, const char *button1,
			 const char *button2, const char *button3);
  virtual bool GetString(const char *prompt, IpeString &str);
  virtual const IpeStyleSheet *StyleSheet();
  virtual const IpeDocument *Document();
  virtual IpeDocument *EditDocument();
  virtual int CurrentPage() const;
  virtual int CurrentView() const;
  virtual int CurrentLayer() const;
  virtual const IpeSnapData &SnapData() const;
  virtual const IpeAllAttributes &Attributes() const;

private:
#if QT_VERSION >= 0x030000
  QKeySequence Key(const char *src, const char *comment);
#else
  int Key(const char *src, const char *comment);
#endif
  inline IpePage *Page() { return (*iDoc)[iPno]; }
  void FitBox(const IpeRect &box);
  void UpdateLayers();
  void SetGridSizeFromPage();
  void SwitchAttributeUi();
  void SwitchSnapUi();
  void SetCaption();
  void ShowStyleInUi();
  void AddUndo(IpeUndoItem *item);
  IpeAttribute PageColor();

  void ErrMsg(QString str);

  IpeFixed AbsValue(IpeAttribute attr);
  void ConvertAbsolute(DecimalSpinBox *spin, IpeAttribute &attr);

  void ResetCombo(IpeKind kind, QComboBox *combo,
		  IpeAttribute &attr, QPixmap *pixmap = 0);
  void InsertColor(QComboBox *combo, IpeAttribute sym);
  void SetColorFromQColor(IpeAttribute &colorToSet, QColor &qColor,
			  QPushButton *button);

  virtual bool eventFilter(QObject *obj, QEvent *ev);

private:
  enum TMenuIds { EZoomMenuId = 1000, ESnapMenuId, EAbsoluteAttributesMenuId,
		  EAbsoluteSnappingMenuId, EGridVisibleMenuId,
		  ECoordinatesVisibleMenuId };

  // UI components
  IpeCanvas *iCanvas;

  QPopupMenu *iFileMenu;
  QPopupMenu *iEditMenu;
  QPopupMenu *iSnapMenu;
  QPopupMenu *iModeMenu;
  QPopupMenu *iZoomMenu;
  QPopupMenu *iLayerMenu;
  QPopupMenu *iViewMenu;
  QPopupMenu *iPageMenu;
  QPopupMenu *iIpeletMenu;

  QToolBar *iFileTools;
  QToolBar *iResolutionTools;
  QToolBar *iObjectTools;
  QToolBar *iPageTools;
  QToolBar *iLineTools;
  QToolBar *iSizeTools;
  QToolBar *iColorTools;
  QToolBar *iSnapTools;
  QToolBar *iLayerTools;
  QToolBar *iBookmarkTools;

  QWidgetStack *iStrokeColorStack;
  QWidgetStack *iFillColorStack;
  QWidgetStack *iLineWidthStack;
  QWidgetStack *iArrowSizeStack;
  QWidgetStack *iTextSizeStack;
  QWidgetStack *iMarkSizeStack;
  QWidgetStack *iGridSizeStack;
  QWidgetStack *iAngleSizeStack;

  QSpinBox *iResolution;

  IpeSpinBox *iPageNumber;
  IpeSpinBox *iViewNumber;

  QComboBox *iStrokeColor;
  QPushButton *iAbsStrokeColor;
  QComboBox *iFillColor;
  QPushButton *iAbsFillColor;

  QComboBox *iLineWidth;
  DecimalSpinBox *iAbsLineWidth;
  QComboBox *iDashStyle;
  QComboBox *iArrow;
  QComboBox *iArrowSize;
  DecimalSpinBox *iAbsArrowSize;

  QActionGroup *iModeActionGroup;
  QAction *iModeAction[IpeOverlayFactory::Num];
  QComboBox *iMarkShape;
  QComboBox *iMarkSize;
  DecimalSpinBox *iAbsMarkSize;
  QComboBox *iTextSize;
  DecimalSpinBox *iAbsTextSize;

  QActionGroup *iSnapActionGroup;
  QAction *iSnapAction[6];
  QComboBox *iGridSize;
  IpeSpinBox *iAbsGridSize;
  QComboBox *iAngleSize;
  DecimalSpinBox *iAbsAngleSize;

  QListBox *iLayerList;
  // QListView *iBookmarks;
  QListBox *iBookmarks;

  QLabel *iMouse;
  IpeVector iMouseBase;

  int iPasteBitmapId;

  //! The most recently used file format on saving
  QString iSaveFilter;

  // Information about the document

  //! The document's filename (null if not yet saved).
  QString iFileName;
  //! The document.
  IpeDocument *iDoc;
  //! The currently displayed page no.
  int iPno;
  //! The current view.
  int iVno;
  //! The current layer.
  int iLayer;
  //! Whether latex needs to be run.
  bool iNeedLatex;
  //! Displaying attributes absolute (or symbolic)
  bool iAbsoluteAttributes;
  //! Displaying absolute snap sizes.
  bool iAbsoluteSnapping;
  //! The attributes set in the UI.
  IpeAllAttributes iAttributes;
  //! Snapping state
  IpeSnapData iSnapData;
  IpeFixed iSnapAngle;
  //! Current Ipe mode.
  int iMode;
  //! All symbolic attributes in style sheet
  IpeAttributeSeq iSyms[IpeAttribute::ETemplate + 1];

  //! Undo stack
  IpeUndoStack iUndo;
  // Ipelets
  //! Ipelet repository
  IpeletMaster iIpeletMaster;
  bool iIpeletNoUndo;

  //! Configurable key sequences
  QTranslator iKeyTranslator;
};

// --------------------------------------------------------------------
#endif
