//
// Class: documentWidet
//
// Widget for displaying TeX DVI files.
// Part of KDVI- A previewer for TeX DVI files.
//
// (C) 2004 Stefan Kebekus. Distributed under the GPL.


#ifndef _documentwidget_h_
#define _documentwidget_h_

#include <qtimer.h> 
#include <qwidget.h>
#include <qpixmap.h>

class CenteringScrollview;
class documentPageCache;
class QPaintEvent;
class QMouseEvent;
class textSelection;

class documentWidget : public QWidget
{
  Q_OBJECT

public:
  documentWidget(QWidget *parent, CenteringScrollview *sv, QSize size, 
                 documentPageCache *cache, textSelection *documentSelection, const char *name);

  void          setPageNumber(Q_UINT16 pageNr);
  Q_UINT16      getPageNumber() {return pageNr;};

  /** Returns the size of the widget without the page shadow. */
  QSize pageSize();

  /** Returns the bounding rectangle of the widget without the page shadow. */
  QRect pageRect();

public slots:
  void          selectAll(void);
  void          flash(int);

  /** This slot is called by the 'Selection', when text in a different
      page is selected */
  void          selectionPageChanged(void);

  /** Sets the size of the widget so that the page is of the given size.
      The widget gets slightly bigger because of the page shadow. */
  void setPageSize(const QSize&);
  void setPageSize(int width, int height);

signals:
  /** Passed through to the top-level kpart. */
  void          setStatusBarText( const QString& );
  void          localLink( const QString& );

  /** Emitted when the widget wants to be shown, e.g., because a
      'flash' takes place at coordinate 'y' */
  void          showMe(QWidget *wdg, Q_UINT16 y);

  /** This signal is emitted when the widget resizes itself */
  void          resized(void);

protected:
  virtual void  paintEvent (QPaintEvent *);
  virtual void  mousePressEvent ( QMouseEvent * e );
  virtual void  mouseReleaseEvent (QMouseEvent *);

  /** This method is used by the documentWidget to find out of the
      mouse pointer hovers over a hyperlink, and to update the
      statusbar accordingly. Scrolling with the left mouse button
      pressed, and the text copy functions are also implemented here. 
      Re-implementations of this method should do the following:
      
      0) Immediately return if pageNr == 0, i.e. if no page number has
         been set

      1) Call the standard implementation using
	  
	  documentWidget::mouseMoveEvent(e);

      2) Ignore the QMouseEvent if a mouse button is pressed

      3) If no mouse button is pressed, analyze the mouse movement and
         take appropriate actions. To set statusbar text, do
	 
	 clearStatusBarTimer.stop();
	 emit setStatusBarText( i18n("Whatever string") );

	 To clear the statusbar, use the following code

	 if (!clearStatusBarTimer.isActive())
	   clearStatusBarTimer.start( 200, TRUE );

	 This clears the statusbar after 200 msec and avoids awful
	 flickering when the mouse is swiftly moved across various
	 areas in the widget.

  */
  virtual void  mouseMoveEvent (QMouseEvent *);

protected:
  /** Methods and counters used for the animation to mark the target of
      an hyperlink. */
  int           timerIdent;
  void          timerEvent( QTimerEvent *e );
  int           animationCounter;
  int           flashOffset;

  Q_UINT16      pageNr;

  /* This timer is used to delay clearing of the statusbar. Clearing
     the statusbar is delayed to avoid awful flickering when the mouse
     moves over a block of text that contains source hyperlinks. The
     signal timeout() is connected to the method clearStatusBar() of
     *this. */
  QTimer        clearStatusBarTimer;

  /* Data structures used for marking text with the mouse */
  QPoint       firstSelectedPoint;
  QRect        selectedRectangle;

  /** Pointer to the CenteringScrollview that contains this
      widget. This pointer is used in the re-implementation of the
      paintEvent() method ---see the explanation there. */
  CenteringScrollview *scrollView;
  documentPageCache *documentCache;
  textSelection *selection;

  enum underlineModes {UL_Enabled = 0, UL_Disabled = 1, UL_OnlyOnHover = 2};

  /** This is set to the index of the link over which the mouse pointer currently resides,
      and -1 if the no link is hovered.
      Is used when "Underline Links" is set to "Only on Hover". */
  int indexOfUnderlinedLink;

private slots:
  /** This slot emits the signal setStatusBarText(QString::null) to
      clear the status bar. It is connected to the timeout slot of the
      clearStatusBarTimer. */
  void clearStatusBar();

private:
    /** Color used by in the shadow drawing to check if the background color has been changed. */
  static QColor backgroundColorForCorners;

  /** Internal storages used in the shadow drawing routines in the
      drawContents method.*/
  static QPixmap URShadow, BRShadow, BLShadow;

  /** The following tables store grey values for roundish shadow
      corners. They were shamelessly stolen from kdelibs/kdefx/kstyle.cpp. */
  static const int bottom_right_corner[16];
  static const int bottom_left_corner[16];
  static const int shadow_strip[4];
};



#endif
