#ifndef _KVI_INPUT_H_
#define _KVI_INPUT_H_

//
//   File : kvi_input.h
//   Creation date : Sun Jan 3 1999 23:04:10 by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 1999-2002 Szymon Stefanek (pragma at kvirc dot net)
//
//   This program is FREE software. You can redistribute it and/or
//   modify it under the terms of the GNU General Public License
//   as published by the Free Software Foundation; either version 2
//   of the License, or (at your opinion) any later version.
//
//   This program is distributed in the HOPE that it will be USEFUL,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software Foundation,
//   Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#include "kvi_settings.h"

#include <qwidget.h>
#include <qpixmap.h>
#include "kvi_list.h"

#include "kvi_string.h"

//#include <qdialog.h>
#include <qtoolbutton.h>

class KviUserListView;
class KviWindow;
class KviInput;

// Default maximum buffer size.
#define KVI_INPUT_MAX_BUFFER_SIZE 400
// Border , better do not touch this
#define KVI_INPUT_BORDER 4
// Cursor blink time...just don't set it to a value less than 100 if
// you don't want to be lagged by your cursors :)
#define KVI_INPUT_BLINK_TIME 800
// Drag scroll speed...(smaller values = faster)
#define KVI_INPUT_DRAG_TIMEOUT 80
// Maximum entries in the history buffer
#define KVI_INPUT_MAX_HISTORY_ENTRIES 100

class KVIRC_API KviInputHistory
{
public:
	KviInputHistory();
	~KviInputHistory();
protected:
	KviPtrList<QString> * m_pStringList;
public:
	void add(QString * s);
	KviPtrList<QString> * list(){ return m_pStringList; };
	void save(const char * filename);
	void load(const char * filename);
};


class KVIRC_API KviInputEditor : public QWidget
{
	// friend class KviUserParser;
	//Q_PROPERTY( int KviProperty_FocusOwner READ heightHint )
	Q_PROPERTY( int TransparencyCapable READ heightHint )

	Q_OBJECT
public:
	KviInputEditor(KviInput * par,KviWindow *wnd,KviUserListView * view = 0);
	~KviInputEditor();
protected:

	QString                  m_szTextBuffer;
	int                      m_iCursorPosition;
	int                      m_iFirstVisibleChar;
	int                      m_iSelectionBegin;
	int                      m_iSelectionEnd;

	unsigned char            m_iCurFore;
	unsigned char            m_iCurBack;
	bool                     m_bCurBold;
	bool                     m_bCurUnderline;

	int                      m_iBlockLen;
	int                      m_iBlockWidth;
	bool                     m_bControlBlock;

	bool                     m_bCursorOn;

	int                      m_iCursorTimer;
	int                      m_iDragTimer;

	int                      m_iLastCursorXPosition;
	int                      m_iSelectionAnchorChar;

	// History stuff
	KviPtrList<QString>    * m_pHistory;
	int                      m_iCurHistoryIdx;

	KviStr                   m_szSaveTextBuffer;

	// Nick completion
	KviUserListView        * m_pUserListView;
	KviStr                   m_szLastCompletedNick;
	KviStr                   m_szLastCompletionBuffer;
	int                      m_iLastCompletionCursorPosition;
	int                      m_iLastCompletionCursorXPosition;
	int                      m_iLastCompletionFirstVisibleChar;

	bool                     m_bUpdatesEnabled;
	KviStr                   m_szAltKeyCode;
	KviWindow              * m_pKviWindow;
	KviInput               * m_pInputParent;

public:
	int  heightHint() const;
	void setText(const QString &text);
	void insertChar(QChar c);
	void insertText(const KviStr & text);
	void insertText(const QString &text);
	void applyOptions();
private:
	void replaceWordBeforeCursor(const KviStr &word,const KviStr &replacement,bool bRepaint = true);
	void getWordBeforeCursor(KviStr &buffer,bool * bIsFirstWordInLine);
	void runUpToTheFirstVisibleChar();
	void extractNextBlock(int idx,QFontMetrics & fm,int curXPos,int maxXPos);
	void drawTextBlock(QPainter *pa,QFontMetrics & fm,int curXPos,int textBaseline,int idx,int len,int wdth);
	QChar getSubstituteChar(unsigned short control_code);
	void moveRightFirstVisibleCharToShowCursor();
	void repaintWithCursorOn();
	void selectOneChar(int pos);
	int  charIndexFromXPosition(int xPos);
	int  xPositionFromCharIndex(int chIdx);
	void killDragTimer();
	void handleDragSelection();
	void end();
	void home();
	bool hasSelection();
	void moveCursorTo(int idx,bool bRepaint = true);
	void returnPressed(bool bRepaint = true);
	void completion(bool bShift);
	void standardNickCompletion(bool bAddMask,KviStr &word,bool bFirstWordInLine);
	void resizeMemBuffer();
	void recalcFontMetrics();
public slots:
	void copy();
	void cut();
	void paste();
	void pasteWithConfirmation();
    void pasteSlow();
	void selectAll();
	void clear();
protected:
	virtual void paintEvent(QPaintEvent *);
	virtual void resizeEvent(QResizeEvent *);
	virtual void timerEvent(QTimerEvent *e);
	virtual void focusInEvent(QFocusEvent *);
	virtual void focusOutEvent(QFocusEvent *);
	virtual void keyPressEvent(QKeyEvent *e);
	virtual void keyReleaseEvent(QKeyEvent *e);
	virtual void mousePressEvent(QMouseEvent *e);
	virtual void mouseReleaseEvent(QMouseEvent *);
	virtual void dragEnterEvent(QDragEnterEvent *e);
	virtual void dropEvent(QDropEvent *e);
};


class KviScriptEditor;

class KVIRC_API KviInput : public QWidget
{
	Q_OBJECT
public:
	KviInput(KviWindow *par,KviUserListView * view = 0);
	~KviInput();
public:
	KviWindow       * m_pWindow;
	KviInputEditor  * m_pInputEditor;
	KviScriptEditor * m_pMultiLineEditor;
	QToolButton     * m_pMultiEditorButton;
	QToolButton     * m_pHistoryButton;

protected:
	virtual void resizeEvent(QResizeEvent * e);
	virtual void focusInEvent(QFocusEvent * e);
	virtual void setFocusProxy(QWidget * w);
	virtual void keyPressEvent(QKeyEvent * e);
public slots:
	void multilineEditorButtonToggled(bool bOn);
	void historyButtonClicked();
public:
	void multiLinePaste(const KviStr &text);
	int  heightHint() const;
	void setText(const QString &text);
	void insertChar(char c);
	void insertText(const KviStr & text);
	void applyOptions();
};




#endif //_KVI_INPUT_H_
