/*=============================================================================
	CAComponentDescription.h
	
	$Log: CAComponentDescription.h,v $
	Revision 1.15  2005/02/15 20:55:38  luke
	make it work properly on 10.3 & 10.4
	
	Revision 1.14  2004/12/02 19:14:36  bills
	fix comp desc
	
	Revision 1.13  2004/09/28 23:16:36  jcm10
	add missing includes
	
	Revision 1.12  2004/08/26 23:47:49  bills
	workaround Panther build issue (augn is not defined yet)
	
	Revision 1.11  2004/04/29 00:11:23  luke
	add IsGenerator()
	
	Revision 1.10  2003/11/20 22:56:53  dwyatt
	__COREAUDIO_USE_FLAT_INCLUDES__
	
	Revision 1.9  2003/08/30 08:52:22  bills
	rewrite equality tests to just test the component type fields
	
	Revision 1.8  2003/06/29 01:10:20  bills
	add const.
	
	Revision 1.7  2003/06/15 23:57:31  bills
	add Offline knowledge
	
	Revision 1.6  2003/03/21 06:53:36  bills
	prelim impl of CA-AU persistence
	
	Revision 1.5  2003/03/12 23:38:21  bills
	CAAudioUnit::CanDo
	
	Revision 1.4  2003/03/12 05:08:57  bills
	some tweaks
	
	Revision 1.3  2003/03/12 05:05:05  bills
	refactor persistence
	
	Revision 1.2  2003/03/11 20:57:29  bills
	first pass at save/restore state
	
	Revision 1.1  2003/03/11 00:38:21  bills
	initial checkin
	
	
	Created by William Stewart on Sat Mar 08 2003.
	Copyright (c) 2003 Apple Computer. All rights reserved.

	$NoKeywords: $
=============================================================================*/

#ifndef __CAComponentDescription_h__
#define __CAComponentDescription_h__

#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
	#include <CoreServices/CoreServices.h>
	#include <AudioUnit/AudioUnit.h>
#else
	#include <ConditionalMacros.h>
	#include <CoreServices.h>
	#include <AudioUnit.h>
#endif

#include "CACFDictionary.h"
#include <stdio.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

void CAShowComponentDescription(const ComponentDescription *desc);

#ifdef __cplusplus
};
#endif


// ____________________________________________________________________________
//
//	CAComponentDescription
class CAComponentDescription : public ComponentDescription {
public:
	CAComponentDescription() { memset (this, 0, sizeof (ComponentDescription)); }
	
	CAComponentDescription (OSType inType, OSType inSubtype = 0, OSType inManu = 0);

	CAComponentDescription(const ComponentDescription& desc) { memcpy (this, &desc, sizeof (ComponentDescription)); }
		
	// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
	//
	// interrogation
	
	bool	IsAU () const;
	
	bool	IsAUFX() const { return componentType == kAudioUnitType_Effect; }
	bool	IsAUFM() const { return componentType == kAudioUnitType_MusicEffect; }
	
	bool 	IsEffect () const { return IsAUFX() || IsAUFM() || IsPanner(); }
	
	bool	IsOffline () const { return componentType == 'auol'; }
	
	bool 	IsFConv () const { return componentType == kAudioUnitType_FormatConverter; }
	
	bool	IsPanner () const { return componentType == kAudioUnitType_Panner; }
	
	bool	IsMusicDevice () const { return componentType == kAudioUnitType_MusicDevice; }
	
#ifndef MAC_OS_X_VERSION_10_4
	bool	IsGenerator () const { return componentType =='augn'; }
#else
	bool	IsGenerator () const { return componentType ==kAudioUnitType_Generator; }
#endif
	
	bool	IsOutput () const { return componentType == kAudioUnitType_Output; }
	
	bool	IsSource () const { return IsMusicDevice() || IsGenerator(); }
	
	OSType	Type () const { return componentType; }
	OSType	SubType () const { return componentSubType; }
	OSType 	Manu () const { return componentManufacturer; }

	int		Count() const { return CountComponents(const_cast<CAComponentDescription*>(this)); }
	
		// does a semantic match where "wild card" values for type, subtype, manu will match
	bool	Matches (const ComponentDescription &desc) const;
	
	// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
	//
	//	other
	
	void	Print(FILE* file = stdout) const 	{ _CAShowComponentDescription (this, file); }

	OSStatus			Save (CFPropertyListRef *outData) const;
	OSStatus			Restore (CFPropertyListRef &inData);

private:
	static void _CAShowComponentDescription (const ComponentDescription *desc, FILE* file);
	friend void CAShowComponentDescription (const ComponentDescription *desc);
};

inline bool	operator< (const ComponentDescription& x, const ComponentDescription& y)
{
	return memcmp (&x, &y, offsetof (ComponentDescription, componentFlags)) < 0;
}

inline bool	operator== (const ComponentDescription& x, const ComponentDescription& y)
{
	return !memcmp (&x, &y, offsetof (ComponentDescription, componentFlags));
}

inline bool	operator!= (const ComponentDescription& x, const ComponentDescription& y)
{
	return !(x == y);
}

#endif
