#ifndef _KVI_USERLISTVIEW_H_
#define _KVI_USERLISTVIEW_H_

//
//   File : kvi_userlistview.h
//   Creation date : Tue Aug 1 2000 21:03:41 by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 1999-2000 Szymon Stefanek (stefanek@tin.it)
//
//   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 "kvi_string.h"
#include "kvi_ircuserdb.h"
#include "kvi_ircmask.h"

#include <time.h>
#include <qtooltip.h>
#include <qwidget.h>
#include "kvi_list.h"
#include <qasciidict.h>

class QLabel;
class QScrollBar;
class QPixmap;

class KviUserListView;
class KviUserListViewArea;

class KviWindow;

class KVIRC_API KviUserListToolTip : public QToolTip
{
public:
	KviUserListToolTip(KviUserListView *v,KviUserListViewArea * a);
	~KviUserListToolTip();
private:
	KviUserListView * m_pListView;
public:
	virtual void maybeTip(const QPoint &pnt);
	void doTip(const QRect &rct,const char * str){ tip(rct,QString(str)); };
};

#define KVI_MAX_TEMPERATURE 150
#define KVI_HOT_TEMPERATURE 100
#define KVI_HALF_HOT_TEMPERATURE 40
#define KVI_MID_TEMPERATURE 0
#define KVI_HALF_COLD_TEMPERATURE -40
#define KVI_COLD_TEMPERATURE -100
#define KVI_MIN_TEMPERATURE -150

#define KVI_USERACTION_ACTION 25
#define KVI_USERACTION_PRIVMSG 25
#define KVI_USERACTION_NOTICE 25
#define KVI_USERACTION_TOPIC 20
#define KVI_USERACTION_KICK 10
#define KVI_USERACTION_NICK -10
#define KVI_USERACTION_CHANMODE -20
#define KVI_USERACTION_JOIN -25

//
//  ACTION     30
//  NOTICE     25
//  PRIVMSG    25
//  TOPIC      20
//  KICK       10
//  OP         5
//  VOICE      5
//  DEOP      -5
//  DEVOICE   -5
//  UNBAN     -15
//  BAN       -20
//  CHANMODE  -25
//  NICK      -30
//  JOIN      -30
//

class KVIRC_API KviUserListEntry
{
	friend class KviUserListView;
	friend class KviUserListViewArea;
public:
	KviUserListEntry(KviUserListView * parent,const char * nick,KviIrcUserEntry * e,short int iFlags,bool bJoinTimeUnknown = true);
	~KviUserListEntry();
protected:
	KviUserListView  * m_pListView;
	KviStr             m_szNick;
	KviIrcUserEntry  * m_pGlobalData;
	short int          m_iFlags;
	short int          m_iTemperature;    // user temperature : 0 = neutral
	time_t             m_lastActionTime;
	time_t             m_joinTime;

	int                m_iHeight;
	bool               m_bSelected;
	KviUserListEntry * m_pNext;
	KviUserListEntry * m_pPrev;
public:
	short int flags(){ return m_iFlags; };
	KviIrcUserEntry * globalData(){ return m_pGlobalData; };
	const KviStr & nick(){ return m_szNick; };
	KviUserListEntry * next(){ return m_pNext; };
protected:
	void recalcSize();
};


typedef struct _KviUserListViewUserStats 
{
	unsigned int uTotal;           // total users on the channel
	unsigned int uActive;          // active users in the last 10 mins
	unsigned int uActiveOp;        // active operators in the last 10 minutes
	unsigned int uHot;             // hot active users
	unsigned int uHotOp;           // hot operators
	unsigned int uOp;              // total operators
	unsigned int uHalfOp;          // total halfops
	unsigned int uVoiced;          // total voiced users
	int iAvgTemperature;           // average user temperature
} KviUserListViewUserStats;


