/*************************************************************************
 *
 *  $RCSfile: inetmsg.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000/09/18 17:03:02 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TOOLS_INETMSG_HXX
#define _TOOLS_INETMSG_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _RTL_TEXTENC_H_
#include <rtl/textenc.h>
#endif

#ifndef _TOOLS_INETMIME_HXX
#include <tools/inetmime.hxx>
#endif

#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

class DateTime;

/*=======================================================================
 *
 * INetMessageHeader Interface.
 *
 *=====================================================================*/
class INetMessageHeader
{
	ByteString m_aName;
	ByteString m_aValue;

public:
	INetMessageHeader (void)
	{}

	INetMessageHeader (
		const ByteString& rName, const ByteString& rValue)
		: m_aName (rName), m_aValue (rValue)
	{}

	INetMessageHeader (
		const INetMessageHeader& rHdr)
		: m_aName (rHdr.m_aName), m_aValue (rHdr.m_aValue)
	{}

	~INetMessageHeader (void)
	{}

	INetMessageHeader& operator= (const INetMessageHeader& rHdr)
	{
		m_aName  = rHdr.m_aName;
		m_aValue = rHdr.m_aValue;
		return *this;
	}

	const ByteString& GetName  (void) const { return m_aName; }
	const ByteString& GetValue (void) const { return m_aValue; }

	friend SvStream& operator<< (
		SvStream& rStrm, const INetMessageHeader& rHdr)
	{
#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
		rStrm << rHdr.m_aName;
		rStrm << rHdr.m_aValue;
#else
		rStrm.WriteByteString (rHdr.m_aName);
		rStrm.WriteByteString (rHdr.m_aValue);
#endif
		return rStrm;
	}

	friend SvStream& operator>> (
		SvStream& rStrm, INetMessageHeader& rHdr)
	{
#ifdef ENABLE_BYTESTRING_STREAM_OPERATORS
		rStrm >> rHdr.m_aName;
		rStrm >> rHdr.m_aValue;
#else
		rStrm.ReadByteString (rHdr.m_aName);
		rStrm.ReadByteString (rHdr.m_aValue);
#endif
		return rStrm;
	}
};

/*=======================================================================
 *
 * INetMessage Interface.
 *
 *=====================================================================*/
class INetMessage
{
	List           m_aHeaderList;

	ULONG          m_nDocSize;
	UniString      m_aDocName;
	SvLockBytesRef m_xDocLB;

