/*-*-c++-*-
 * $Id: cnconsole.h,v 1.2 2002/04/19 15:24:17 felfert Exp $
 *
 * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
 *
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *
 * Authors:
 * Michael Geselbracht (let@users.sourceforge.net)
 * Fritz Elfert (elfert@de.ibm.com)
 * Michael Holzheu (holzheu@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */
#ifndef CNCONSOLE_H
#define CNCONSOLE_H

#include <qwidget.h>
#include <qcolor.h>
#include <qlist.h>
#include <qpixmap.h>
#include <qstringlist.h>

#include "cstring.h"
#include "ctextring.h"
#include "crashtypes.h"
#include "ctextrange.h"
#include "ctableview.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

class QLcrashApp;

class QStringList;
class QFont;
class QTimer;

/**A console widget with command history
support for coloured text.
  *@author Michael Geselbracht
  */

class CNConsole : public QTableView {
   Q_OBJECT

public:
	CNConsole(QWidget *parent, const char *name=0);
	~CNConsole();
	
	/* Appends a piece of text. It may contain newline characters. */
	void append(QString, int pos=-1);
	
	/* Returns the  maximum number of lines of this console. */
	inline unsigned int maxLines() const {
		return oMaxLines;
	}
	
	/* Specify the color for the next inserted text lines. */
	inline void setColor(QColor color) {
		oColor = color;
	}
	
	/* Specify cursor position. Values < 0 move the cursor two the end of the line. */
	void setCursorPosition(int col);
	
	/* Move the cursor relative to its current position. */
	bool moveCursor(int offset);
	
	/* Initialize/update command completion.  */
	void updateCommandSet(const QString& cmds);
	
	virtual void setFont(const QFont&);
	virtual QSize sizeHint() const;
	
signals:
	void sigLine(CNConsole*, QString);
	void sigClosed(CNConsole*);

public slots:
	void slotLine(QString);

protected slots:
	void slotBlink();

protected:
	virtual void resizeEvent(QResizeEvent*);
	virtual void paintCell(QPainter*, int row, int col);
	virtual void keyPressEvent(QKeyEvent*);
	virtual void closeEvent(QCloseEvent*);
	virtual void mousePressEvent(QMouseEvent*);
	virtual void mouseDoubleClickEvent(QMouseEvent*);
	virtual void mouseReleaseEvent(QMouseEvent*);
	virtual void mouseMoveEvent(QMouseEvent*);
	virtual void focusInEvent(QFocusEvent*);
	virtual void focusOutEvent(QFocusEvent*);
	
#if (QT_VERSION >= 300)
	virtual bool eventFilter(QObject* obj, QEvent* e);
#endif
	
	void updateWidth(int row);
	void keyUp();
	void keyDown();
	void doUpdate();
	void clearCursorBuffer();
	void restoreCursorBackground(int x, int y, int h, QWidget* dst);
	void saveCursorBackground(int x, int y, int h, QWidget* src);
	
	// draw a line of text
	void drawLine(QPainter*, int yPos, QString* str);
	
	// draw a line of text with a marked part. note that this method modifies the painter
	void drawMarkedLine(QPainter*, int yPos, CString* str, int line, QFontMetrics*);
	
	void drawCursor(bool moveView=false);
	QPoint textPosition(QPoint mousePos);
	
private:
	QStringList cmdMatchList(const QString& cmd);

private:
	unsigned int oMaxLines;
	QColor oColor;
	
	// the ring buffer containing the text
	CTextRing oText;
	
	// the cursor position (0,0 is top left)
	int oCursX;
	int oCursY;
	
	// used for the editing function and the return key
	int oInsertPos;
	
	QList<QString> oHistory;
	
	// show a cursor?
	bool oShowCursor;
	
	// used for cursor blinking
	QTimer* oBlinker;
	bool oBlinkShow; // toggles with each timeout
	
	// the marked region
	CTextRange oMarkedRegion;
	
	QLcrashApp*	 oApp;
	QFont oFont;
	QPixmap oCursorBuffer;
	bool oCursorBufferClear;
	
	// Command set for command completion
	QStringList oCmdSet;
	bool oCmdDisplayed;
};

#endif
