#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) 2000-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_ircuserdb.h"
#include "kvi_ircmask.h"
#include "kvi_time.h"

#include <time.h>
#include "kvi_tal_tooltip.h"
#include <tqwidget.h>
#include "kvi_pointerlist.h"
#include "kvi_pointerhashtable.h"
#include "kvi_toolwindows_container.h"

class TQLabel;
class TQScrollBar;

class KviUserListView;
class KviUserListViewArea;
class KviConsole;
class KviWindow;

#define KVI_USERLISTVIEW_GRIDTYPE_3DGRID 0
#define KVI_USERLISTVIEW_GRIDTYPE_3DBUTTONS 1
#define KVI_USERLISTVIEW_GRIDTYPE_PLAINGRID 2
#define KVI_USERLISTVIEW_GRIDTYPE_DOTGRID 3

#define KVI_USERLISTVIEW_GRIDTYPE_MAXIMUM 3
#define KVI_USERLISTVIEW_GRIDTYPE_DEFAULT 0

class KVIRC_API KviUserListToolTip : public KviTalToolTip
{
public:
	KviUserListToolTip(KviUserListView *v,KviUserListViewArea * a);
	virtual ~KviUserListToolTip();
private:
	KviUserListView * m_pListView;
public:
	virtual void maybeTip(const TQPoint &pnt);
	void doTip(const TQRect &rct,const TQString &str){ tip(rct,str); };
};



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

	int                m_iHeight;
	bool               m_bSelected;
	KviUserListEntry * m_pNext;
	KviUserListEntry * m_pPrev;
public:
	short int flags() const { return m_iFlags; };
	KviIrcUserEntry * globalData(){ return m_pGlobalData; };
	const TQString &nick() const { return m_szNick; };
	KviUserListEntry * next(){ return m_pNext; };
	bool color(TQColor& color);
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
	unsigned int uChanAdmin;       // total channel administrators
	unsigned int uChanOwner;       // total channel owners
	unsigned int uUserOp;          // total userops (uops)
	int iAvgTemperature;           // average user temperature
} KviUserListViewUserStats;


class KVIRC_API KviUserListView : public KviWindowToolWidget
{
	friend class KviUserListEntry;
	friend class KviUserListViewArea;
	friend class KviUserListToolTip;
	friend class KviConsole;
	friend class KviChannel;
	friend class KviQuery;
	TQ_OBJECT
  
public:
	KviUserListView(TQWidget * parent,KviWindowToolPageButton* button,KviIrcUserDataBase * db,KviWindow * pWnd,int dictSize = 5,const TQString &label_text = TQString(),const char * name = 0);
	~KviUserListView();
protected:
	KviPointerHashTable<TQString,KviUserListEntry>         * m_pEntryDict;
	KviUserListEntry                * m_pTopItem;
	KviUserListEntry                * m_pHeadItem;
	KviUserListEntry                * m_pTailItem;
	KviUserListEntry                * m_pIterator;
	TQLabel                          * m_pUsersLabel;
	KviUserListViewArea             * m_pViewArea;
	KviIrcUserDataBase              * m_pIrcUserDataBase;
	int                               m_iSelectedCount;
	int                               m_iOpCount;
	int                               m_iVoiceCount;
	int                               m_iHalfOpCount;
	int                               m_iChanAdminCount;
	int                               m_iChanOwnerCount;
	int                               m_iUserOpCount;
	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 TQPoint &pnt);
	void triggerUpdate();
	void updateUsersLabel();
	void insertUserEntry(const TQString  &nick,KviUserListEntry * e);
	void removeAllEntries();
	virtual void resizeEvent(TQResizeEvent *);
	bool partInternal(const TQString &nick,bool bRemove = true);
	void setUserDataBase(KviIrcUserDataBase * db){ m_pIrcUserDataBase = db; };
	void updateScrollBarRange();