	void ListCleanup_Impl (void);
	void ListCopy (const INetMessage& rMsg);

protected:
	UniString GetHeaderName_Impl (
		ULONG nIndex, rtl_TextEncoding eEncoding) const
	{
		INetMessageHeader *p =
			(INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
		if (p)
			return UniString(p->GetName(), eEncoding);
		else
			return UniString();
	}

	UniString GetHeaderValue_Impl (
		ULONG nIndex, INetMIME::HeaderFieldType eType) const
	{
		INetMessageHeader *p =
			(INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
		if (p)
			return INetMIME::decodeHeaderFieldBody (eType, p->GetValue());
		else
			return UniString();
	}

	void SetHeaderField_Impl (
		const INetMessageHeader &rHeader, ULONG &rnIndex)
	{
		INetMessageHeader *p = new INetMessageHeader (rHeader);
		if (m_aHeaderList.Count() <= rnIndex)
		{
			m_aHeaderList.Insert (p, LIST_APPEND);
			rnIndex = m_aHeaderList.Count() - 1;
		}
		else
		{
			p = (INetMessageHeader*)(m_aHeaderList.Replace(p, rnIndex));
			delete p;
		}
	}

	void SetHeaderField_Impl (
		INetMIME::HeaderFieldType  eType,
		const ByteString          &rName,
		const UniString           &rValue,
		ULONG                     &rnIndex);

	virtual SvStream& operator<< (SvStream& rStrm) const;
	virtual SvStream& operator>> (SvStream& rStrm);

public:
	INetMessage (void) : m_nDocSize(0) {}
	virtual ~INetMessage (void);

	INetMessage (const INetMessage& rMsg)
		: m_nDocSize (rMsg.m_nDocSize),
		  m_aDocName (rMsg.m_aDocName),
		  m_xDocLB   (rMsg.m_xDocLB)
	{
		ListCopy (rMsg);
	}

	INetMessage& operator= (const INetMessage& rMsg)
	{
		m_nDocSize = rMsg.m_nDocSize;
		m_aDocName = rMsg.m_aDocName;
		m_xDocLB   = rMsg.m_xDocLB;
		ListCopy (rMsg);
		return *this;
	}

	ULONG GetHeaderCount (void) const { return m_aHeaderList.Count(); }

	UniString GetHeaderName (ULONG nIndex) const
	{
		return GetHeaderName_Impl (nIndex, RTL_TEXTENCODING_ASCII_US);
	}

	UniString GetHeaderValue (ULONG nIndex) const
	{
		return GetHeaderValue_Impl (nIndex, INetMIME::HEADER_FIELD_TEXT);
	}

	INetMessageHeader GetHeaderField (ULONG nIndex) const
	{
		INetMessageHeader *p =
			(INetMessageHeader*)(m_aHeaderList.GetObject(nIndex));
		if (p)
			return INetMessageHeader(*p);
		else
			return INetMessageHeader();
	}

	ULONG SetHeaderField (
		const UniString& rName,
		const UniString& rValue,
		ULONG            nIndex = LIST_APPEND);

	virtual ULONG SetHeaderField (
		const INetMessageHeader &rField, ULONG nIndex = LIST_APPEND);

	ULONG GetDocumentSize (void) const { return m_nDocSize; }
	void  SetDocumentSize (ULONG nSize) { m_nDocSize = nSize; }

	const UniString& GetDocumentName (void) const { return m_aDocName; }
	void  SetDocumentName (const UniString& rName) { m_aDocName = rName; }

	SvLockBytes* GetDocumentLB (void) const { return m_xDocLB; }
	void         SetDocumentLB (SvLockBytes *pDocLB) { m_xDocLB = pDocLB; }

	friend SvStream& operator<< (
		SvStream& rStrm, const INetMessage& rMsg)
	{
		return rMsg.operator<< (rStrm);
	}

	friend SvStream& operator>> (
		SvStream& rStrm, INetMessage& rMsg)
	{
		return rMsg.operator>> (rStrm);
	}
};

/*=======================================================================
 *
 * INetMessageHeaderIterator Interface.
 *
 *=====================================================================*/
class INetMessageHeaderIterator
{
	ULONG     nValueCount;
	List      aValueList;
	UniString aEmptyString;

public:
	INetMessageHeaderIterator (
		const INetMessage& rMsg, const UniString& rHdrName);
	virtual ~INetMessageHeaderIterator (void);

	ULONG GetValueCount (void) const { return nValueCount; }
	const UniString& GetValue (ULONG nIndex) const
	{
		if (nIndex < nValueCount)
		{
			return *((UniString*)(aValueList.GetObject(nIndex)));
		}
		else
		{
			return aEmptyString;
		}
	}
};

/*=======================================================================
 *
 * INetRFC822Message Interface.
 *
 *=====================================================================*/
#define INETMSG_RFC822_BCC                 0
#define INETMSG_RFC822_CC                  1
#define INETMSG_RFC822_COMMENTS            2
#define INETMSG_RFC822_DATE                3
#define INETMSG_RFC822_FROM                4
#define INETMSG_RFC822_IN_REPLY_TO         5
#define INETMSG_RFC822_KEYWORDS            6
#define INETMSG_RFC822_MESSAGE_ID          7
#define INETMSG_RFC822_REFERENCES          8
#define INETMSG_RFC822_REPLY_TO            9
#define INETMSG_RFC822_RETURN_PATH        10
#define INETMSG_RFC822_SENDER             11
#define INETMSG_RFC822_SUBJECT            12
#define INETMSG_RFC822_TO                 13

#define INETMSG_RFC822_X_MAILER           14
#define INETMSG_RFC822_RETURN_RECEIPT_TO  15

#define INETMSG_RFC822_NUMHDR             16

class INetRFC822Message : public INetMessage
{
	ULONG m_nIndex[INETMSG_RFC822_NUMHDR];

protected:
	virtual SvStream& operator<< (SvStream& rStrm) const;
	virtual SvStream& operator>> (SvStream& rStrm);

public:
	INetRFC822Message (void);
	INetRFC822Message (const INetRFC822Message& rMsg);
	virtual ~INetRFC822Message (void);

	INetRFC822Message& operator= (const INetRFC822Message& rMsg);

	static BOOL GenerateDateField (
		const DateTime& rDateTime, UniString& rDateField);
	static BOOL ParseDateField (
		const UniString& rDateField, DateTime& rDateTime);

	virtual ULONG SetHeaderField (
		const INetMessageHeader &rHeader, ULONG nIndex = LIST_APPEND);

	/** Header fields.
	 */
	void      SetBCC (const UniString& rBCC);
	UniString GetBCC (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_BCC],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetCC (const UniString& rCC);
	UniString GetCC (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_CC],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetComments (const UniString& rComments);
	UniString GetComments (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_COMMENTS],
			INetMIME::HEADER_FIELD_TEXT);
	}

