/*=============================================================================
	CACFObject.h

	$Log: CACFObject.h,v $
	Revision 1.11  2004/08/05 01:26:11  jcm10
	add CACFBundle
	
	Revision 1.10  2004/03/29 20:15:58  jcm10
	no longer need CACFPlugIn defined here. Use CACFPlugIn.h instead.
	
	Revision 1.9  2003/11/20 22:56:53  dwyatt
	__COREAUDIO_USE_FLAT_INCLUDES__
	
	Revision 1.8  2003/05/22 19:06:01  jcm10
	remove the CACFDictionary and CACFArray classes, use the stand alone versions instead
	
	Revision 1.7  2003/05/04 00:02:32  jcm10
	rename CACFArray<> to not clash with the full blown class
	
	Revision 1.6  2003/04/23 19:53:54  jcm10
	make the typedef of CACFObject<CFDictionaryRef> not clash with the new CACFDictionary class
	
	Revision 1.5  2002/09/10 19:02:19  jcm10
	added IsEqual and CACFUUID
	
	Revision 1.4  2002/09/05 22:37:19  jcm10
	predefine some common types
	
	Revision 1.3  2002/07/07 00:46:31  jcm10
	add default a default constructor
	
	Revision 1.2  2002/04/10 01:14:36  jcm10
	destructors need to be public
	
	Revision 1.1  2002/04/10 00:30:04  jcm10
	first checked in
	
	Revision 0.0  Tue Apr 09 2002 14:28:22 US/Pacific  moorf
	Created
		
	$NoKeywords: $
=============================================================================*/
#if !defined(__CACFObject_h__)
#define __CACFObject_h__

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

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

//=============================================================================
//	CACFObject
//=============================================================================

template <class CFObjectType>
class CACFObject
{

//	Construction/Destruction
public:
					CACFObject() : mCFObject(NULL), mWillRelease(true) {}
					CACFObject(CFObjectType inCFObject, bool inWillRelease = true) : mCFObject(inCFObject), mWillRelease(inWillRelease) {}
					~CACFObject() { Release(); }
					CACFObject(const CACFObject& inObject) : mCFObject(inObject.mCFObject), mWillRelease(inObject.mWillRelease) { Retain(); }
	CACFObject&		operator=(const CACFObject& inObject) { Release(); mCFObject = inObject.mCFObject; mWillRelease = inObject.mWillRelease; Retain(); return *this; }
	CACFObject&		operator=(CFObjectType inCFObject) { Release(); mCFObject = inCFObject; mWillRelease = true; return *this; }

private:
	void			Retain() { if(mWillRelease && (mCFObject != NULL)) { CFRetain(mCFObject); } }
	void			Release() { if(mWillRelease && (mCFObject != NULL)) { CFRelease(mCFObject); mCFObject = NULL; } }
	
	CFObjectType	mCFObject;
	bool			mWillRelease;

//	Operations
public:
	void			AllowRelease() { mWillRelease = true; }
	void			DontAllowRelease() { mWillRelease = false; }
	bool			IsValid() const { return mCFObject != NULL; }
	CFTypeID		GetTypeID() const { return CFGetTypeID(mCFObject); }
	bool			IsEqual(CFObjectType inCFObject) const { return CFEqual(inCFObject, mCFObject) != 0; }

//	Value Access
public:
	CFObjectType	GetCFObject() const { return mCFObject; }
	CFObjectType	CopyCFObject() const { if(mCFObject != NULL) { CFRetain(mCFObject); } return mCFObject; }

};

typedef	CACFObject<CFBundleRef>	CACFBundle;
typedef	CACFObject<CFUUIDRef>	CACFUUID;
typedef	CACFObject<CFURLRef>	CACFURL;

#endif
