/* ====================================================================
 * Copyright (c) 2003-2006, 2008  Martin Hauner
 *                                http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

#ifndef _TEXTWIDGET_H
#define _TEXTWIDGET_H

// sc
#include "DiffInfo.h"
#include "sublib/BlockInfo.h"
#include "sublib/Cursor.h"
#include "util/types.h"
class TextModel;
class Line;
class TextPositionCalculator;
class DiffInfoModel;

// qt
#include <QtGui/QWidget>
class QRubberBand;

class TextWidget : public QWidget
{
  typedef QWidget super;
  Q_OBJECT 

public:
  enum Position { None, Left, Right, Merge };
  
  TextWidget( QWidget *parent=0, Position pos = None );
  virtual ~TextWidget();

  void setModel( DiffInfoModel *model );
  void setModel( TextModel *model, TextModel* diff );
  void setModelSize( sc::Size columns, sc::Size lines );
  TextModel* getModel() const;

  void setBlockSelection( int block );
  void clearBlockSelection();
  int getBlockSelection() const;

  int calcLineY( int line, bool optimize = false );
  
  void setEditable( bool editable );
  bool isEditable() const;

  void setRightColMark( int column );
  void enableRightColMark( bool b = true );

  //void enableCursor( bool enable );
  void enableSelection( bool enable );

  void dragEnterEvent(QDragEnterEvent* e);
  void dropEvent(QDropEvent* e);

public slots:
  void setScrollPosY(int y);
  void setScrollPosX(int x);

  void timerSelection();
  void timerCursor();
  
  void contextMenu( const QPoint& pos );

  QSize sizeHint() const;

signals:
  void blockChanged( int b );
  //void widthChanged( int w );
  //void heightChanged( int h );
  void xChanged( int x );
  void yChanged( int y );
  void sizeChanged();
  void mouseLine( int y );

  void fileDropped( const QString& f );

protected:
  //void resizeEvent( QResizeEvent * );
  bool event( QEvent* e );
  void paintEvent( QPaintEvent* );
  void keyPressEvent( QKeyEvent* );
  void keyReleaseEvent( QKeyEvent* );
  void mousePressEvent( QMouseEvent* );
  void mouseReleaseEvent( QMouseEvent* );
  void mouseDoubleClickEvent( QMouseEvent* e );
  void mouseMoveEvent( QMouseEvent* );
  void focusInEvent( QFocusEvent* );
  void focusOutEvent( QFocusEvent* );

  //int width() const;
  //int height() const;

private:
  void drawLine( QPainter& pp, int x, int y, const Line& line );
  QRect calcCursorRect( const TextPositionCalculator& calc, const Cursor& c );
  QRect calcCursorRect( const Cursor& c );
  QRect calcBlockRect( const TextPositionCalculator& calc );
  QRect calcBlockRect();
  QRect calcHighlightedRect();
  Cursor calcCursorPos( int x, int y );
  const QColor& getConflictBgColor( ConflictType t );
  const QColor& getMergeBgColor( MergeType t );
  const QColor& getBgColor( ConflictType ct, MergeType mt );

  //QString getHighlightedText() const;

  void setScrollPosCursor( const Cursor& oc, const Cursor& nc );

  void moveCursorRight();
  void moveCursorLeft();
  void moveCursorDown();
  void moveCursorUp();
  void updateCursor();

private:
  TextModel*     _model;        // data source
  TextModel*     _diff;         // diff model for calculating line diffs
  DiffInfoModel* _info;

  sc::Size      _columns;      // pretend to have this number of columns
  sc::Size      _lines;        // pretend to have this number of lines

  int           _xpos;         // scroll position x
  int           _ypos;         // scroll position y

  bool          _enableRightColMark; // draw right column mark?
  int           _rightColMark;       // column for right column mark

  QTimer*       _tSel;         // block selection stuff
  int           _tSelCnt;
  bool          _drawSel;
  int           _selBlockNr;
  BlockInfo     _selBlock;

  QTimer*        _tCursor;     // cursor blink timer

  bool           _shiftKey;    // shift   key pressed?
  bool           _cntrlKey;    // control key pressed?

  // configuration
  bool           _editable;
  bool           _enableSelection;
  Position       _pos;
};


#endif // _TEXTWIDGET_H