	void      SetDate (const UniString& rDate);
	UniString GetDate (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_DATE],
			INetMIME::HEADER_FIELD_STRUCTURED);
	}

	void      SetFrom (const UniString& rFrom);
	UniString GetFrom (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_FROM],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetInReplyTo (const UniString& rInReplyTo);
	UniString GetInReplyTo (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_IN_REPLY_TO],
			INetMIME::HEADER_FIELD_ADDRESS); // ??? MESSAGE_ID ???
	}

	void      SetKeywords (const UniString& rKeywords);
	UniString GetKeywords (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_KEYWORDS],
			INetMIME::HEADER_FIELD_PHRASE);
	}

	void      SetMessageID (const UniString& rMessageID);
	UniString GetMessageID (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_MESSAGE_ID],
			INetMIME::HEADER_FIELD_MESSAGE_ID);
	}

	void      SetReferences (const UniString& rReferences);
	UniString GetReferences (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_REFERENCES],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetReplyTo (const UniString& rReplyTo);
	UniString GetReplyTo (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_REPLY_TO],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetReturnPath (const UniString& rReturnPath);
	UniString GetReturnPath (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_RETURN_PATH],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetReturnReceiptTo (const UniString& rReturnReceiptTo);
	UniString GetReturnReceiptTo (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_RETURN_RECEIPT_TO],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetSender (const UniString& rSender);
	UniString GetSender (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_SENDER],
			INetMIME::HEADER_FIELD_ADDRESS);
	}

	void      SetSubject (const UniString& rSubject);
	UniString GetSubject (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_SUBJECT],
			INetMIME::HEADER_FIELD_TEXT);
	}

	void      SetTo (const UniString& rTo);
	UniString GetTo (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_TO],
			INetMIME::HEADER_FIELD_TEXT);
	}

	void      SetXMailer (const UniString& rXMailer);
	UniString GetXMailer (void) const
	{
		return GetHeaderValue_Impl (
			m_nIndex[INETMSG_RFC822_X_MAILER],
			INetMIME::HEADER_FIELD_TEXT);
	}

	/** Stream operators.
	 */
	friend SvStream& operator<< (
		SvStream& rStrm, const INetRFC822Message& rMsg)
	{
		return rMsg.operator<< (rStrm);
	}

	friend SvStream& operator>> (
		SvStream& rStrm, INetRFC822Message& rMsg)
	{
		return rMsg.operator>> (rStrm);
	}
};

