/*************************************************************************
 *
 *  $RCSfile: poolitem.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2003/03/27 14:36:25 $
 *
 *  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 _SFXPOOLITEM_HXX
#define _SFXPOOLITEM_HXX

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

#define TF_POOLABLE

#ifndef _SAL_CONFIG_H_ /* defines _USE_NAMESPACE */
#include <sal/config.h>
#endif
#ifndef _RTTI_HXX //autogen
#include <tools/rtti.hxx>
#endif
#include <limits.h>
#ifndef _SOLAR_H
#include <tools/solar.h>
#endif
#ifndef _DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#include <svtools/svarray.hxx>
#include <svtools/hint.hxx>

// Mit einem include args.hxx ziehen wir das gesamte Sbx an, daher aus
// args.hxx hierhin gezogen !!		MH
//
//#include <svtools/args.hxx>
typedef long SfxArgumentError;

class SbxVariable;
class SbxObject;
class SvStream;
class Color;
class IntlWrapper;

namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }

#define SFX_ITEMS_DIRECT                    0xffff
#define SFX_ITEMS_NULL                      0xfff0  // anstelle StoreSurrogate

#define SFX_ITEMS_POOLDEFAULT               0xffff
#define SFX_ITEMS_STATICDEFAULT             0xfffe
#define SFX_ITEMS_DELETEONIDLE              0xfffd

#define SFX_ITEMS_OLD_MAXREF                0xffef
#define SFX_ITEMS_MAXREF                    0xfffffffe
#define SFX_ITEMS_SPECIAL					0xffffffff

#define CONVERT_TWIPS 						0x80	//Uno-Konvertierung fuer Massangaben (fuer MemberId)

// -----------------------------------------------------------------------

// UNO3 shortcuts

// warning, if there is no boolean inside the any this will always return the value false
inline sal_Bool Any2Bool( const ::com::sun::star::uno::Any&rValue )
{
	sal_Bool nValue = sal_False;
	if( rValue.hasValue() )
	{
		if( rValue.getValueType() == ::getCppuBooleanType() )
		{
			nValue = *(sal_Bool*)rValue.getValue();
		}
		else
		{
			sal_Int32 nNum;
			if( rValue >>= nNum )
				nValue = nNum != 0;
		}
	}

	return nValue;
}

inline ::com::sun::star::uno::Any Bool2Any( sal_Bool bValue )
{
	return ::com::sun::star::uno::Any( &bValue, ::getCppuBooleanType() );
}

// -----------------------------------------------------------------------

//! Notloesung!!!
enum SfxFieldUnit
{
	SFX_FUNIT_NONE, SFX_FUNIT_MM, SFX_FUNIT_CM, SFX_FUNIT_M, SFX_FUNIT_KM,
	SFX_FUNIT_TWIP, SFX_FUNIT_POINT, SFX_FUNIT_PICA,
	SFX_FUNIT_INCH, SFX_FUNIT_FOOT, SFX_FUNIT_MILE, SFX_FUNIT_CUSTOM
};

enum SfxMapUnit
{
	SFX_MAPUNIT_100TH_MM,
	SFX_MAPUNIT_10TH_MM,
	SFX_MAPUNIT_MM,
	SFX_MAPUNIT_CM,
	SFX_MAPUNIT_1000TH_INCH,
	SFX_MAPUNIT_100TH_INCH,
	SFX_MAPUNIT_10TH_INCH,
	SFX_MAPUNIT_INCH,
	SFX_MAPUNIT_POINT,
	SFX_MAPUNIT_TWIP,
	SFX_MAPUNIT_PIXEL,
	SFX_MAPUNIT_SYSFONT,
	SFX_MAPUNIT_APPFONT,
	SFX_MAPUNIT_RELATIVE
};

// -----------------------------------------------------------------------

enum SfxItemPresentation

/*  [Beschreibung]

	Die Werte dieses Enums bezeichnen den Grad der textuellen
	Presentation eines Items nach Aufruf der virtuellen Methode
	<SfxPoolItem::GetPresentation()const>.
*/

{
	SFX_ITEM_PRESENTATION_NONE,
	SFX_ITEM_PRESENTATION_NAMEONLY,
	SFX_ITEM_PRESENTATION_NAMELESS,
	SFX_ITEM_PRESENTATION_COMPLETE
};

// -----------------------------------------------------------------------

typedef USHORT SfxItemState;

#define	SFX_ITEM_UNKNOWN	0x0000

#define SFX_ITEM_DISABLED	0x0001
#define SFX_ITEM_READONLY	0x0002

#define SFX_ITEM_DONTCARE   0x0010
#define SFX_ITEM_DEFAULT	0x0020
#define SFX_ITEM_SET		0x0030

// old stuff - dont use!!!
#define SFX_ITEM_AVAILABLE	SFX_ITEM_DEFAULT
#define SFX_ITEM_OFF      	SFX_ITEM_DEFAULT
#define SFX_ITEM_ON			SFX_ITEM_SET

DBG_NAMEEX(SfxPoolItem);
DBG_NAMEEX(SfxVoidItem);
DBG_NAMEEX(SfxItemHandle);

