/******************************************************************************************************
 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released      *
 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission.     *
 ******************************************************************************************************/

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

#include <QGraphicsView>
#include <QImage>
#include <QUrl>

class MainWindow;
class QByteArray;
class QGraphicsPixmapItem;
class QGraphicsScene;

/// QGraphicsView class with event handling added. Typically the events are sent to the active digitizing state.
class GraphicsView : public QGraphicsView
{
  Q_OBJECT;

public:
  /// Single constructor.
  GraphicsView(QGraphicsScene *scene,
               MainWindow &mainWindow);
  virtual ~GraphicsView();

  /// Intercept context event to support point editing
  virtual void contextMenuEvent (QContextMenuEvent *event);

  /// Intercept mouse drag event to support drag-and-drop.
  virtual void dragEnterEvent (QDragEnterEvent *event);

  /// Intercept mouse move event to support drag-and-drop.
  virtual void dragMoveEvent (QDragMoveEvent *event);

  /// Intercept mouse drop event to support drag-and-drop. This initiates asynchronous loading of the dragged image
  virtual void dropEvent (QDropEvent *event);

  /// Intercept key press events to handle left/right/up/down moving.
  virtual void keyPressEvent (QKeyEvent *event);

  /// Intercept mouse move events to populate the current cursor position in StatusBar.
  virtual void mouseMoveEvent (QMouseEvent *event);

  /// Intercept mouse press events to create one or more Points.
  virtual void mousePressEvent (QMouseEvent *event);

  /// Intercept mouse release events to move one or more Points.
  virtual void mouseReleaseEvent (QMouseEvent *event);

  /// Convert wheel events into zoom in/out
  virtual void wheelEvent(QWheelEvent *event);

signals:
  /// Send right click on axis point to MainWindow for editing.
  void signalContextMenuEventAxis (QString pointIdentifier);

  /// Send right click on graph point(s) to MainWindow for editing.
  void signalContextMenuEventGraph (QStringList pointIdentifiers);

  /// Send dragged dig file to MainWindow for import. This comes from dragging an engauge dig file
  void signalDraggedDigFile (QString);

  /// Send dragged image to MainWindow for import. This typically comes from dragging a file
  void signalDraggedImage (QImage);

  /// Send dragged url to MainWindow for import. This typically comes from dragging an image from a browser
  void signalDraggedImageUrl (QUrl);

  /// Send keypress to MainWindow for eventual processing by DigitizeStateAbstractBase subclasses.
  void signalKeyPress (Qt::Key, bool atLeastOneSelectedItem);

  /// Send mouse move to MainWindow for eventual display of cursor coordinates in StatusBar
  void signalMouseMove (QPointF);

  /// Send mouse press to MainWindow for creating one or more Points
  void signalMousePress (QPointF);

  /// Send mouse release to MainWindow for moving Points.
  void signalMouseRelease (QPointF);

  /// Send wheel event to MainWindow for zooming in
  void signalViewZoomIn();

  /// Send wheel event to MainWindow for zooming out
  void signalViewZoomOut();

public slots:
  /// Receive drag and drop regression test url
  void slotDropRegression (QString);

private:
  GraphicsView();

  bool handleDropEvent (const QString &possibleDigFileName,
                        bool hasUrls,
                        const QUrl &urlFirst,
                        bool hasImage,
                        const QImage &image);
  QStringList pointIdentifiersFromSelection (const QList<QGraphicsItem*> &items) const;
  bool inBounds (const QPointF &posScreen);

};

#endif // GRAPHICSVIEW_H