/*=======================================================================
 *
 * INetMIMEMessage Interface.
 *
 *=====================================================================*/
#define INETMSG_MIME_VERSION                    0
#define INETMSG_MIME_CONTENT_DESCRIPTION        1
#define INETMSG_MIME_CONTENT_DISPOSITION        2
#define INETMSG_MIME_CONTENT_ID                 3
#define INETMSG_MIME_CONTENT_TYPE               4
#define INETMSG_MIME_CONTENT_TRANSFER_ENCODING  5

#define INETMSG_MIME_NUMHDR                     6

#if 0  /* @@@ WHO HAS INTRODUCED THIS HERE FOR WHAT PURPOSE @@@ */

#define ID_MIMETYPE_DONTKNOW			0
#define ID_MIMETYPE_APP_OCTSTREAM		1
#define ID_MIMETYPE_APP_PDF				2
#define ID_MIMETYPE_APP_RTF				3
#define ID_MIMETYPE_APP_MSWORD			4
#define ID_MIMETYPE_APP_STARCALC		5
#define ID_MIMETYPE_APP_STARCHART		6
#define ID_MIMETYPE_APP_STARDRAW		7
#define ID_MIMETYPE_APP_STARIMAGE		8
#define ID_MIMETYPE_APP_STARMATH		9
#define ID_MIMETYPE_APP_STARWRITER		10
#define ID_MIMETYPE_APP_ZIP				11
#define ID_MIMETYPE_AUDIO_AIFF			12
#define ID_MIMETYPE_AUDIO_BASIC			13
#define ID_MIMETYPE_AUDIO_MIDI			14
#define ID_MIMETYPE_AUDIO_WAV			15
#define ID_MIMETYPE_IMAGE_GIF			16
#define ID_MIMETYPE_IMAGE_JPEG			17
#define ID_MIMETYPE_IMAGE_PCX			18
#define ID_MIMETYPE_IMAGE_BMP			19
#define ID_MIMETYPE_TEXT_HTML			20
#define ID_MIMETYPE_TEXT_PLAIN			21
#define ID_MIMETYPE_TEXT_URL			22
#define ID_MIMETYPE_TEXT_VCARD			23
#define ID_MIMETYPE_VIDEO_VDO			24
#define ID_MIMETYPE_VIDEO_MSVIDEO		25
#define ID_MIMETYPE_X_STARMAIL			26
#define ID_MIMETYPE_X_VRML				27
#define ID_MIMETYPE_APP_STARIMPRESS		28
#define ID_MIMETYPE_APP_STARHELP		29
#define ID_MIMETYPE_APP_STARSCHEDULE_CMB 	30
#define ID_MIMETYPE_APP_STARSCHEDULE_EVT 	31
#define ID_MIMETYPE_APP_STARSCHEDULE_TASK	32
#define ID_MIMETYPE_APP_STARSCHEDULE_TVIEW 	33
#define ID_MIMETYPE_LAST ID_MIMETYPE_APP_STARSCHEDULE_TVIEW

#endif /* @@@ WHO HAS INTRODUCED THIS HERE FOR WHAT PURPOSE @@@ */

enum INetMessageContainerType
{
	INETMSG_MESSAGE_RFC822,
	INETMSG_MULTIPART_MIXED,
	INETMSG_MULTIPART_ALTERNATIVE,
	INETMSG_MULTIPART_DIGEST,
	INETMSG_MULTIPART_PARALLEL,
	INETMSG_MULTIPART_RELATED,
	INETMSG_MULTIPART_FORM_DATA
};

class INetMIMEMessage : public INetRFC822Message
{
	ULONG           m_nIndex[INETMSG_MIME_NUMHDR];

	INetMIMEMessage *pParent;
	ULONG           nNumChildren;
	List            aChildren;
	ByteString      m_aBoundary;
	BOOL            bHeaderParsed;

	friend class INetMIMEMessageStream;