class SvXMLUnitConverter;

class String;
namespace rtl
{
	class OUString;
}

// -----------------------------------------------------------------------

class SfxPoolItem
{
friend class SfxItemPool;
friend class SfxItemDesruptor_Impl;
friend class SfxItemPoolCache;
friend class SfxItemSet;
friend class SfxVoidItem;

	ULONG                    nRefCount;                    // Referenzzaehler
	USHORT                   nWhich;
	USHORT					 nKind;

private:
	inline void              SetRefCount( ULONG n );
	inline void				 SetKind( USHORT n );
public:
	inline ULONG             AddRef( ULONG n = 1 ) const;
private:
	inline ULONG             ReleaseRef( ULONG n = 1 ) const;
	long                     Delete_Impl(void*);

	virtual void             Store( SvStream & ) const;
	virtual void             GetVersion() const;

protected:
							 SfxPoolItem( USHORT nWhich = 0 );
							 SfxPoolItem( const SfxPoolItem& );

public:
							 TYPEINFO();
	virtual                  ~SfxPoolItem();

	void                     SetWhich( USHORT nId ) {
								DBG_CHKTHIS(SfxPoolItem, 0);
								nWhich = nId; }
	USHORT                   Which() const {
								 DBG_CHKTHIS(SfxPoolItem, 0);
								 return nWhich; }
	virtual int              operator==( const SfxPoolItem& ) const = 0;
	int                      operator!=( const SfxPoolItem& rItem ) const
							 { return !(*this == rItem); }
	virtual int				 Compare( const SfxPoolItem &rWith ) const;
    virtual int              Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const;

	virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation,
									SfxMapUnit eCoreMetric,
									SfxMapUnit ePresentationMetric,
									XubString &rText,
                                    const IntlWrapper * pIntlWrapper = 0 )
		const;
	virtual USHORT           GetVersion( USHORT nFileFormatVersion ) const;
	virtual int              ScaleMetrics( long lMult, long lDiv );
	virtual int              HasMetrics() const;

	virtual	BOOL        	 QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
	virtual	BOOL			 PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );

	virtual SfxPoolItem*     Create( SvStream &, USHORT nItemVersion ) const;
	virtual SvStream&        Store( SvStream &, USHORT nItemVersion ) const;
	virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const = 0;

	ULONG                    GetRefCount() const { return nRefCount; }
	inline USHORT			 GetKind() const { return nKind; }

	/** Read in a Unicode string from a streamed byte string representation.

		@param rStream  Some (input) stream.  Its Stream/TargetCharSets must
		be set to correct values!

		@param rString  On success, returns the reconstructed Unicode string.

		@return  True if the string was successfuly read and reconstructed.
	 */
	static bool readByteString(SvStream & rStream, UniString & rString);

	/** Write a byte string representation of a Unicode string into a stream.

		@param rStream  Some (output) stream.  Its Stream/TargetCharSets must
		be set to correct values!

		@param rString  Some Unicode string.
	 */
	static void writeByteString(SvStream & rStream,
								UniString const & rString);

	/** Read in a Unicode string from either a streamed Unicode or byte string
		representation.

		@param rStream  Some (input) stream.  If bUnicode is false, its
		Stream/TargetCharSets must be set to correct values!

		@param rString  On success, returns the reconstructed Unicode string.

		@param bUnicode  Whether to read in a stream Unicode (true) or byte
		string (false) representation.

		@return  True if the string was successfuly read and reconstructed.
	 */
	static bool readUnicodeString(SvStream & rStream, UniString & rString,
								  bool bUnicode);

	/** Write a Unicode string representation of a Unicode string into a
		stream.

		@param rStream  Some (output) stream.

		@param rString  Some Unicode string.
	 */
	static void writeUnicodeString(SvStream & rStream,
								   UniString const & rString);

private:
	SfxPoolItem&             operator=( const SfxPoolItem& );    // n.i.!!
};

// -----------------------------------------------------------------------

inline void SfxPoolItem::SetRefCount( ULONG n )
{
	DBG_CHKTHIS( SfxPoolItem, 0 );
	nRefCount = n;
	nKind = 0;
}

inline void SfxPoolItem::SetKind( USHORT n )
{
	DBG_CHKTHIS( SfxPoolItem, 0 );
	nRefCount = SFX_ITEMS_SPECIAL;
	nKind = n;
}

inline ULONG SfxPoolItem::AddRef( ULONG n ) const
{
	DBG_CHKTHIS( SfxPoolItem, 0 );
	DBG_ASSERT( nRefCount <= SFX_ITEMS_MAXREF, "AddRef mit nicht-Pool-Item" );
	DBG_ASSERT( ULONG_MAX - nRefCount > n, "AddRef: Referenzzaehler ueberschlaegt sich" );
	return ( ((SfxPoolItem *)this)->nRefCount += n );
}

inline ULONG SfxPoolItem::ReleaseRef( ULONG n ) const
{
	DBG_CHKTHIS( SfxPoolItem, 0 );
	DBG_ASSERT( nRefCount <= SFX_ITEMS_MAXREF, "AddRef mit nicht-Pool-Item" );
	DBG_ASSERT( nRefCount >= n, "ReleaseRef: Referenzzaehler ueberschlaegt sich" );
	((SfxPoolItem *)this)->nRefCount -= n;
	return nRefCount;
}

