/*=============================================================================
	CAComponentDescription.cpp
 
	$Log: CAComponentDescription.cpp,v $
	Revision 1.8  2004/09/28 23:16:13  jcm10
	add missing include
	
	Revision 1.7  2004/07/30 21:23:05  bills
	fix comp type printing
	
	Revision 1.6  2004/07/29 01:43:13  bills
	fix printing of component desc types
	
	Revision 1.5  2003/06/15 23:57:31  bills
	add Offline knowledge
	
	Revision 1.4  2003/03/21 06:53:37  bills
	prelim impl of CA-AU persistence
	
	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 __MyCompanyName__. All rights reserved.

=============================================================================*/

#include "CAComponentDescription.h"
#include <ctype.h>

extern "C" void CAShowComponentDescription(const ComponentDescription *desc)
{
	CAComponentDescription::_CAShowComponentDescription (desc, stdout);
}

char *StringForOSType (OSType t, char *writeLocation)
{
	char *p = writeLocation;
	unsigned char str[4], *q = str;
	*(UInt32 *)str = EndianU32_NtoB(t);
	for (int i = 0; i < 4; ++i) {
		if (isprint(*q) && *q != '\\')
			*p++ = *q++;
		else {
			sprintf(p, "\\x%02X", *q++);
			p += 4;
		}
	}
	*p = '\0';
	return writeLocation;
}


void 	CAComponentDescription::_CAShowComponentDescription(const ComponentDescription *desc, FILE* file)
{
	if (desc)
	{
		char str[24];
		fprintf (file, "ComponentDescription: %4.4s - ", StringForOSType(desc->componentType, str));
		fprintf (file, "%s - ", StringForOSType(desc->componentSubType, str));
		fprintf (file, "%s", StringForOSType(desc->componentManufacturer, str));		
		fprintf (file, ", 0x%lX, 0x%lX\n", desc->componentFlags, desc->componentFlagsMask);
	}
}

CAComponentDescription::CAComponentDescription (OSType inType, OSType inSubtype, OSType inManu)
{
	componentType = inType;
	componentSubType = inSubtype;
	componentManufacturer = inManu;
	componentFlags = 0;
	componentFlagsMask = 0;
}

bool	CAComponentDescription::IsAU () const 
{ 
	bool flag = IsEffect() || IsMusicDevice() || IsOffline();
	if (flag) return true;
	
	switch (componentType) {
		case kAudioUnitType_Output:
		case kAudioUnitType_FormatConverter:
		case kAudioUnitType_Mixer:
			return true;
	}
	return false;
}

inline bool _MatchTest (const OSType &inTypeA, const OSType &inTypeB)
{
	return ((inTypeA == inTypeB) || (!inTypeA && !inTypeB) || (inTypeA && !inTypeB) || (!inTypeA && inTypeB)); 
}

bool	CAComponentDescription::Matches (const ComponentDescription &desc) const
{
	bool matches = false;
		
		// see if the type matches
	matches = _MatchTest (componentType, desc.componentType);
	
	if (matches)
		matches = _MatchTest (componentSubType, desc.componentSubType);
	
	if (matches)
		matches = _MatchTest (componentManufacturer, desc.componentManufacturer);
	
	return matches;
}
