/*=============================================================================
	CAAudioFileFormats.h
	
	$Log: CAAudioFileFormats.h,v $
	Revision 1.4  2005/02/25 02:01:46  dwyatt
	some things should be declared AudioFileTypeID
	
	Revision 1.3  2004/10/15 17:10:34  dwyatt
	CAAudioFile rewrite to use ExtAudioFile (changeable via compile flag in CAAudioFile.h)
	
	Revision 1.2  2004/09/03 03:55:45  jcm10
	fix various header issues
	
	Revision 1.1  2004/05/25 23:30:10  dwyatt
	moved from Source/Tests/AudioFileTools/Utility
	
	Revision 1.2  2004/05/15 01:20:10  dwyatt
	track changes to CAAudioFile etc.
	
	Revision 1.1  2004/01/14 00:09:51  dwyatt
	moved from Source/Tests/AudioFileUtility/Utility
	
	Revision 1.3  2003/08/27 23:44:01  dwyatt
	force use of CAAudioFileFormats::Instance()
	
	Revision 1.2  2003/08/04 23:45:20  dwyatt
	track extensions, add OSTypeToStr
	
	Revision 1.1  2003/06/23 23:07:37  dwyatt
	initial checkin
	
	created Fri Jun 20 2003, Doug Wyatt
	Copyright (c) 2003 Apple Computer, Inc.  All Rights Reserved

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

#ifndef __CAAudioFileFormats_h__
#define __CAAudioFileFormats_h__

#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
	#include <AudioToolbox/AudioToolbox.h>
#else
	#include <AudioToolbox.h>
#endif
#include "CAStreamBasicDescription.h"

class CAAudioFileFormats {
public:
	struct DataFormatInfo {
		DataFormatInfo() : mVariants(NULL) { }
		~DataFormatInfo() { delete[] mVariants; }
		
		UInt32							mFormatID;
		int								mNumVariants;
		AudioStreamBasicDescription *	mVariants;
		bool							mReadable;
		bool							mWritable;
		bool							mEitherEndianPCM;

#if DEBUG
		void	DebugPrint();
#endif
	};
	
	struct FileFormatInfo {
		FileFormatInfo() : mFileTypeName(NULL), mExtensions(NULL), mDataFormats(NULL) { }
		~FileFormatInfo() {
			delete[] mDataFormats;
			if (mFileTypeName)
				CFRelease(mFileTypeName);
			if (mExtensions)
				CFRelease(mExtensions);
		}
		
		AudioFileTypeID					mFileTypeID;
		CFStringRef						mFileTypeName;
		CFArrayRef						mExtensions;
		int								mNumDataFormats;
		DataFormatInfo *				mDataFormats;
		
		int		NumberOfExtensions() { return mExtensions ? CFArrayGetCount(mExtensions) : 0; }
		char *	GetExtension(int index, char *buf, int buflen) {
					CFStringRef cfext = (CFStringRef)CFArrayGetValueAtIndex(mExtensions, index);
					CFStringGetCString(cfext, buf, buflen, kCFStringEncodingUTF8);
					return buf;
				}
		bool	AnyWritableFormats();
		
#if DEBUG
		void	DebugPrint();
#endif
	};
	
private:	// use Instance()
	CAAudioFileFormats();
	~CAAudioFileFormats();
public:
	
	bool	InferDataFormatFromFileFormat(AudioFileTypeID filetype, CAStreamBasicDescription &fmt);
	
	bool	InferFileFormatFromDataFormat(const CAStreamBasicDescription &fmt, AudioFileTypeID &filetype);

	bool	IsKnownDataFormat(UInt32 dataFormat);
	
#if DEBUG
	void	DebugPrint();
#endif

	int					mNumFileFormats;
	FileFormatInfo	*	mFileFormats;
	
	FileFormatInfo *	FindFileFormat(UInt32 formatID);

	static CAAudioFileFormats *	Instance();

private:	
	static CAAudioFileFormats *	sInstance;
};

char *	OSTypeToStr(char *buf, UInt32 t);
int		StrToOSType(const char *str, UInt32 &t);

#endif // __CAAudioFileFormats_h__