	void SetChildCount (ULONG nCount) { nNumChildren = nCount; }
	const ByteString& GetMultipartBoundary (void) const { return m_aBoundary; }
	void SetMultipartBoundary (const ByteString& rBnd) { m_aBoundary = rBnd; }

	void CleanupImp (void);
	void CopyImp    (const INetMIMEMessage& rMsg);
	void SetHeaderParsed() { bHeaderParsed = TRUE; }

protected:
	virtual SvStream& operator<< (SvStream& rStrm) const;
	virtual SvStream& operator>> (SvStream& rStrm);

public:
	INetMIMEMessage (void);
	INetMIMEMessage (const INetMIMEMessage& rMsg);
	virtual ~INetMIMEMessage (void);

	INetMIMEMessage& operator= (const INetMIMEMessage& rMsg);

	BOOL HeaderParsed() const { return bHeaderParsed; }

	virtual INetMIMEMessage* CreateMessage (
		const INetMIMEMessage& rMsg) const;

	virtual ULONG SetHeaderField (
		const INetMessageHeader &rHeader, ULONG nIndex = LIST_APPEND);

	/** Header fields.
	 */
	void      SetMIMEVersion (const UniString& rVersion);
	UniString GetMIMEVersion (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_MIME_VERSION]);
	}

	void      SetContentDescription (const UniString& rDescription);
	UniString GetContentDescription (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_DESCRIPTION]);
	}

	void      SetContentDisposition (const UniString& rDisposition);
	UniString GetContentDisposition (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_DISPOSITION]);
	}

	void      SetContentID (const UniString& rID);
	UniString GetContentID (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_ID]);
	}

	void      SetContentType (const UniString& rType);
	UniString GetContentType (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_TYPE]);
	}

	void      SetContentTransferEncoding (const UniString& rEncoding);
	UniString GetContentTransferEncoding (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_MIME_CONTENT_TRANSFER_ENCODING]);
	}

	virtual void GetDefaultContentType (UniString& rContentType);

	/** Message container methods.
	 */
	BOOL IsContainer (void) const
	{
		return (IsMessage() || IsMultipart());
	}
	BOOL IsMessage (void) const
	{
		UniString aType (GetContentType());
		return (aType.CompareIgnoreCaseToAscii("message/", 8) == 0);
	}
	BOOL IsMultipart (void) const
	{
		UniString aType (GetContentType());
		return (aType.CompareIgnoreCaseToAscii("multipart/", 10) == 0);
	}

	ULONG GetChildCount (void) const { return nNumChildren; }
	INetMIMEMessage* GetChild (ULONG nIndex) const
	{
		return ((INetMIMEMessage *)(aChildren.GetObject (nIndex)));
	}
	INetMIMEMessage* GetParent (void) const { return pParent; }

	BOOL EnableAttachChild (
		INetMessageContainerType eType = INETMSG_MULTIPART_MIXED);
	BOOL AttachChild (
		INetMIMEMessage& rChildMsg, BOOL bOwner = TRUE);
	BOOL DetachChild (
		ULONG nIndex, INetMIMEMessage& rChildMsg) const;

	/** Stream operators.
	 */
	friend SvStream& operator<< (
		SvStream& rStrm, const INetMIMEMessage& rMsg)
	{
		return rMsg.operator<< (rStrm);
	}

	friend SvStream& operator>> (
		SvStream& rStrm, INetMIMEMessage& rMsg)
	{
		return rMsg.operator>> (rStrm);
	}
};

/*=======================================================================
 *
 * INetNewsMessage Interface.
 *
 *=====================================================================*/
#define INETMSG_NEWS_APPROVED       0
#define INETMSG_NEWS_CONTROL        1
#define INETMSG_NEWS_DISTRIBUTION   2
#define INETMSG_NEWS_EXPIRES        3
#define INETMSG_NEWS_FOLLOWUP_TO    4
#define INETMSG_NEWS_LINES          5
#define INETMSG_NEWS_NEWSGROUPS     6
#define INETMSG_NEWS_ORGANIZATION   7
#define INETMSG_NEWS_PATH           8
#define INETMSG_NEWS_SUMMARY        9
#define INETMSG_NEWS_XREF          10
#define INETMSG_NEWS_X_NEWSREADER  11

