/*=============================================================================
 *  CAAUPresetFile.cpp
 
	$Log: CAAUPresetFile.cpp,v $
	Revision 1.5  2005/01/08 00:06:01  luke
	crasher [3941171] fixed
	
	Revision 1.4  2004/06/24 23:15:39  mhopkins
	Added name and data keys
	
	Revision 1.3  2004/06/02 19:59:32  bills
	CreateTrees Needs to know if it should search for Network Dir
	
	Revision 1.2  2004/05/26 17:21:01  luke
	[3656248] allow constructor option to search Network
	
	Revision 1.1  2003/12/02 01:09:53  luke
	broke CAAUPresetFile out of CAFileHandling
	
    
 *  Created by William Stewart on Thu Oct 02 2003.
 *  Copyright (c) 2003 Apple Computer. All rights reserved.
==============================================================================*/

#include "CAAUPresetFile.h"

const CFStringRef  	CAAUPresetFile::kAUPresetFileExtension = CFSTR("aupreset");
const CFStringRef 	CAAUPresetFile::kAUPresetFileDirName = CFSTR("Presets");
const CFStringRef   CAAUPresetFile::kAUPresetNameKeyString = CFSTR(kAUPresetNameKey);
const CFStringRef   CAAUPresetFile::kAUPresetDataKeyString = CFSTR(kAUPresetDataKey);

static const CFStringRef	kAUUnknownName = CFSTR("Unnamed Audio Unit");
static const CFStringRef	kAUUnknownMfr = CFSTR("Unknown Manufacturer");

CAAUPresetFile::CAAUPresetFile (CAComponent inComp, bool inShouldSearchNetwork)
	: CAFileHandling(CAAUPresetFile::kAUPresetFileDirName, inShouldSearchNetwork),
	  mComp (inComp)
{
	CFStringRef name = mComp.GetAUName();
	CFStringRef manu = mComp.GetAUManu();
	
	if (!name && !manu) {
		SetUserDir (NULL);
		SetLocalDir (NULL);
		SetNetworkDir (NULL);
		return;
	}
	
	if (!name)
		name = kAUUnknownName;
	
	if (!manu)
		manu = kAUUnknownMfr;
	
	FSRef ref;
	
	const FSRef *startRef = GetUserDir ();
	if (startRef) {
		if (GetRootDir (*startRef, manu, name, ref) == noErr)
			SetUserDir (&ref);
		else
			SetUserDir (NULL);
	}
	
	startRef = GetLocalDir ();
	if (startRef) {
		if (GetRootDir (*startRef, manu, name, ref) == noErr)
			SetLocalDir (&ref);
		else
			SetLocalDir (NULL);
	}
	
	if (inShouldSearchNetwork)
	{
		startRef = GetNetworkDir ();
		if (startRef) {
			if (GetRootDir (*startRef, manu, name, ref) == noErr)
				SetNetworkDir (&ref);
			else
				SetNetworkDir (NULL);
		}
	}
	
	if (HasValidDir())
		CreateTrees (inShouldSearchNetwork);
}

CAAUPresetFile::~CAAUPresetFile()
{
}

OSStatus		CAAUPresetFile::CreateSubDirectories (FSRef &inParentRef, SInt16 inDomain)
{
	CFStringRef name = mComp.GetAUName();
	CFStringRef manu = mComp.GetAUManu();
	if (!name && !manu)
		return -1;
	
	if (!name)
		name = kAUUnknownName;
	
	if (!manu)
		manu = kAUUnknownMfr;
	
	OSStatus result;
	FSRef ref;
	if (result = GetRootDir (inParentRef, manu, name, ref, true)) {
        switch (inDomain) {
            case kUserDomain: SetUserDir (NULL); break;
            case kLocalDomain: SetLocalDir (NULL); break;
            case kNetworkDomain: SetNetworkDir (NULL); break;
        }
        return result;
    }
	
    return CAFileHandling::CreateSubDirectories (ref, inDomain);
}

OSStatus		CAAUPresetFile::GetRootDir (const FSRef &inRef, CFStringRef manuName, CFStringRef compName, FSRef &outRef, bool inCreateDir)
{
	FSRef ref;	
	OSStatus result;
	if (result = FindSpecifiedDir (inRef, manuName, ref, inCreateDir))
		return result;

	if (result = FindSpecifiedDir (ref, compName, outRef, inCreateDir))
		return result;
	
	return noErr;
}

bool		CAAUPresetFile::ValidPropertyList (CFPropertyListRef inData)
{
	if (CAFileHandling::ValidPropertyList (inData) == false)
		return false;
		
	CFDictionaryRef dict = static_cast<CFDictionaryRef>(inData);
	CFNumberRef cfnum = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, CFSTR(kAUPresetTypeKey)));
	if (cfnum == NULL) {
		return false;
	}
	OSType type;
	CFNumberGetValue (cfnum, kCFNumberSInt32Type, &type);
	
	cfnum = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, CFSTR(kAUPresetSubtypeKey)));
	if (cfnum == NULL) {
		return false;
	}
	OSType subtype;
	CFNumberGetValue (cfnum, kCFNumberSInt32Type, &subtype);

	cfnum = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, CFSTR(kAUPresetManufacturerKey)));
	if (cfnum == NULL) {
		return false;
	}
	OSType manu;
	CFNumberGetValue (cfnum, kCFNumberSInt32Type, &manu);
				
	if (!(manu == mComp.Desc().Manu() && subtype == mComp.Desc().SubType() && type == mComp.Desc().Type()))
		return false;

	return true;
}

bool		CAAUPresetFile::IsPartPreset (CFTreeRef inTree) const
{
	CFPropertyListRef preset;
	OSStatus result;
	if ((result = ReadFromTreeLeaf (inTree, preset)) == noErr) 
	{
		CFStringRef partKey = CFSTR (kAUPresetPartKey);
		if (CFGetTypeID(preset) == CFDictionaryGetTypeID()) {
			bool res = CFDictionaryContainsKey ((CFDictionaryRef)preset, partKey);
			CFRelease (preset);
			return res;
		}
		CFRelease (preset);
		return false;
	}
	return false;
}
