#include "stdio.h"
#include "MemUtils.h"
#include "IC_Errors.h"
#include "ADFS_LogFile.h"
#include "CCopyFile_Tree.h"
#include "CCopyFile_MetaTree.h"

/**********************************************/
OSErr			CCopyFile_MetaTree::ICopyFile_MetaTree(
	CCopyFile		*parent0, 
	Ptr				destFolderP)
{
	OSErr		err		= noErr;
	
	//	i'll never add sources to a MetaTree, since it is used
	//	only for writing (to a dest)
	err = _inherited::ICopyFile(parent0, CCT_Copy_META_TREE, destFolderP);

	return err;
}

void	CCopyFile_MetaTree::Dispose(void)
{
	_inherited::Dispose();
}

/**********************************************/
CCopyTree	*CCopyFile_MetaTree::GetDestTree(void)
{
	return (CCopyTree *)(i_myData);
}

OSErr	CCopyFile_MetaTree::GetFileInfo(CCT_MemFileRec *fileRecP)
{
	OSErr		err = noErr;
	
	//	you can't read from a meta tree
	ReportError(err = IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return err;
}
	
/**********************************************/
OSErr	CCopyFile_MetaTree::IsFolder(Boolean *isFolderB)
{
	OSErr			err			= noErr;

	*isFolderB = TRUE;
	
	return err;
}
	
OSErr	CCopyFile_MetaTree::CountFilesInFolder(ulong *numFilesL)
{
	OSErr			err			= noErr;

	//	you can't read from a meta tree
	ReportError(err = IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return err;
}

OSErr	CCopyFile_MetaTree::GetIndFileInFolder(ulong fileIndex, Ptr *fileDataP)
{
	OSErr			err			= noErr;

	//	you can't read from a meta tree
	ReportError(err = IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return err;
}

/**********************************************/
OSErr	CCopyFile_MetaTree::CreateFile(Ptr parentFolderP, CCT_MemFileRec *fileRec)
{
	OSErr			err				= noErr;
	CCopyTree		*destTree		= GetDestTree();
	CCT_MemFileRecH	memFileRecH		= (CCT_MemFileRecH)TrackNewHandleClear("mem file rec",
		sizeof(CCT_MemFileRec));
	
	if (memFileRecH == NULL) {
		ReportError(err = IC_Err_OUT_OF_MEMORY);
	}
	
	if (!err) {
		(**memFileRecH) = *fileRec;
		
		if (destTree == (CCopyTree *)parentFolderP) {
			parentFolderP = NULL;
		}
		
		if (!err) err = destTree->AddEntry(
			(CCopyFile *)parentFolderP, CCT_Copy_TREE, 
			(Ptr)memFileRecH, (CCopyFile **)&i_myFileData);
	}

	return err;
}
	
OSErr		CCopyFile_MetaTree::SetFileInfo(CCT_MemFileRec *fileRecP)
{
	OSErr		err = noErr;

	//	nothin' going on here

	return err;
}

void		CCopyFile_MetaTree::DisposeData(void)
{
	_inherited::DisposeData();
}
	
/**********************************************/
OSErr			CCopyFile_MetaTree::Open(ADFS_IOType ioType, Boolean resForkB)
{
	OSErr		err	= _inherited::Open(ioType, resForkB);
	
	if (!err) {
		CCopyFile_Tree	*copyFile		= (CCopyFile_Tree *)i_myFileData;
		CCT_MemFileRecH	memFileRecH		= copyFile->GetFileRecH();
		Handle			*forkHP;
		
		forkHP		= i_res_forkB ? &(**memFileRecH).resH : &(**memFileRecH).dataH;

		err = ASSERT(*forkHP == NULL && ioType == ADFS_IO_WRITE);
		
		if (!err) {
			*forkHP = TrackNewHandle((char *)(i_res_forkB ? "tree file res fork" : "tree file data fork"), 0);

			if (*forkHP == NULL) {
				ReportError(err = IC_Err_OUT_OF_MEMORY);
			}
		}
	}
		
	return err;
}

OSErr			CCopyFile_MetaTree::Close(void)
{
	OSErr		err = noErr;
	
	err = _inherited::Close();
	
	return err;
}

OSErr			CCopyFile_MetaTree::Read(ulong *bytesIO, char *bufP)
{
	OSErr		err = noErr;
	
	//	you can't read from a meta tree
	ReportError(err = IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return err;
}

OSErr			CCopyFile_MetaTree::Write(ulong *bytesIO, char *bufP)
{
	OSErr			err				= noErr;
	CCopyFile_Tree	*copyFile		= (CCopyFile_Tree *)i_myFileData;
	CCT_MemFileRecH	memFileRecH		= copyFile->GetFileRecH();
	Handle			forkH			= i_res_forkB ? (**memFileRecH).resH : (**memFileRecH).dataH;
	
	err = ASSERT(forkH != NULL);
	if (!err) {
		err = TrackPtrAndHand(bufP, forkH, *bytesIO);
		if (err) ReportError(IC_Err_OUT_OF_MEMORY);
	}
	
	return err;
}

OSErr			CCopyFile_MetaTree::VerifyFreeSpace(CCT_CopyRec *copyRecP)
{
	OSErr			err			= noErr;
	Size			size;
	long			neededMem = copyRecP->totalSizeL;
	
	PurgeMem((long)neededMem);
	size = CompactMem((long)neededMem);
	
	if (size < neededMem) {
		char	strAC[256];
		
		//	ReportFreeSpace(neededMem);
		sprintf(strAC, "Out of memory.  (Requested: %d KB)", (int)(((float)(neededMem - size) / 1024.0) + 1));
		ReportErrorStr(err = IC_Err_OUT_OF_MEMORY, strAC);
	}
	
	return err;
}

OSErr			CCopyFile_MetaTree::VerifyFileSize(CCopyFile *sourceP, ulong fileSizeL)
{
	return _inherited::VerifyFileSize(sourceP, fileSizeL);
}

OSErr			CCopyFile_MetaTree::GetSizeSelf(CCT_CopyRec *copyRecP)
{
	OSErr			err			= noErr;
	
	//	you can't read from a meta tree
	ReportError(err = IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return err;
}

OSErr			CCopyFile_MetaTree::ScanForCopySelf(Ptr myDataP, CCopyFile **fileExistsH)
{
	OSErr		err = noErr;

	if ((CCopyTree *)myDataP == GetDestTree()) {
		*fileExistsH = this;
	}
	
	return err;	
}

OSErr			CCopyFile_MetaTree::GetParentRef(Ptr *parentFolderH)
{
	OSErr		err		= noErr;

	*parentFolderH	= (Ptr)i_parentP0;

	return err;
}

OSErr			CCopyFile_MetaTree::GetVolumeRef(Ptr *volumeH)
{
	OSErr		err		= noErr;
	
	*volumeH		= (Ptr)i_copyTreeP;
	
	return err;
}

void			CCopyFile_MetaTree::LogCopyFileType(void)
{
	ADFS_Log("a meta tree");
}

Boolean			CCopyFile_MetaTree::IsForked(void)
{
	//	you can't read from a meta tree
	ReportError(IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return FALSE;
}

Boolean			CCopyFile_MetaTree::SupportsForks(void)
{
	return TRUE;
}

OSErr			CCopyFile_MetaTree::GetForkInfo(CCT_ForkInfo *forkInfoP)
{
	OSErr		err		= noErr;

	//	you can't read from a meta tree
	ReportError(err = IC_Err_READ_ILLEGAL_FILE_BLOCK);

	return err;
}

OSErr			CCopyFile_MetaTree::SetForkInfo(CCT_ForkInfo *forkInfoP)
{
	OSErr		err		= noErr;

	//	nothin' going on here?

	return err;
}


