/*=============================================================================
	CACFDictionary.h
 
	$Log: CACFDictionary.h,v $
	Revision 1.21  2005/01/05 23:57:11  dwyatt
	gcc4 / SDK / need newline at EOF
	
	Revision 1.20  2004/09/14 19:53:58  jcm10
	add GetBool()
	
	Revision 1.19  2004/01/29 00:24:44  jcm10
	add CanModify() and Clear()
	
	Revision 1.18  2004/01/12 20:36:17  jcm10
	add SetCFMutableDictionaryFromCopy
	
	Revision 1.17  2003/11/20 22:56:53  dwyatt
	__COREAUDIO_USE_FLAT_INCLUDES__
	
	Revision 1.16  2003/10/29 01:53:48  bills
	a couple of new methods
	
	Revision 1.15  2003/10/02 00:45:54  bills
	GetData
	
	Revision 1.14  2003/08/17 23:03:39  bills
	add show method
	
	Revision 1.13  2003/07/16 00:59:49  bills
	HasKey is const
	
	Revision 1.12  2003/05/22 19:07:18  jcm10
	rework this class to prevent polymorphic problems with CFTypes
	
	Revision 1.11  2003/05/08 20:09:45  jcm10
	add a const CFDictionaryRef constructor
	
	Revision 1.10  2003/05/04 00:00:54  jcm10
	add getters for CFArrays and CFDictionaries
	
	Revision 1.9  2003/05/02 01:15:30  jcm10
	check for NULL before calling CFRelease in the desstructor
	
	Revision 1.8  2003/04/27 02:32:58  bills
	add Float32 support
	
	Revision 1.7  2003/04/02 18:20:02  bills
	changes to make persistence work
	
	Revision 1.6  2003/03/25 18:59:06  bills
	get should really get:)
	
	Revision 1.5  2003/03/23 02:53:12  bills
	some rewrite and add methods
	
	Revision 1.4  2003/03/21 06:53:36  bills
	prelim impl of CA-AU persistence
	
	Revision 1.3  2003/03/17 02:55:52  bills
	couple of other API
	
	Revision 1.2  2003/03/12 05:05:04  bills
	refactor persistence
	
	Revision 1.1  2003/03/11 20:57:08  bills
	initial checkin
		

	Created by William Stewart on Sat Mar 08 2003.
	Copyright (c) 2003 Apple Computer. All rights reserved.

=============================================================================*/
#if !defined(__CACFDictionary_h__)
#define __CACFDictionary_h__

//=============================================================================
//	Includes
//=============================================================================

//	System Includes
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
	#include <CoreFoundation/CoreFoundation.h>
#else
	#include <CoreFoundation.h>
#endif

//=============================================================================
//	CACFDictionary
//=============================================================================

class CACFDictionary 
{

//	Construction/Destruction
public:
							CACFDictionary(bool inRelease) : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(inRelease), mMutable(true) {}
							CACFDictionary(const CFDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(const_cast<CFMutableDictionaryRef>(inCFDictionary)), mRelease(inRelease), mMutable(true) {}
							CACFDictionary(const CFMutableDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(inCFDictionary), mRelease(inRelease), mMutable(true) {}
							CACFDictionary(const CACFDictionary& inDictionary) : mCFDictionary(inDictionary.mCFDictionary), mRelease(inDictionary.mRelease), mMutable(inDictionary.mMutable) { if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } }
	CACFDictionary&			operator=(const CACFDictionary& inDictionary) { mCFDictionary = inDictionary.mCFDictionary; mRelease = inDictionary.mRelease; mMutable = inDictionary.mMutable; if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } return *this; } 
							~CACFDictionary() { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } }
		
//	Attributes
public:
	bool					IsValid() const { return mCFDictionary != NULL; }
	bool					IsMutable() const { return mMutable;}
	bool					CanModify() const { return mMutable && (mCFDictionary != NULL); }
	
	bool					WillRelease() const { return mRelease; }
	void					ShouldRelease(bool inRelease) { mRelease = inRelease; }
	
	CFDictionaryRef			GetDict() const { return mCFDictionary; }
	CFDictionaryRef			GetCFDictionary() const { return mCFDictionary; }
	CFDictionaryRef			CopyCFDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }

	CFMutableDictionaryRef	GetMutableDict() { return mCFDictionary; }
	CFMutableDictionaryRef	GetCFMutableDictionary() const { return mCFDictionary; }
	CFMutableDictionaryRef	CopyCFMutableDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
	void					SetCFMutableDictionaryFromCopy(CFDictionaryRef inDictionary, bool inRelease = true) { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } mCFDictionary = CFDictionaryCreateMutableCopy(NULL, 0, inDictionary); mMutable = true; mRelease = inRelease; }

	CFPropertyListRef		AsPropertyList() const { return mCFDictionary; }
	OSStatus				GetDictIfMutable(CFMutableDictionaryRef& outDict) const { OSStatus theAnswer = -1; if(mMutable) { outDict = mCFDictionary; theAnswer = 0; } return theAnswer; }

//	Item Operations
public:
	bool					HasKey(const CFStringRef inKey) const;
	UInt32					Size() const;
	void					GetKeys(const void** keys) const;
	
	bool					GetBool(const CFStringRef inKey, bool& outValue) const;
	bool					GetSInt32(const CFStringRef inKey, SInt32& outValue) const;
	bool					GetUInt32(const CFStringRef inKey, UInt32& outValue) const;
	bool					GetSInt64(const CFStringRef inKey, SInt64& outValue) const;
	bool					GetUInt64(const CFStringRef inKey, UInt64& outValue) const;
	bool					GetFloat32(const CFStringRef inKey, Float32& outValue) const;
	bool					GetFloat64(const CFStringRef inKey, Float64& outValue) const;
	bool					GetString(const CFStringRef inKey, CFStringRef& outValue) const;	
	bool					GetArray(const CFStringRef inKey, CFArrayRef& outValue) const;	
	bool					GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const;	
	bool					GetData(const CFStringRef inKey, CFDataRef& outValue) const;
	bool					GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const;
	
	bool					GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const;

	bool					AddSInt32(const CFStringRef inKey, SInt32 inValue);
	bool					AddUInt32(const CFStringRef inKey, UInt32 inValue);
	bool					AddSInt64(const CFStringRef inKey, SInt64 inValue);
	bool					AddUInt64(const CFStringRef inKey, UInt64 inValue);
	bool					AddFloat32(const CFStringRef inKey, Float32 inValue);
	bool					AddFloat64(const CFStringRef inKey, Float64 inValue);
	bool					AddNumber(const CFStringRef inKey, const CFNumberRef inValue);
	bool					AddString(const CFStringRef inKey, const CFStringRef inValue);
	bool					AddArray(const CFStringRef inKey, const CFArrayRef inValue);
	bool					AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue);
	bool					AddCFType(const CFStringRef inKey, const CFTypeRef inValue);
	
	bool					AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue);
	bool					AddCString(const CFStringRef inKey, const char* inValue);

	void					Clear() { if(CanModify()) { CFDictionaryRemoveAllValues(mCFDictionary); } }
	
	void					Show() { CFShow(mCFDictionary); }
	
//	Implementation
private:
	CFMutableDictionaryRef 	mCFDictionary;
	bool					mRelease;
	bool					mMutable;
};

#endif //__CACFDictionary_h__