class KVIRC_API KviUserListView : public QWidget
{
	friend class KviUserListEntry;
	friend class KviUserListViewArea;
	friend class KviUserListToolTip;
	friend class KviConsole;
	friend class KviChannel;
	friend class KviQuery;
	Q_OBJECT
public:
	KviUserListView(QWidget * par,KviIrcUserDataBase * db,KviWindow * pWnd,int dictSize = 5,const char * label_text = 0,const char * name = 0);
	~KviUserListView();
protected:
	QAsciiDict<KviUserListEntry>    * m_pEntryDict;
	KviUserListEntry                * m_pTopItem;
	KviUserListEntry                * m_pHeadItem;
	KviUserListEntry                * m_pTailItem;
	KviUserListEntry                * m_pIterator;
	QLabel                          * m_pUsersLabel;
	KviUserListViewArea             * m_pViewArea;
	KviIrcUserDataBase              * m_pIrcUserDataBase;
	int                               m_iOpCount;
	int                               m_iVoiceCount;
	int                               m_iHalfOpCount;
	int                               m_iTotalHeight;
	int                               m_iFontHeight;
	KviUserListToolTip              * m_pToolTip;
	int                               m_ibEntries;
	int                               m_ieEntries;
	int                               m_iIEntries;
	KviWindow                       * m_pKviWindow;
protected:
	void maybeTip(KviUserListToolTip * tip,const QPoint &pnt);
	void triggerUpdate();
	void updateUsersLabel();
	void insertUserEntry(const char * nick,KviUserListEntry * e);
	void removeAllEntries();
	virtual void resizeEvent(QResizeEvent *);
	bool partInternal(const char * nick,bool bRemove = true);
	void setUserDataBase(KviIrcUserDataBase * db){ m_pIrcUserDataBase = db; };
	void updateScrollBarRange();
public:
	void applyOptions();
	QAsciiDict<KviUserListEntry> * entryDict(){ return m_pEntryDict; };
	KviUserListEntry * firstItem(){ return m_pHeadItem; };
	KviUserListEntry * itemAt(const QPoint &pnt,QRect * rct = 0);
	bool itemVisible(KviUserListEntry * e);

	unsigned int count(){ return m_pEntryDict->count(); };
	int opCount(){ return m_iOpCount; };
	int voiceCount(){ return m_iVoiceCount; };
	int halfOpCount(){ return m_iHalfOpCount; };

	KviUserListEntry * findEntry(const char * nick){ return m_pEntryDict->find(nick); };
	void appendSelectedNicknames(KviStr &buffer);
	KviStr * firstSelectedNickname();
	KviStr * nextSelectedNickname();
	void partAll();
	void userStats(KviUserListViewUserStats * s);
	char getUserFlag(const char * nick);
	bool part(const char * nick){ return partInternal(nick,true); };
	bool op(const char *nick,bool bOp);
	void prependUserFlag(const char * nick,KviStr &buffer);
	int flags(const char * nick);
	bool isOp(const char * nick);
	bool isVoice(const char * nick);
	bool isHalfOp(const char * nick);
	bool voice(const char *nick,bool bVoice);
	bool halfop(const char * nick,bool bHalfOp);
	void userAction(KviIrcMask *user,int actionTemperature);
	void userAction(const char *nick,int actionTemperature);
	bool nickChange(const char *oldNick,const char * newNick);
	//KviUserListEntry * join(const char *nick,const char * user,const char * host,bool bOp,bool bVoice,bool bHalfOp);
	KviUserListEntry * join(const char *nick,const char * user = 0,const char * host = 0,int iFlags = 0);
	bool avatarChanged(const char * nick);
	void enableUpdates(bool bEnable);
	void setbEntries(int num){ m_ibEntries = num; updateUsersLabel(); };
	void seteEntries(int num){ m_ieEntries = num; updateUsersLabel(); };
	void setIEntries(int num){ m_iIEntries = num; updateUsersLabel(); };
	void emitRightClick();
	void emitDoubleClick();
	bool completeNickStandard(const KviStr &begin,const KviStr &skipAfter,KviStr &buffer,bool bAppendMask);
	void completeNickBashLike(const KviStr &begin,KviPtrList<KviStr> * l,bool bAppendMask);
};

class KVIRC_API KviUserListViewArea : public QWidget
{
	friend class KviUserListView;

	Q_OBJECT
	Q_PROPERTY(int TransparencyCapable READ dummyRead)
public:
	KviUserListViewArea(KviUserListView * par);
	~KviUserListViewArea();
public:
	int dummyRead() const { return 0; };
protected:
	KviUserListView  * m_pListView;
	KviUserListEntry * m_pLastEntryUnderMouse;
	QScrollBar       * m_pScrollBar;
	QPixmap          * m_pMemBuffer;
	int                m_iLastScrollBarVal;
	int                m_iTopItemOffset;
	bool               m_bIgnoreScrollBar;
protected:
	virtual void paintEvent(QPaintEvent *);
	virtual void resizeEvent(QResizeEvent *);
	virtual void mousePressEvent(QMouseEvent *e);
	virtual void mouseMoveEvent(QMouseEvent *e);
	virtual void mouseReleaseEvent(QMouseEvent *);
	virtual void mouseDoubleClickEvent(QMouseEvent *e);
	virtual void wheelEvent(QWheelEvent *e);
protected slots:
	void scrollBarMoved(int newVal);
};


#endif //!_KVI_USERLISTVIEW_H_