public:
	void updateArea();
	void select(const TQString&);
	void applyOptions();
	KviPointerHashTable<TQString,KviUserListEntry> * entryDict(){ return m_pEntryDict; };
	KviUserListEntry * firstItem(){ return m_pHeadItem; };
	KviUserListEntry * itemAt(const TQPoint &pnt,TQRect * rct = 0);
	bool itemVisible(KviUserListEntry * e);
	KviWindow * window(){ return m_pKviWindow; };

	unsigned int count(){ return m_pEntryDict->count(); };
	int selectedCount(){ return m_iSelectedCount; };
	int opCount(){ return m_iOpCount; };
	int voiceCount(){ return m_iVoiceCount; };
	int chanOwnerCount(){ return m_iChanOwnerCount; };
	int chanAdminCount(){ return m_iChanAdminCount; };
	int halfOpCount(){ return m_iHalfOpCount; };
	int userOpCount(){ return m_iUserOpCount; };

	KviUserListEntry * findEntry(const TQString &nick){ return nick.isEmpty() ? 0 : m_pEntryDict->find(nick); };
	void appendSelectedNicknames(TQString &buffer);
	TQString * firstSelectedNickname();
	TQString * nextSelectedNickname();
	void partAll();
	void partAllButOne(const TQString &whoNot);
	void userStats(KviUserListViewUserStats * s);
	int getUserModeLevel(const TQString &nick);
	kvi_time_t getUserJoinTime(const TQString &nick);
	kvi_time_t getUserLastActionTime(const TQString &nick);
	char getUserFlag(KviUserListEntry * e);
	char getUserFlag(const TQString &nick){ return getUserFlag(m_pEntryDict->find(nick)); };
	bool part(const TQString &nick){ return partInternal(nick,true); };
	bool op(const TQString &nick,bool bOp);
	void prependUserFlag(const TQString &nick,TQString &buffer);
	int flags(const TQString &nick);
	bool isOp(const TQString &nick,bool bAtLeast = false);
	bool isVoice(const TQString &nick,bool bAtLeast = false);
	bool isHalfOp(const TQString &nick,bool bAtLeast = false);
	bool isChanAdmin(const TQString &nick,bool bAtLeast = false);
	bool isChanOwner(const TQString &nick,bool bAtLeast = false);
	bool isUserOp(const TQString &nick,bool bAtLeast = false);
	bool voice(const TQString &nick,bool bVoice);
	bool setChanAdmin(const TQString &nick,bool bChanAdmin);
	bool setChanOwner(const TQString &nick,bool bChanOwner);
	bool halfop(const TQString &nick,bool bHalfOp);
	bool userop(const TQString &nick,bool bUserOp);
	void userAction(KviIrcMask *user,int actionTemperature);
	bool userActionVerifyMask(const TQString &nick,const TQString &user,const TQString &host,int actionTemperature,TQString &oldUser,TQString &oldHost);
	void userAction(const TQString &nick,const TQString &user,const TQString &host,int actionTemperature);
	void userAction(const TQString &nick,int actionTemperature);
	bool nickChange(const TQString &oldNick,const TQString &newNick);
	//KviUserListEntry * join(const char *nick,const char * user,const char * host,bool bOp,bool bVoice,bool bHalfOp);
	KviUserListEntry * join(const TQString &nick,const TQString &user = TQString(),const TQString &host = TQString(),int iFlags = 0);
	bool avatarChanged(const TQString &nick);
	void enableUpdates(bool bEnable);
	void setMaskEntries(char type, int num);
	void emitRightClick();
	void emitDoubleClick();
	bool completeNickStandard(const TQString &begin,const TQString &skipAfter,TQString &buffer,bool bAppendMask);
	void completeNickBashLike(const TQString &begin,KviPointerList<TQString> * l,bool bAppendMask);
};

class KVIRC_API KviUserListViewArea : public TQWidget
{
	friend class KviUserListView;

	TQ_OBJECT
  
	TQ_PROPERTY(int TransparencyCapable READ dummyRead)
public:
	KviUserListViewArea(KviUserListView * par);
	~KviUserListViewArea();
public:
	int dummyRead() const { return 0; };
protected:
	KviUserListView  * m_pListView;
	KviUserListEntry * m_pLastEntryUnderMouse;
	TQScrollBar       * m_pScrollBar;
	int                m_iLastScrollBarVal;
	int                m_iTopItemOffset;
	bool               m_bIgnoreScrollBar;
protected:
	virtual void paintEvent(TQPaintEvent *);
	virtual void resizeEvent(TQResizeEvent *);
	virtual void mousePressEvent(TQMouseEvent *e);
	virtual void mouseMoveEvent(TQMouseEvent *e);
	virtual void mouseReleaseEvent(TQMouseEvent *);
	virtual void mouseDoubleClickEvent(TQMouseEvent *e);
	virtual void wheelEvent(TQWheelEvent *e);
	virtual void keyPressEvent( TQKeyEvent * e );
protected slots:
	void scrollBarMoved(int newVal);
};


#endif //!_KVI_USERLISTVIEW_H_
