#ifndef _KVI_IRCMASK_H_
#define _KVI_IRCMASK_H_

//=============================================================================
//
//   File : kvi_ircmask.h
//   Creation date : Fri Jan 8 1999 19:50:35 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.
//
//=============================================================================

// originally this file was named kvi_ircuser.h and the class was KviIrcUser

#include "kvi_settings.h"
#include "kvi_heapobject.h"
#include "kvi_string.h"

//=============================================================================
// Irc user mask abstraction
//=============================================================================

class KVILIB_API KviIrcMask : public KviHeapObject
{
	friend class KviIrcUserList;
	friend class KviIrcUserChanList;
public:
	// Constructs an empty mask (*!*@*)
	KviIrcMask();
	// Constructs this KviIrcMask object from a string mask
	KviIrcMask(const char *szMask,char c=' ');
	// Carbon copy
	KviIrcMask(const KviIrcMask &ircUser);
	KviIrcMask(const char * nick,const char * user,const char * host);
	// Die! die!
	~KviIrcMask();
private:
	char *m_nick_ptr;
	char *m_user_ptr;
	char *m_host_ptr;
public:

	// Sets the nick for this user.<br>
	// If szNick is NULL or it points to an empty string the nick is set to "*".<br>
	void setNick(const char *szNick);
	// Sets the username for this user.<br>
	// If szUsername is NULL or it points to an empty string the username is set to "*".<br>
	void setUsername(const char *szUsername);
	// Sets the host for this user.<br>
	// If szHost is NULL or it points to an empty string the host is set to "*".<br>
	void setHost(const char *szHost);
	// Sets the host , nick and username extracting it from an irc mask:<br>
	// nick!user@host<br>
	// The mask is terminated by end-of string null character or a character equal to c in the string.<br>
	// Returns the pointer to the end of the mask in the szMask string.(c or null-terminator)<br>
	const char * setMask(const char *szMask,char c=' ');
	// Sets the host , nick and username extracting it from an userhost mask:<br>
	// nick[*]=<+|->user@host<br>
	// The mask is terminated by end-of string null char or a space character.<br>
	// Returns the pointer to the next non-space char in the szMask string or to the null-terminator<br>
	// If there are no more masks avaiable.
	// WARNING : the szMask pointer can NOT be NULL
	const char *setUserhostMask(const char *szMask);
	// Returns the nick of this user.<br>
	// In the worst case you get a string == "*"<br>
	const char *nick() const { return m_nick_ptr; };
	// DEPRECATED!
	const char *username() const { return m_user_ptr; };
	const char *user() const { return m_user_ptr; };
	const char *host() const { return m_host_ptr; };

	bool hasNick() const;
	bool hasUsername() const;
	bool hasHost() const;
	bool hasMask() const;
	bool hasNumericHost() const;
	// Retuns in szMask the specified (if possible) mask of this user.<br>
	// If the host or username are not known , the mask may contain less information
	// than requested.<br>
	// Mask types:<br>
	// 0 : nick!~user@machine.host.top (nick!~user@XXX.XXX.XXX.XXX) (default)<br>
	// 1 : nick!~user@*.host.top       (nick!~user@XXX.XXX.XXX.*)<br>
	// 2 : nick!~user@*<br>
	// 3 : nick!*@machine.host.top    (nick!*@XXX.XXX.XXX.XXX)<br>
	// 4 : nick!*@*.host.top          (nick!*@XXX.XXX.XXX.*)<br>
	// 5 : nick!*@*<br>
	// 6 : *!~user@machine.host.top    (*!~user@XXX.XXX.XXX.XXX)<br>
	// 7 : *!~user@*.host.top          (*!~user@XXX.XXX.XXX.*)<br>
	// 8 : *!~user@*<br>
	// 9 : *!*@machine.host.top       (*!*@XXX.XXX.XXX.XXX)<br>
	// 10: *!*@*.host.top             (*!*@XXX.XXX.XXX.*)<br>
	// 11 : nick!user@machine.host.top    (nick!user@XXX.XXX.XXX.XXX)<br>
	// 12 : nick!user@*.host.top          (nick!user@XXX.XXX.XXX.*)<br>
	// 13 : nick!user@*<br>
	// 14 : *!user@machine.host.top    (*!user@XXX.XXX.XXX.XXX)<br>
	// 15 : *!user@*.host.top          (*!user@XXX.XXX.XXX.*)<br>
	// 16 : *!user@*<br>
	// If some data is missing , these types may change:<br>
	// For example , if hostname is missing , the mask type 3 may be reduced to type 5
	// DEPRECATED: use the version below!
	void mask(KviStr &szMask,int mask_type = 0);
	
