#ifndef _KVI_IRCVIEW_H_
#define _KVI_IRCVIEW_H_
//=========================================================================================================
//
//   File : kvi_ircview.h
//   Creation date : Fri Mar 19 1999 05:39:01 by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 1999-2004 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=========================================================================================================

#include "kvi_settings.h"
#include "kvi_string.h"
#include "kvi_pointerlist.h"

#include <tqwidget.h>
#include <tqpixmap.h>      // needed

class TQScrollBar;
class TQLineEdit;
class TQFile;
class TQToolButton;
class TQFontMetrics;
class KviTalPopupMenu;

class KviWindow;
class KviFrame;
class KviConsole;
class KviIrcViewToolWidget;
class KviIrcViewToolTip;

typedef struct _KviIrcViewLineChunk KviIrcViewLineChunk;
typedef struct _KviIrcViewWrappedBlock KviIrcViewWrappedBlock;
typedef struct _KviIrcViewLine KviIrcViewLine;
typedef struct _KviIrcViewWrappedBlockSelectionInfoTag KviIrcViewWrappedBlockSelectionInfo;

#define KVI_IRCVIEW_INVALID_LINE_MARK_INDEX 0xffffffff

class KVIRC_API KviIrcView : public TQWidget
{
	TQ_OBJECT
  
	TQ_PROPERTY(int TransparencyCapable READ dummyRead)
	TQ_PROPERTY(bool usePaintOnScreen READ getPaintOnScreen WRITE setPaintOnScreen)
public:
	friend class KviIrcViewToolTip;
	friend class KviIrcViewToolWidget;
public:
	KviIrcView(TQWidget *parent,KviFrame *pFrm,KviWindow *pWnd);
	~KviIrcView();
public:
	int dummyRead() const { return 0; };
	bool getPaintOnScreen() const { return 0;};
	void setPaintOnScreen(bool bFlag){} ;
private:
//	TQDate                       m_lastLogDay;
	int		 	                m_iFlushTimer;
	KviIrcViewLine            * m_pFirstLine;
	KviIrcViewLine            * m_pCurLine;    // Bottom line in the view
	KviIrcViewLine            * m_pLastLine;
	KviIrcViewLine            * m_pCursorLine;
	unsigned int                m_uLineMarkLineIndex;

	// Highliting of links
	KviIrcViewWrappedBlock    * m_pLastLinkUnderMouse;
	int                         m_iLastLinkRectTop;
	int                         m_iLastLinkRectHeight;

	int                         m_iNumLines;
	int                         m_iMaxLines;

	unsigned int                m_uNextLineIndex;

	TQPixmap                   * m_pPrivateBackgroundPixmap;
	TQScrollBar                * m_pScrollBar;
	TQToolButton               * m_pToolsButton;
	KviTalPopupMenu           * m_pToolsPopup;

	KviIrcViewToolWidget      * m_pToolWidget;

	int                         m_iLastScrollBarValue;

	// Font related stuff (needs precalculation!)
	int                         m_iFontLineSpacing;
	int                         m_iFontLineWidth;
	int                         m_iFontDescent;
	int                         m_iFontCharacterWidth[256];    //1024 bytes fixed

	int                         m_iWrapMargin;
	int                         m_iMinimumPaintWidth;
	int                         m_iRelativePixmapY;
	int                         m_iIconWidth;
	int                         m_iIconSideSpacing;

	TQPoint                      m_mousePressPos;
	TQPoint                      m_mouseCurrentPos;

	// Selection
	int                         m_iSelectionBegin;
	int                         m_iSelectionTop;
	int                         m_iSelectionEnd;
	int                         m_iSelectionBottom;
	int                         m_iSelectionLeft;
	int                         m_iSelectionRight;

	bool                        m_bMouseIsDown;
	bool                        m_bShiftPressed;

	bool                        m_bSkipScrollBarRepaint;
	int                         m_iSelectTimer;
	int                         m_iMouseTimer;
	//int                         m_iTipTimer;
	TQString                     m_szLastSelection;
	TQString                     m_szLastSelectionLine;
	KviWindow                 * m_pKviWindow;
	KviIrcViewWrappedBlockSelectionInfo * m_pWrappedBlockSelectionInfo;
	TQFile                     * m_pLogFile;
	KviFrame                  * m_pFrm;
	bool                        m_bAcceptDrops;
	int                         m_iUnprocessedPaintEventRequests;
	bool                        m_bPostedPaintEventPending;
	KviPointerList<KviIrcViewLine> * m_pMessagesStoppedWhileSelecting;
	KviIrcView                * m_pMasterView;
	TQFontMetrics              * m_pFm;               // assume this valid only inside a paint event (may be 0 in other circumstances)
	
	TQMouseEvent              *  m_pLastEvent;
	