#define INETMSG_NEWS_NUMHDR        12

class INetNewsMessage : public INetMIMEMessage
{
	ULONG m_nIndex[INETMSG_NEWS_NUMHDR];

protected:
	virtual SvStream& operator<< (SvStream& rStrm) const;
	virtual SvStream& operator>> (SvStream& rStrm);

public:
	INetNewsMessage (void);
	INetNewsMessage (const INetNewsMessage& rMsg);
	virtual ~INetNewsMessage (void);

	INetNewsMessage& operator= (const INetNewsMessage& rMsg);

	virtual INetNewsMessage *CreateMessage (
		const INetNewsMessage& rMsg) const;

	virtual ULONG SetHeaderField (
		const INetMessageHeader &rHeader, ULONG nIndex = LIST_APPEND);

	/** Header fields.
	 */
	void      SetApproved (const UniString& rApproved);
	UniString GetApproved (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_APPROVED]);
	}

	void      SetControl (const UniString& rControl);
	UniString GetControl (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_CONTROL]);
	}

	void      SetDistribution (const UniString& rDistribution);
	UniString GetDistribution (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_DISTRIBUTION]);
	}

	void      SetExpires (const UniString& rExpires);
	UniString GetExpires (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_EXPIRES]);
	}

	void      SetFollowupTo (const UniString& rFollowupTo);
	UniString GetFollowupTo (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_FOLLOWUP_TO]);
	}

	void      SetLines (const UniString& rLines);
	UniString GetLines (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_LINES]);
	}

	void      SetNewsgroups (const UniString& rNewsgroups);
	UniString GetNewsgroups (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_NEWSGROUPS]);
	}

	void      SetOrganization (const UniString& rOrganization);
	UniString GetOrganization (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_ORGANIZATION]);
	}

	void      SetPath (const UniString& rPath);
	UniString GetPath (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_PATH]);
	}

	void      SetSummary (const UniString& rSummary);
	UniString GetSummary (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_SUMMARY]);
	}

	void      SetXref (const UniString& rXref);
	UniString GetXref (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_XREF]);
	}

	void      SetXNewsreader (const UniString& rXNewsreader);
	UniString GetXNewsreader (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_NEWS_X_NEWSREADER]);
	}

	/** Stream operators.
	 */
	friend SvStream& operator<< (
		SvStream& rStrm, const INetNewsMessage& rMsg)
	{
		return rMsg.operator<< (rStrm);
	}

	friend SvStream& operator>> (
		SvStream& rStrm, INetNewsMessage& rMsg)
	{
		return rMsg.operator>> (rStrm);
	}
};

/*=======================================================================
 *
 * INetHTTPMessage Interface.
 *
 *=====================================================================*/