	enum MaskType
	{
		NickUserHost = 0,        // nick!~user@machine.host.top (nick!~user@XXX.XXX.XXX.XXX) (default)
		NickUserNet = 1,         // 1 : nick!~user@*.host.top       (nick!~user@XXX.XXX.XXX.*)
		NickUser = 2,            // 2 : nick!~user@*
		NickHost = 3,            // 3 : nick!*@machine.host.top    (nick!*@XXX.XXX.XXX.XXX)
		NickNet = 4,             // 4 : nick!*@*.host.top          (nick!*@XXX.XXX.XXX.*)
		Nick = 5,                // 5 : nick!*@*
		UserHost = 6,            // 6 : *!~user@machine.host.top    (*!~user@XXX.XXX.XXX.XXX)
		UserNet = 7,             // 7 : *!~user@*.host.top          (*!~user@XXX.XXX.XXX.*)
		User = 8,                // 8 : *!~user@*
		Host = 9,                // 9 : *!*@machine.host.top       (*!*@XXX.XXX.XXX.XXX)
		Net = 10,                // 10: *!*@*.host.top             (*!*@XXX.XXX.XXX.*)
		NickCleanUserHost = 11,  // 11 : nick!user@machine.host.top    (nick!user@XXX.XXX.XXX.XXX)
		NickCleanUserNet = 12,   // 12 : nick!user@*.host.top          (nick!user@XXX.XXX.XXX.*)
		NickCleanUser = 13,      // 13 : nick!user@*
		CleanUserHost = 14,      // 14 : *!user@machine.host.top    (*!user@XXX.XXX.XXX.XXX)
		CleanUserNet = 15,       // 15 : *!user@*.host.top          (*!user@XXX.XXX.XXX.*)
		CleanUser = 16           // 16 : *!user@*
	};
	
	void mask(QString &szMask,MaskType eMaskType = NickCleanUserHost) const;
	bool hasWildNick();

	// Wild external matches (this and external are wild)

//	bool matches(const char *szMask);
//	// passing 0 as one of params here means that it is a match by default
//	bool matches(const char *nick,const char *user,const char *host);
	bool matches(const KviIrcMask &mask) const;


	// Fixed external matches  (this is wild , external is fixed)
	bool matchesFixed(const char * nick,const char * user,const char * host) const;
	bool matchesFixed(const char * szMask) const;
	bool matchesFixed(const KviIrcMask &mask) const;

	// Fixed internal matches (this is fixed , external is wild)
	bool matchedBy(const char * szMask) const;
	bool matchedBy(const KviIrcMask &mask) const { return mask.matchesFixed(*this); };

	int nonWildChars();
	bool operator==(const KviIrcMask &user);
private:
	int getIpDomainMaskLen() const;
	char *getHostDomainMaskPtr() const;
};

inline bool KviIrcMask::hasNick() const
{ return ((*m_nick_ptr != '*')||(*(m_nick_ptr+1) != '\0')); }
inline bool KviIrcMask::hasUsername() const
{ return ((*m_user_ptr != '*')||(*(m_user_ptr+1) != '\0')); }
inline bool KviIrcMask::hasHost() const
{ return ((*m_host_ptr != '*')||(*(m_host_ptr+1) != '\0')); }
inline bool KviIrcMask::hasMask() const
{ return  ( ( (*m_nick_ptr != '*') || (*(m_nick_ptr+1) != '\0') ) ||
            ( (*m_user_ptr != '*') || (*(m_user_ptr+1) != '\0') ) ||
			( (*m_host_ptr != '*') || (*(m_host_ptr+1) != '\0') ) ); }




#endif //_KVI_IRCMASK_H_
