/*=============================================================================
 *  CAFileHandling.h
 
	$Log: CAFileHandling.h,v $
	Revision 1.13  2004/06/02 19:59:32  bills
	CreateTrees Needs to know if it should search for Network Dir
	
	Revision 1.12  2004/05/26 17:21:02  luke
	[3656248] allow constructor option to search Network
	
	Revision 1.11  2003/12/02 01:11:43  luke
	factor subclasses out into separate files.  AUPresetFile stays public, others are private.
	
	Revision 1.10  2003/11/17 20:19:25  bills
	add comment
	
	Revision 1.9  2003/11/06 22:23:26  luke
	Subdirectory construction needs to happen in the base class
	
	Revision 1.8  2003/10/22 21:48:32  luke
	add interface to get a particular tree's path
	
	Revision 1.7  2003/10/14 19:16:52  luke
	(GetItemNameCopy + GetDirectoryNameCopy) -> GetNameCopy
	
	Revision 1.6  2003/10/14 18:19:39  luke
	pull GetDirectoryNameCopy() functionality from GetItemNameCopy()
	
	Revision 1.5  2003/10/14 17:18:46  luke
	add context-awareness & fix spelling errors
	
	Revision 1.4  2003/10/11 22:58:08  bills
	add support for au effect chains
	
	Revision 1.3  2003/10/05 23:14:54  bills
	tweaks and add support for MIDIThru
	
	Revision 1.2  2003/10/04 07:06:03  bills
	further additions
	
	Revision 1.1  2003/10/04 01:42:12  bills
	initial checkin
	

 *  Created by William Stewart on Thu Oct 02 2003.
 *  Copyright (c) 2003 Apple Computer. All rights reserved.
==============================================================================*/

#ifndef __CAFileHandling_h__
#define __CAFileHandling_h__

#include <CoreServices/CoreServices.h>
#include "CAComponent.h"

// Creates a Tree from Library/Audio/
// Each contained tree's context.info is a CFURLRef - The client should NOT release this URL
// The Returned Trees are owned by the objects
// if you save a file in one of the trees, it is added to the tree for you

// The Root of the tree handed back contains the parent dir from which all of the tree is built

// A CAFileHandling subclass is designed to deal with files of a particular type
// Thus, the IsItem call will return true if Tree node matches the described files

// Thanks to Marc Poirier for suggestions incorporated into this implementation

class CAFileHandling 
{
public:
		// *all* files have the same name key
	static const CFStringRef	kItemNameKey;
	
											// may return NULL if no tree in this domain
	CFTreeRef							GetLocalTree () const { return mLocalTree; }
	CFTreeRef							GetUserTree () const { return mUserTree; }
	CFTreeRef							GetNetworkTree () const { return mNetworkTree; }
	
	OSStatus							SaveInDirectory (CFTreeRef inTree, CFStringRef fileName, CFPropertyListRef inData);
											
											//can pass in a pointer to a CFString if this is NOT null on return - must release it
	OSStatus							ReadFromTreeLeaf (CFTreeRef inTreeLeaf, CFPropertyListRef &outData, 
																			CFStringRef *outErrString = NULL) const;
	
	bool								IsDirectory (CFTreeRef inTree) const;

	bool								IsItem (CFTreeRef inTree) const;
    
    bool								IsUserContext (CFTreeRef inTree);
    bool								IsNetworkContext (CFTreeRef inTree);
    bool								IsLocalContext (CFTreeRef inTree);
    
											// these calls can create the sub directories
											// that should exist in the specified locale
											// this will create root trees for these directories
											// returns noErr if these directories exist
	OSStatus							CreateUserDirectories ();
	OSStatus							CreateNetworkDirectories ();
	OSStatus							CreateLocalDirectories ();
										
	OSStatus							CreateDirectory (CFTreeRef inDirTree, CFStringRef inDirName, CFTreeRef *outTree);
    
	OSStatus							GetNameCopy (CFTreeRef inTree, CFStringRef &outName) const;
    OSStatus							GetPathCopy (CFTreeRef inTree, CFURLRef &outURL) const;
    
	void								ShowEntireTree (CFTreeRef inTree);
	
protected:
										CAFileHandling (CFStringRef inSubDir, bool inShouldSearchNetwork);
										virtual ~CAFileHandling ();

	static OSStatus						FindSpecifiedDir (const FSRef &inParentDir, CFStringRef inSubDir, FSRef &outDir, bool inCreateDir = false);
	bool								HasValidDir () const { return mHasUserDir || mHasLocalDir || mHasNetworkDir; }
	const FSRef*						GetUserDir () const { return mHasUserDir ? &mUserDir : NULL; }
	const FSRef*						GetLocalDir () const { return mHasLocalDir ? &mLocalDir : NULL; }
	const FSRef*						GetNetworkDir () const { return mHasNetworkDir ? &mNetworkDir : NULL; }
    
	void								CreateTrees (bool inShouldSearchNetwork);
		
		// if NULL it will invalidate user dir
		// if NOT NULL AND user dir is valid, resets base level directory
	void  								SetUserDir (FSRef *inRef);
	void  								SetLocalDir (FSRef *inRef);
	void  								SetNetworkDir (FSRef *inRef);

	virtual	const CFStringRef			GetExtension () const = 0;
	virtual bool						ValidPropertyList (CFPropertyListRef inData);
	virtual OSStatus					CreateSubDirectories (FSRef &inParentRef, SInt16 inDomain);
	virtual OSStatus					PremassageDataToSave (CFPropertyListRef inData, CFStringRef inName, CFPropertyListRef &outData)
										{
											outData = inData;
											return noErr;
										}
	virtual void						PostmassageSavedData (CFPropertyListRef inData) {}
	virtual void						PostProcessReadData (CFPropertyListRef readData, CFPropertyListRef &outData) const
										{
											outData = readData;
										}

private:
	static OSStatus			FindSpecifiedDir (SInt16 inDomain, CFStringRef inAudioSubDirName, FSRef &outDir, bool inCreateDir = false);

	static CFTreeRef 		AddFileItemToTree (const FSRef &inRef, CFTreeRef inParentTree);
	static CFTreeRef		CreateTree (const FSRef &inRef);
	static CFTreeRef		CreateTree (CFURLRef inURL);
	CFTreeRef 				CreateNewTree (const FSRef* inRef, CFTreeRef inTree);
	void					Scan (const FSRef &inParentDir, CFTreeRef inParentTree);

	FSRef			mLocalDir, mNetworkDir, mUserDir;
	bool			mHasLocalDir, mHasNetworkDir, mHasUserDir;
	CFTreeRef		mLocalTree, mUserTree, mNetworkTree;
	CFStringRef		mSubDirName;
};

#endif
