/* brushlib - The MyPaint Brush Library (demonstration project)
 * Copyright (C) 2013 POINTCARRE SARL / Sebastien Leon email: sleon at pointcarre.com
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 */
 
#ifndef MYPAINTVIEW_H
#define MYPAINTVIEW_H

#include <QWidget>
#include <QImage>
#include <QPoint>
#include <QTabletEvent>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QMainWindow>
#include <QDockWidget>
#include <QPushButton>
#include <QLayout>
#include "PuMPBrushes.h"

#undef TRUE   // redeclared in mypaint !
#undef FALSE
#include "mypaint-surface.h"
#include "mypaint-tiled-surface.h"
#include "mypaint-brush.h"


class Tile;
// The drawing surface : will display the result of mouse/tablet press events
// and contains the current brush & the tiles in a basic 2D table...
class MypaintView : public QGraphicsView
{
  Q_OBJECT

public:
  MypaintView(QWidget* p_parent): QGraphicsView(p_parent), mp_brush(NULL) { Init(); }
  virtual ~MypaintView();
  enum { k_center = 50, k_max = 2*k_center, k_tile_dim = 64 };

protected:
  virtual void tabletEvent       ( QTabletEvent *event );
  virtual void mouseMoveEvent    ( QMouseEvent * event );
  virtual void mousePressEvent   ( QMouseEvent * event );
  virtual void mouseReleaseEvent ( QMouseEvent * event );

private:
  void  Init();
  float GetDTime(); // return deltat Time since m_lastTimeEvent and update it to current time

  QGraphicsScene      m_scene;
  float               m_lastTimeEvent;
  MyPaintBrush*       mp_brush;
  MyPaintTiledSurface m_tile;
  QColor              m_color;

public:
  // TILE MANAGEMENT :
  // very basic tile engine. Each tile is 128x128 pixels (biggest image is 128000 x 128000 pxls)
  // Only the requested tile are created
  Tile*          GetTileFromPos (const QPoint& pos) { return GetTileFromIdx(GetTileIndex( pos )); }
  Tile*          GetTileFromIdx (const QPoint& idx);
  inline bool    CheckIndex     (uint n) { return (n<k_max); }
  inline QPoint  GetTilePos     (const QPoint& idx) { return QPoint(k_tile_dim*idx.x(), k_tile_dim*idx.y()); }
  inline QPoint  GetTileIndex   (const QPoint& pos) { return QPoint(pos.x()/k_tile_dim, pos.y()/k_tile_dim); }
  inline QPointF GetTileFIndex  (const QPoint& pos) { return QPointF((qreal)pos.x()/k_tile_dim, (qreal)pos.y()/k_tile_dim); }
protected:
  Tile* m_tileTable [k_center*2][k_center*2]; // each allocated image is shown using the graphics view

public slots:
  void BrushSelected      (const QByteArray& content);
  void BtnChgColorPressed ();
};

// Very few things to do in this class... Just make the glue between
// the brush library widget & the drawing surface...
class MyPaintWindow : public QMainWindow
{
  Q_OBJECT
public:
  MyPaintWindow():QMainWindow(), mp_view(NULL), mp_brushes(NULL), mp_colorBtn(NULL)
  {
    // Central widget:
    mp_view = new MypaintView(NULL);
    setCentralWidget (mp_view);

    // Add a color selector:
    QDockWidget* p_dockColor = new QDockWidget("Color selection");
    mp_colorBtn = new QPushButton("Click to select another brush color...");
    mp_colorBtn->setMinimumHeight(60);
    mp_colorBtn->setStyleSheet( "color: white; background-color: black;" );
    p_dockColor->setWidget (mp_colorBtn);
    addDockWidget ( Qt::RightDockWidgetArea, p_dockColor );

    // Add a docked widget
    QDockWidget* p_dockBrush = new QDockWidget("Brush Library");
    mp_brushes = new PuMPBrushes( "brushes", NULL);
    p_dockBrush->setWidget   (mp_brushes);
    addDockWidget ( Qt::RightDockWidgetArea, p_dockBrush );
	
    connect(mp_colorBtn, SIGNAL(pressed ()), mp_view, SLOT(BtnChgColorPressed()));
    connect(mp_brushes,  SIGNAL(BrushSelected(const QByteArray&)), mp_view, SLOT(BrushSelected(const QByteArray&)));
    resize(800, 700);
    mp_brushes->SelectDefaultBrush();
  }
protected:
  MypaintView* mp_view;
  PuMPBrushes* mp_brushes;
  QPushButton* mp_colorBtn;
};

#endif
