// CNTITEM.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#if !defined(__CNTITEM_H__)
#define __CNTITEM_H__

#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif

#if !defined(__CNTDEF_H__)
#include <cntdef.h>
#endif

#if !defined(__CNTFIELD_H__)
#include <cntfield.h>
#endif

const TInt KUidStringLength =244;
#define KUidStringSeparator '-'
class CContactItemField;
#define KContactMaxFieldNumber 32
class CContactItemViewDef;
class CContactItem;

const TInt KContactFieldSetSearchAll=-1;

class CContactItemFieldSet : public CBase
	{
	friend class CContactItemField;
	friend class CContactDatabase;
public:
	IMPORT_C static CContactItemFieldSet* NewL();
	IMPORT_C static CContactItemFieldSet* NewLC();
	IMPORT_C ~CContactItemFieldSet();
	inline const CContactItemField& operator[](TInt aIndex) const;
	inline CContactItemField& operator[](TInt aIndex);
	inline TInt Find(TFieldType aFieldType) const; // will only find the first such occurence
	inline TInt Find(TFieldType aFieldType,TUid aMapping) const;
	IMPORT_C TInt FindNext(TFieldType aFieldType,TInt aStartPos=KContactFieldSetSearchAll) const;
	IMPORT_C TInt FindNext(TFieldType aFieldType,TUid aMapping,TInt aStartPos=KContactFieldSetSearchAll) const;
	inline TInt Count() const;
	inline void Reset();
	void UpdateFieldL(const CContactItemField &aField, TInt aMatchCount);
	IMPORT_C CContactItemFieldSet& AddL(CContactItemField& aField);
	IMPORT_C void Remove(TInt aIndex);
	IMPORT_C void InsertL(TInt aIndex,CContactItemField& aField);
	IMPORT_C void Move(TInt aFrom, TInt aTo);
	IMPORT_C TStreamId StoreL(CStreamStore& aStore);
	IMPORT_C void RestoreL(CStreamStore& aStore, TStreamId anId,const CContactItemViewDef& aViewDef);
private:
	CContactItemFieldSet();
	void ConstructL();
	void SetFieldId(CContactItemField& aField);
	const CContactItemField* FindById(TInt aId) const;
	TStreamId StoreL(CStreamStore& aStore,const CContactItem* aTemplate);
	void RestoreL(CStreamStore& aStore, TStreamId anId,const CContactItemViewDef& aViewDef,const CContactItem* aTemplate);
	void RestoreAndAddTemplateL(CStreamStore& aStore, TStreamId aId,const CContactItemViewDef& aViewDef,const CContactItem* aTemplate);
	TInt MatchTemplateField(const CContentType& aContentType,TUint aUserFlags,TBool &aExactMatch) const;
private:
	CArrayPtr<CContactItemField>* iFields;
	};

class CContactDatabase;

class CContactItem : public CBase
	{
	friend class CContactCard;
	friend class CContactTemplate;
	friend class CContactGroup;
	friend class CVCardToContactsAppConverter;
public:
	IMPORT_C ~CContactItem();
	virtual TUid Type() const=0;
	IMPORT_C TContactItemId Id() const;
	IMPORT_C TTime LastModified() const;
	IMPORT_C void SetLastModified(const TTime& aLastModified);
	IMPORT_C void AddFieldL(CContactItemField& aField);
	IMPORT_C void RemoveField(TInt aFieldPos);
	IMPORT_C void InsertFieldL(CContactItemField& aField,TInt aFieldPos);
	IMPORT_C CContactItemFieldSet& CardFields() const;
	IMPORT_C void SetHidden(TBool aHidden);
	IMPORT_C void SetSystem(TBool aSystem);    	
	IMPORT_C TBool IsHidden();
	IMPORT_C TBool IsSystem();    	
	IMPORT_C void UpdateFieldSet(CContactItemFieldSet* aNewFieldSet);
	TContactItemId Agent();
	inline TBool IsDeletable();
	inline void SetDeleteFlag(TBool aValue);
	inline TBool IsDeleted();
	inline void IncAccessCount();
	inline void DecAccessCount();
	inline TInt AccessCount() const;
	void SetUidStringL(TDesC& aString);
	IMPORT_C TPtrC UidStringL(TInt64 aMachineUniqueId) const;
protected:
private:
	CContactItem();
	void ConstructL();
	void ConstructL(const CContactItem *aTemplate);
	void MakeUidStringL(TInt64 aMachineUniqueId);
	void SetHasCompressedGuid(TBool aCompressed);
	TBool GuidIsCompressed() const;
private:
	enum { ESystem=0x01, EHidden=0x02, ECompressedGuid=0x04 };
private:
	CContactItemFieldSet* iFieldSet;
	TUint32 iAttributes;
	TContactItemId iId;
	TTime iLastModified;
	TUint32 iAccessCount;
	TBool iDeleteFlag;
	HBufC* iGuid;
	friend class CContactDatabase;
	};

