#ifndef OUTPUT_H
#define OUTPUT_H

#include <stdlib.h>

#include <qstring.h>
#include <qevent.h>
#include <qwidget.h>
#include <qcolor.h>
#include <qpainter.h>
#include <qlist.h>
#include <qrect.h>
#include <qscrbar.h>
#include <qsize.h>
#include <qpaintd.h>
#include <qwmatrix.h>
#include <qpixmap.h>
#include <qapp.h>
#include <qpicture.h>
#include <qpoint.h>
#include <qtablevw.h>

class Object 
{
public:
    Object() { isSelected = FALSE; x1 = -1; x2 = -1; }
    enum {STRING, PIXMAP} type;
    void SetSelected(bool yn, int startX=0, int endX=0) { isSelected = yn; x1 = startX; x2 = endX; }
    bool IsSelected() { return isSelected; }
    int StartX() { return x1; }
    int EndX() { return x2; }
    virtual int Width() { return 0; }
    virtual int Height() { return 0; }
protected:
    bool isSelected;
    int x1, x2;
};

class ObjectString : public Object, public QString
{
public:
    ObjectString(const char *txt=0);
    virtual ~ObjectString();
    QFont &Font();
    QColor &Color();
    void SetFont(QFont &fnt);
    void SetColor(QColor &c);
    void SetInverse(bool yn) { inverse = yn; }
    bool IsInverse() { return inverse; }
    inline void DrawText(QPainter *, const char *word, int x, int y);
    virtual int Width();
    virtual int Height();
private:
    QFont font;
    QColor color;
    bool inverse;
};

class ObjectPixmap : public Object, public QPixmap
{
public:
    ObjectPixmap(const char *filename=0);
    virtual ~ObjectPixmap();
    virtual int Width() { return width(); }
    virtual int Height() { return height(); }
};

class OutputWidget;

class OutputLine
{
    friend class OutputWidget;
public:
    OutputLine();
    virtual ~OutputLine();
    void InsertObject(Object *);
    int Height() { return height; }
    int ActualHeight() { return height*numLines; }
    int NumLines() { return numLines; }
    Object *ObjectAt(int x);
    void SelectText(int x1, int x2);
    void UnselectText();
protected:
    void PaintObjects(QPainter *, int maxWidth);
    int NextSpace(int startingIndex);
    void DrawObject (int, QPainter *, int &, int &, int);
private:
    QList<Object> *objects;
    int height;
    int numLines;
};
        
class OutputWidget : public QTableView
{
    Q_OBJECT
public:
    OutputWidget(QWidget *parent=0,const char *name=0);  
    ~OutputWidget();
    QFont &CurrentFont();
    QColor &CurrentColor();
    Object *ObjectAt(int x, int y);
    virtual void setBackgroundPixmap(const QPixmap &p) { bgPixmap = p; }
public slots:
    void InsertText(const char *text);
    void NewLine();
    void InsertPixmap(const char *filename);
    void SetCurrentFont(QFont &);
    void SetCurrentColor (QColor &);
    void SetInverse(bool yn) { inverse = yn; }
    bool IsInverse() { return inverse; }
    void EnableCaching(bool);
    void UpdateLastRow();
    void SelectText(int x1, int y1, int x2, int y2);
signals:
    void Popup();
protected:
    void DrawBackground(QPainter *, int row);
    virtual int cellHeight(int);
    virtual int totalHeight();
    virtual void paintCell(QPainter *, int  row, int  col);
    virtual void resizeEvent(QResizeEvent *);
private:
    void NewTextObject();
    // void AdjustScrollBar();
    QList<OutputLine> *lines;
    ObjectString *textObj; // the current text object
    QFont currentFont;
    QColor currentColor;
    bool settingsChanged;
    int offx, offy; // offsets
    bool caching;
    bool isTextSelected;
    QList <QString> *picNames;
    QList <ObjectPixmap> *pics;
    // QScrollBar *vertScroll;
    QPoint selectPoint;
    QRect selectRect;
    int docHeight;
    bool updateAll; // after a resize we need to update all lines
    bool inverse;
    bool scrollPixmap;
    QPixmap bgPixmap;
private slots:
    void Update();
};
#endif //OUPTUT_H