// -----------------------------------------------------------------------

inline int IsPoolDefaultItem(const SfxPoolItem *pItem )
{
	return pItem && pItem->GetKind() == SFX_ITEMS_POOLDEFAULT;
}

inline int IsStaticDefaultItem(const SfxPoolItem *pItem )
{
	return pItem && pItem->GetKind() == SFX_ITEMS_STATICDEFAULT;
}

inline int IsDefaultItem( const SfxPoolItem *pItem )
{
	return pItem && pItem->GetKind() >= SFX_ITEMS_STATICDEFAULT;
}

inline int IsPooledItem( const SfxPoolItem *pItem )
{
	return pItem && pItem->GetRefCount() > 0 && pItem->GetRefCount() <= SFX_ITEMS_MAXREF;
}

inline int IsInvalidItem(const SfxPoolItem *pItem)
{
	return pItem == (SfxPoolItem *)-1;
}

// -----------------------------------------------------------------------

class SfxVoidItem: public SfxPoolItem
{
public:
							TYPEINFO();
							SfxVoidItem( USHORT nWhich );
							SfxVoidItem( USHORT nWhich, SvStream & );
							SfxVoidItem( const SfxVoidItem& );
							~SfxVoidItem();

	virtual int             operator==( const SfxPoolItem& ) const;

	virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
									SfxMapUnit eCoreMetric,
									SfxMapUnit ePresMetric,
									XubString &rText,
                                    const IntlWrapper * = 0 ) const;

	// von sich selbst eine Kopie erzeugen
	virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;
			void            SetWhich(USHORT nWh) { nWhich = nWh; }
};

// -----------------------------------------------------------------------

class SfxSetItem: public SfxPoolItem
{
	SfxItemSet              *pSet;

public:
							TYPEINFO();
							SfxSetItem( USHORT nWhich, SfxItemSet *pSet );
							SfxSetItem( USHORT nWhich, const SfxItemSet &rSet );
							SfxSetItem( const SfxSetItem&, SfxItemPool *pPool = 0 );
							~SfxSetItem();

	virtual int             operator==( const SfxPoolItem& ) const;

	virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
									SfxMapUnit eCoreMetric,
									SfxMapUnit ePresMetric,
									XubString &rText,
                                    const IntlWrapper * = 0 ) const;

	// von sich selbst eine Kopie erzeugen
	virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const = 0;
	virtual SfxPoolItem*    Create(SvStream &, USHORT nVersion) const = 0;
	virtual SvStream&       Store(SvStream &, USHORT nVer) const;

	const SfxItemSet&       GetItemSet() const
							{ return *pSet; }
	SfxItemSet&             GetItemSet()
							{ return *pSet; }
};

// -----------------------------------------------------------------------

class SfxInvalidItem: public SfxPoolItem
{
friend class SfxItemSet;

	const SfxPoolItem*      pDefaultItem;

private:
							TYPEINFO();
							SfxInvalidItem( USHORT nWhich, const SfxPoolItem &rDefault );
							SfxInvalidItem( const SfxInvalidItem& );
	virtual                 ~SfxInvalidItem();

public:
	virtual int             operator==( const SfxPoolItem& ) const;

	virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
									SfxMapUnit eCoreMetric,
									SfxMapUnit ePresMetric,
									XubString &rText,
                                    const IntlWrapper * = 0 ) const;
	const SfxPoolItem*      GetDefaultItem() const { return pDefaultItem; }

	// von sich selbst eine Kopie erzeugen
	virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;
	virtual SfxPoolItem*    Create(SvStream &, USHORT nVersion) const;
	virtual SvStream&       Store(SvStream &, USHORT nVer ) const;
};

// -----------------------------------------------------------------------
// Handle Klasse fuer PoolItems

class SfxItemHandle
{
	USHORT      *pRef;
	SfxPoolItem *pItem;
public:
	SfxItemHandle( SfxPoolItem& );
	SfxItemHandle( const SfxItemHandle& );
	~SfxItemHandle();

	const SfxItemHandle &operator=(const SfxItemHandle &);
	const SfxPoolItem &GetItem() const { return *pItem; }
};

// -----------------------------------------------------------------------

DECL_PTRHINT(SfxPoolItemHint,SfxPoolItem);

// -----------------------------------------------------------------------

class SfxItemChangedHint: public SfxHint
{
	const SfxPoolItem& 	_rOld;
	const SfxPoolItem& 	_rNew;

public:
						TYPEINFO(); \
    					SfxItemChangedHint( const SfxPoolItem &rOld,
											const SfxPoolItem &rNew )
						:	_rOld( rOld ),
							_rNew( rNew )
						{}

	const SfxPoolItem&	GetOldItem() const { return _rOld; }
	const SfxPoolItem&	GetNewItem() const { return _rNew; }
};

#endif // #ifndef _SFXPOOLITEM_HXX