	KviIrcViewToolTip         * m_pToolTip;
	bool m_bHaveUnreadedHighlightedMessages;
	bool m_bHaveUnreadedMessages;
public:
	void checkLogDate();
	void clearUnreaded();
	void applyOptions();
	void enableDnd(bool bEnable);
	bool haveUnreadedMessages() { return m_bHaveUnreadedMessages; };
	bool haveUnreadedHighlightedMessages() { return m_bHaveUnreadedHighlightedMessages; };
	enum AppendTextFlags { NoRepaint = 1, NoTimestamp = 2, SetLineMark = 4 };
	void appendText(int msg_type,const kvi_wchar_t *data_ptr,int iFlags = 0);
	void clearLineMark(bool bRepaint=false);
	bool hasLineMark(){ return m_uLineMarkLineIndex != KVI_IRCVIEW_INVALID_LINE_MARK_INDEX; };
	void removeHeadLine(bool bRepaint=false);
	void emptyBuffer(bool bRepaint=true);
	void getTextBuffer(TQString &buffer);
	void setMaxBufferSize(int maxBufSize,bool bRepaint=true);
	int  maxBufferSize(){ return m_iMaxLines; }; //Never used ?
	bool saveBuffer(const char *filename);
	void findNext(const TQString& szText,bool bCaseS = false,bool bRegExp = false,bool bExtended = false);
	void findPrev(const TQString& szText,bool bCaseS = false,bool bRegExp = false,bool bExtended = false);
	KviWindow * parentKviWindow(){ return m_pKviWindow; };
	KviConsole * console();
	// A null pixmap passed here unsets the private backgrdound.
	void setPrivateBackgroundPixmap(const TQPixmap &pixmap,bool bRepaint=true);
	bool hasPrivateBackgroundPixmap(){ return (m_pPrivateBackgroundPixmap != 0); };

	//==============================================================================================
	// Logging
	// Stops previous logging session too...
	bool startLogging(const TQString& fname = TQString(),bool bPrependCurBuffer = false);
	void stopLogging();
	bool isLogging(){ return (m_pLogFile != 0); };
	void getLogFileName(KviStr &buffer);
	void getLogFileName(TQString &buffer);
	//void add2Log(const char *buffer,int buf_len=-1);
	void add2Log(const TQString &szBuffer,int iMsgType=0);

	//==============================================================================================
	// Channel view splitting
	void setMasterView(KviIrcView * v);
	void splitMessagesTo(KviIrcView * v);
	void joinMessagesFrom(KviIrcView * v);
	void appendMessagesFrom(KviIrcView * v);

	void prevLine();
	void nextLine();
	void nextPage();
	void prevPage();
	virtual TQSize sizeHint() const;
	const TQString & lastLineOfText();
	const TQString & lastMessageText();
	virtual void setFont(const TQFont &f);
public slots:
	void flushLog();
	void showToolsPopup();
	void clearBuffer();
	void toggleToolWidget();
	void increaseFontSize();
	void decreaseFontSize();
	void chooseFont();
	void chooseBackground();
	void resetBackground();
signals:
	void rightClicked();
	void dndEntered();
	void fileDropped(const char *);
private:
	void setCursorLine(KviIrcViewLine * l);
	KviIrcViewLine * getVisibleLineAt(int xPos,int yPos);
	void getLinkEscapeCommand(TQString &buffer,const TQString &escape_cmd,const TQString &escape_label);
	void appendLine(KviIrcViewLine *ptr,bool bRepaint);
	void postUpdateEvent();
	void fastScroll(int lines = 1);
	const kvi_wchar_t * getTextLine(int msg_type,const kvi_wchar_t * data_ptr,KviIrcViewLine *line_ptr,bool bEnableTimeStamp = true);
	void calculateLineWraps(KviIrcViewLine *ptr,int maxWidth);
	void recalcFontVariables(const TQFontMetrics &fm,const TQFontInfo &fi);
	bool checkSelectionBlock(KviIrcViewLine * line,int left,int bottom,int bufIndex);
	void calculateSelectionBounds();
	KviIrcViewWrappedBlock * getLinkUnderMouse(int xPos,int yPos,TQRect * pRect = 0,TQString * linkCmd = 0,TQString * linkText = 0);
	void doLinkToolTip(const TQRect &rct,TQString &linkCmd,TQString &linkText);
protected:
	virtual void paintEvent(TQPaintEvent *);
	virtual void resizeEvent(TQResizeEvent *);
	virtual void mousePressEvent(TQMouseEvent *e);
	virtual void mouseRealPressEvent(TQMouseEvent *e);
	virtual void mouseReleaseEvent(TQMouseEvent *);
	virtual void mouseDoubleClickEvent(TQMouseEvent *e);
	virtual void mouseMoveEvent(TQMouseEvent *e);
	virtual void timerEvent(TQTimerEvent *e);
	virtual void dragEnterEvent(TQDragEnterEvent *e);
	virtual void dropEvent(TQDropEvent *e);
	virtual bool event(TQEvent *e);
	virtual void wheelEvent(TQWheelEvent *e);
	virtual void keyPressEvent(TQKeyEvent *e);
	void maybeTip(const TQPoint &pnt);
	virtual void leaveEvent ( TQEvent * );
protected slots:
	virtual void scrollBarPositionChanged(int newValue);
	void masterDead();
};

#endif //_KVI_IRCVIEW_H_