#define INETMSG_HTTP_ACCEPT                0
#define INETMSG_HTTP_ACCEPT_CHARSET        1
#define INETMSG_HTTP_ACCEPT_ENCODING       2
#define INETMSG_HTTP_ACCEPT_LANGUAGE       3
#define INETMSG_HTTP_ALLOW                 4
#define INETMSG_HTTP_AUTHORIZATION         5
#define INETMSG_HTTP_CACHE_CONTROL         6
#define INETMSG_HTTP_CONNECTION            7
#define INETMSG_HTTP_CONTENT_ENCODING      8
#define INETMSG_HTTP_CONTENT_LANGUAGE      9
#define INETMSG_HTTP_CONTENT_LENGTH       10
#define INETMSG_HTTP_CONTENT_MD5          11
#define INETMSG_HTTP_CONTENT_RANGE        12
#define INETMSG_HTTP_CONTENT_VERSION      13
#define INETMSG_HTTP_COOKIE               14
#define INETMSG_HTTP_DERIVED_FROM         15
#define INETMSG_HTTP_EXPIRES              16
#define INETMSG_HTTP_FORWARDED            17
#define INETMSG_HTTP_HOST                 18
#define INETMSG_HTTP_IF_MODIFIED_SINCE    19
#define INETMSG_HTTP_KEEP_ALIVE           20
#define INETMSG_HTTP_LAST_MODIFIED        21
#define INETMSG_HTTP_LINK                 22
#define INETMSG_HTTP_LOCATION             23
#define INETMSG_HTTP_PROXY_AUTHENTICATE   24
#define INETMSG_HTTP_PROXY_AUTHORIZATION  25
#define INETMSG_HTTP_PRAGMA               26
#define INETMSG_HTTP_PUBLIC               27
#define INETMSG_HTTP_RANGE                28
#define INETMSG_HTTP_REFERER              29
#define INETMSG_HTTP_RETRY_AFTER          30
#define INETMSG_HTTP_SERVER               31
#define INETMSG_HTTP_TITLE                32
#define INETMSG_HTTP_TRANSFER_ENCODING    33
#define INETMSG_HTTP_UNLESS               34
#define INETMSG_HTTP_UPGRADE              35
#define INETMSG_HTTP_URI                  36
#define INETMSG_HTTP_USER_AGENT           37
#define INETMSG_HTTP_WWW_AUTHENTICATE     38

#define INETMSG_HTTP_NUMHDR               39

class INetHTTPMessage : public INetMIMEMessage
{
	ULONG m_nIndex[INETMSG_HTTP_NUMHDR];

protected:
	virtual SvStream& operator<< (SvStream& rStrm) const;
	virtual SvStream& operator>> (SvStream& rStrm);

public:
	INetHTTPMessage (void);
	INetHTTPMessage (const INetHTTPMessage& rMsg);
	virtual ~INetHTTPMessage (void);

	INetHTTPMessage& operator= (const INetHTTPMessage& rMsg);

	virtual INetHTTPMessage *CreateMessage (
		const INetHTTPMessage& rMsg) const;

	virtual ULONG SetHeaderField (
		const INetMessageHeader &rHeader, ULONG nIndex = LIST_APPEND);