class CContactGroup : public CContactItem
	{
public:
	IMPORT_C static CContactGroup* NewL();
	IMPORT_C static CContactGroup* NewLC();
	IMPORT_C ~CContactGroup();
public: // from CContactItem
	IMPORT_C TUid Type() const;
public:
	IMPORT_C CContactIdArray* ItemsContained() const;
//	IMPORT_C CContactIdArray* CardsContained() const;
//	IMPORT_C CContactIdArray* GroupsContained() const;
	IMPORT_C TBool IsSystem() const;
	IMPORT_C void SetSystem(TBool aSystem);
	IMPORT_C void AddItemL(TContactItemId aContactId);
	IMPORT_C void RemoveItem(TContactItemId aContactId);
private:
	CContactGroup();
private:
//	CContactIdArray* iCards;
//	CContactIdArray* iGroups;
	CContactIdArray* iItems;
	};

class CContactCard : public CContactItem
	{
public:
	IMPORT_C static CContactCard* NewL();
	IMPORT_C static CContactCard* NewLC();
	IMPORT_C static CContactCard* NewL(const CContactItem *aTemplate);
	IMPORT_C static CContactCard* NewLC(const CContactItem *aTemplate);
public: // from CContactItem
	IMPORT_C TUid Type() const;
public:
//	IMPORT_C CContactIdArray* GroupsJoined() const;
private:
	CContactCard();
private:
	CContactIdArray* iGroups;
	};

class CContactTemplate : public CContactItem
	{
public:
	IMPORT_C static CContactTemplate* NewL();
	IMPORT_C static CContactTemplate* NewLC();
	IMPORT_C static CContactTemplate* NewL(const CContactItem *aTemplate);
	IMPORT_C static CContactTemplate* NewLC(const CContactItem *aTemplate);
public: // from CContactItem
	IMPORT_C TUid Type() const;
private:
	CContactTemplate();
	};

//
// class ContactGuid
//

class ContactGuid
	{
public:
	static TContactItemId IsLocalContactUidString(const TDesC& aString, TInt64 aMachineUniqueId);
	static TBool GetCreationDate(TDes& aString, TInt64 aMachineUniqueId);
	static HBufC* CreateGuidLC(const TDesC& aCreationDate,TContactItemId aId, TInt64 aMachineUniqueId);
	static HBufC* CreateGuidLC(const TTime& aCreationDate,TContactItemId aId, TInt64 aMachineUniqueId);
	static HBufC* CreateGuidLC(TContactItemId aId, TInt64 aMachineUniqueId);
	};

inline const CContactItemField& CContactItemFieldSet::operator[](TInt aIndex) const
	{ return *(*iFields)[aIndex]; }
inline CContactItemField& CContactItemFieldSet::operator[](TInt aIndex)
	{ return *(*iFields)[aIndex]; }
inline TInt CContactItemFieldSet::Find(TFieldType aFieldType) const
	{ return FindNext(aFieldType,KContactFieldSetSearchAll); }
inline TInt CContactItemFieldSet::Find(TFieldType aFieldType,TUid aMapping) const
	{ return FindNext(aFieldType,aMapping,KContactFieldSetSearchAll); }
inline TInt CContactItemFieldSet::Count() const
	{ return iFields->Count(); }
inline void CContactItemFieldSet::Reset()
	{ iFields->ResetAndDestroy(); }
inline TBool CContactItem::IsDeletable()
	{return (iAccessCount == 0);}
inline void CContactItem::SetDeleteFlag(TBool aValue)
	{iDeleteFlag=aValue;};
inline TBool CContactItem::IsDeleted()
	{return iDeleteFlag;};
inline void CContactItem::IncAccessCount()
	{iAccessCount++;}
inline void CContactItem::DecAccessCount()
	{if(iAccessCount) iAccessCount--;}
inline TInt CContactItem::AccessCount() const
	{return(iAccessCount);}

#endif