	/** Header fields.
	 */
	void      SetAccept (const UniString& rAccept);
	UniString GetAccept (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_ACCEPT]);
	}

	void      SetAcceptCharset (const UniString& rAcceptCharset);
	UniString GetAcceptCharset (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_ACCEPT_CHARSET]);
	}

	void      SetAcceptEncoding (const UniString& rAcceptEncoding);
	UniString GetAcceptEncoding (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_ACCEPT_ENCODING]);
	}

	void      SetAcceptLanguage (const UniString& rAcceptLanguage);
	UniString GetAcceptLanguage (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_ACCEPT_LANGUAGE]);
	}

	void      SetAllow (const UniString& rAllow);
	UniString GetAllow (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_ALLOW]);
	}

	void      SetAuthorization (const UniString& rAuthorization);
	UniString GetAuthorization (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_AUTHORIZATION]);
	}

	void      SetCacheControl (const UniString& rCacheControl);
	UniString GetCacheControl (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CACHE_CONTROL]);
	}

	void      SetConnection (const UniString& rConnection);
	UniString GetConnection (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONNECTION]);
	}

	void      SetContentEncoding (const UniString& rContentEncoding);
	UniString GetContentEncoding (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONTENT_ENCODING]);
	}

	void      SetContentLanguage (const UniString& rContentLanguage);
	UniString GetContentLanguage (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONTENT_LANGUAGE]);
	}

	void      SetContentLength (const UniString& rContentLength);
	UniString GetContentLength (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONTENT_LENGTH]);
	}

	void      SetContentMD5 (const UniString& rContentMD5);
	UniString GetContentMD5 (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONTENT_MD5]);
	}

	void      SetContentRange (const UniString& rContentRange);
	UniString GetContentRange (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONTENT_RANGE]);
	}

	void      SetContentVersion (const UniString& rContentVersion);
	UniString GetContentVersion (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_CONTENT_VERSION]);
	}

	void      SetCookie (const UniString& rCookie);
	UniString GetCookie (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_COOKIE]);
	}

	void      SetDerivedFrom (const UniString& rDerivedFrom);
	UniString GetDerivedFrom (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_DERIVED_FROM]);
	}

	void      SetExpires (const UniString& rExpires);
	UniString GetExpires (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_EXPIRES]);
	}

	void      SetForwarded (const UniString& rForwarded);
	UniString GetForwarded (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_FORWARDED]);
	}

	void      SetHost (const UniString& rHost);
	UniString GetHost (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_HOST]);
	}

	void      SetIfModifiedSince (const UniString& rIfModifiedSince);
	UniString GetIfModifiedSince (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_IF_MODIFIED_SINCE]);
	}

	void      SetKeepAlive (const UniString& rKeepAlive);
	UniString GetKeepAlive (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_KEEP_ALIVE]);
	}

	void      SetLastModified (const UniString& rLastModified);
	UniString GetLastModified (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_LAST_MODIFIED]);
	}

	void      SetLink (const UniString& rLink);
	UniString GetLink (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_LINK]);
	}

	void      SetLocation (const UniString& rLocation);
	UniString GetLocation (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_LOCATION]);
	}

	void      SetProxyAuthenticate (const UniString& rProxyAuthenticate);
	UniString GetProxyAuthenticate (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_PROXY_AUTHENTICATE]);
	}

	void      SetProxyAuthorization (const UniString& rProxyAuthorization);
	UniString GetProxyAuthorization (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_PROXY_AUTHORIZATION]);
	}

	void      SetPragma (const UniString& rPragma);
	UniString GetPragma (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_PRAGMA]);
	}

	void      SetPublic (const UniString& rPublic);
	UniString GetPublic (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_PUBLIC]);
	}

	void      SetRange (const UniString& rRange);
	UniString GetRange (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_RANGE]);
	}

	void      SetReferer (const UniString& rReferer);
	UniString GetReferer (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_REFERER]);
	}

	void      SetRetryAfter (const UniString& rRetryAfter);
	UniString GetRetryAfter (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_RETRY_AFTER]);
	}

	void      SetServer (const UniString& rServer);
	UniString GetServer (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_SERVER]);
	}

	void      SetTitle (const UniString& rTitle);
	UniString GetTitle (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_TITLE]);
	}

	void      SetTransferEncoding (const UniString& rTransferEncoding);
	UniString GetTransferEncoding (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_TRANSFER_ENCODING]);
	}

	void      SetUnless (const UniString& rUnless);
	UniString GetUnless (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_UNLESS]);
	}

	void      SetUpgrade (const UniString& rUpgrade);
	UniString GetUpgrade (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_UPGRADE]);
	}

	void      SetURI (const UniString& rURI);
	UniString GetURI (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_URI]);
	}

	void      SetUserAgent (const UniString& rUserAgent);
	UniString GetUserAgent (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_USER_AGENT]);
	}

	void      SetWWWAuthenticate (const UniString& rWWWAuthenticate);
	UniString GetWWWAuthenticate (void) const
	{
		return GetHeaderValue (m_nIndex[INETMSG_HTTP_WWW_AUTHENTICATE]);
	}

	/** Stream operators.
	 */
	friend SvStream& operator<< (
		SvStream& rStrm, const INetHTTPMessage& rMsg)
	{
		return rMsg.operator<< (rStrm);
	}

	friend SvStream& operator>> (
		SvStream& rStrm, INetHTTPMessage& rMsg)
	{
		return rMsg.operator>> (rStrm);
	}
};

#endif /* !_TOOLS_INETMSG_HXX */

