
pascal	OSErr	MoreAEOCreateAliasDesc( const AliasHandle pAliasHdl,
										AEDesc *pAliasAEDesc )
{
	OSErr	anErr = noErr;
	
	char	handleState = HGetState( (Handle)pAliasHdl );
	HLock( (Handle)pAliasHdl );
	
	anErr = AECreateDesc( typeAlias, *pAliasHdl, GetHandleSize( (Handle)pAliasHdl ), pAliasAEDesc );
	
	HSetState( (Handle)pAliasHdl, handleState );
	
	return anErr;
}//end MoreAEOCreateAliasDesc

pascal	OSErr	MoreAEOCreateAliasDescFromFSSpec( const FSSpecPtr pFSSpec,
												  AEDesc *pAliasAEDesc )
{
	OSErr			anErr = noErr;
	AliasHandle		tAliasHandle;
	
	anErr = NewAlias( NULL, pFSSpec, &tAliasHandle);
	if ( noErr == anErr  &&  tAliasHandle == NULL )
	{
		anErr = paramErr;
	}

	if ( noErr == anErr )
	{
		anErr = MoreAEOCreateAliasDesc( tAliasHandle, pAliasAEDesc );
		DisposeHandle( (Handle)tAliasHandle );
	}
		
	return anErr;
}//end MoreAEOCreateAliasDescFromFSSpec

pascal	OSErr	MoreAEOCreateAliasObjectFromFSSpec( const FSSpecPtr pFSSpec,
													AEDesc *pContainerAEDesc,
													AEDesc *pAliasObjectAEDesc )
{
	OSErr		anErr = noErr;
	AEDesc		aliasDesc = {typeNull,NULL};

	anErr = MoreAEOCreateAliasDescFromFSSpec( pFSSpec, &aliasDesc );
	if ( noErr == anErr )
	{
		anErr = CreateObjSpecifier( typeAlias, pContainerAEDesc, formAbsolutePosition,
									&aliasDesc, false, pAliasObjectAEDesc );
		MoreAEDisposeDesc( &aliasDesc );
	}
	
	return anErr;
}//end MoreAEOCreateAliasObjectFromFSSpec

pascal	OSErr	MoreAEOCreatePropertyObject( const DescType pPropertyType,
											 AEDesc *pContainerAEDesc,
											 AEDesc *propertyObjPtr )
{
	OSErr	anErr = noErr;
	AEDesc	propDesc;
	
	anErr = AECreateDesc( typeType, &pPropertyType, sizeof( pPropertyType ), &propDesc );
	if ( noErr == anErr )
	{
		anErr = CreateObjSpecifier( cProperty, pContainerAEDesc, formPropertyID,
									&propDesc, false, propertyObjPtr );
		MoreAEDisposeDesc( &propDesc );
	}
	
	return anErr;
}//end MoreAEOCreatePropertyObject

pascal	OSErr	MoreAEOCreateAliasDescFromFSRef( const FSRefPtr pFSRef,
												  AEDesc *pAliasAEDesc )
{
	OSErr			anErr = noErr;
	AliasHandle		tAliasHandle;
	
	anErr = FSNewAlias( NULL, pFSRef, &tAliasHandle);
	if ( noErr == anErr  &&  tAliasHandle == NULL )
	{
		anErr = paramErr;
	}

	if ( noErr == anErr )
	{
		anErr = MoreAEOCreateAliasDesc( tAliasHandle, pAliasAEDesc );
		DisposeHandle( (Handle)tAliasHandle );
	}
		
	return anErr;
}//end MoreAEOCreateAliasDescFromFSRef


pascal	OSErr	MoreAEOCreateAliasObjectFromFSRef( const FSRefPtr pFSRef,
													AEDesc *pContainerAEDesc,
													AEDesc *pAliasObjectAEDesc )
{
	OSErr		anErr = noErr;
	AEDesc		aliasDesc = {typeNull,NULL};

	anErr = MoreAEOCreateAliasDescFromFSRef( pFSRef, &aliasDesc );
	if ( noErr == anErr )
	{
		anErr = CreateObjSpecifier( typeAlias, pContainerAEDesc, formAbsolutePosition,
									&aliasDesc, false, pAliasObjectAEDesc );
		MoreAEDisposeDesc( &aliasDesc );
	}
	
	return anErr;
}//end MoreAEOCreateAliasObjectFromFSRef


pascal OSStatus MoreAEOCreateObjSpecifierFromFSSpec(const FSSpecPtr pFSSpecPtr,AEDesc *pObjSpecifier)
{
	OSErr 		anErr = paramErr;

	if (NULL != pFSSpecPtr)
	{
		AEDesc containerAEDesc = {typeNull,NULL};

		anErr = MoreAEOCreateAliasObjectFromFSSpec(pFSSpecPtr,&containerAEDesc,pObjSpecifier);
	}
	return anErr;
}//end MoreAEOCreateObjSpecifierFromFSSpec


pascal	OSStatus	MoreAEGetHandlerError(const AppleEvent* pAEReply)
{
	OSStatus	anError = noErr;
	OSErr		handlerErr;
	
	DescType	actualType;
	long		actualSize;
	
	if ( pAEReply->descriptorType != typeNull )	// there's a reply, so there may be an error
	{
		OSErr	getErrErr = noErr;
		
		getErrErr = AEGetParamPtr( pAEReply, keyErrorNumber, typeShortInteger, &actualType,
									&handlerErr, sizeof( OSErr ), &actualSize );
		
		if ( getErrErr != errAEDescNotFound )	// found an errorNumber parameter
		{
			anError = handlerErr;					// so return it's value
		}
	}
	return anError;
}//end MoreAEGetHandlerError

pascal OSStatus MoreAESendEventReturnAEDesc(
						const AEIdleUPP		pIdleProcUPP,
						const AppleEvent	*pAppleEvent,
						const DescType		pDescType,
						AEDesc				*pAEDesc)
{
	OSStatus anError = noErr;

	//	No idle function is an error, since we are expected to return a value
	if (pIdleProcUPP == NULL)
		anError = paramErr;
	else
	{
		AppleEvent theReply = {typeNull,NULL};
		AESendMode sendMode = kAEWaitReply;

		anError = AESend(pAppleEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, pIdleProcUPP, NULL);
		//	[ Don't dispose of the event, it's not ours ]
		if (noErr == anError)
		{
			anError = MoreAEGetHandlerError(&theReply);

			if (!anError && theReply.descriptorType != typeNull)
			{
				anError = AEGetParamDesc(&theReply, keyDirectObject, pDescType, pAEDesc);
			}
			MoreAEDisposeDesc(&theReply);
		}
	}
	return anError;
}	// MoreAESendEventReturnAEDesc

pascal OSStatus MoreAESendEventReturnAEDescList(
					const AEIdleUPP pIdleProcUPP,
					const AppleEvent* pAppleEvent,
					AEDescList* pAEDescList)
{
	return MoreAESendEventReturnAEDesc(pIdleProcUPP,pAppleEvent,typeAEList,pAEDescList);
}	// MoreAESendEventReturnAEDescList

extern pascal OSErr MoreMemError(void *p)
	// See comment in interface part.
{
	OSErr err;
	
	err = MemError();
	if ((err == noErr) && (p == NULL)) {
		assert(false);
		err = memFullErr;
	}
	return err;
}

pascal OSStatus MoreAECopyDescriptorDataToHandle(const AEDesc* pAEDesc, Handle* pDescData)
{
	OSStatus anErr;
	OSStatus junk;
	
	assert(pAEDesc   != NULL);
	assert(pDescData  != NULL);
	assert(*pDescData == NULL);
	
	*pDescData = NewHandle(AEGetDescDataSize(pAEDesc));
	anErr = MoreMemError(*pDescData);
	if (noErr == anErr) {
		HLock(*pDescData);
		junk = AEGetDescData(pAEDesc, **pDescData, AEGetDescDataSize(pAEDesc));
		assert(junk == noErr);
		HUnlock(*pDescData);
	}
	return anErr;
}//end MoreAECopyDescriptorDataToHandle

pascal	OSErr	MoreFECreateIconSuite(const AEDescList *pIconFamilyAEDescList,
										Handle *pIconSuiteHdl)
{
	OSErr	anErr = noErr;

	const	long		iconTypesCnt = 6;
	static	DescType	iconTypes[] = {	typeIconAndMask,type8BitMask,type32BitIcon,type8BitIcon,
										type4BitIcon,typeSmallIconAndMask,typeSmall8BitMask,
										typeSmall32BitIcon,typeSmall8BitIcon,typeSmall4BitIcon};
	
	AEDescList	iconList = {typeNull,NULL};
	
	if (MoreFEUsesIconFamily())
	{
		anErr = AECoerceDesc(pIconFamilyAEDescList,typeAERecord,&iconList);
	}
	else
	{
		iconList = *pIconFamilyAEDescList;
	}
	
	if (noErr == anErr)
	{
		anErr = NewIconSuite(pIconSuiteHdl);
		if (noErr == anErr)
		{
			long	index;
			AEDesc	iconDataDesc = {typeNull,NULL};
			
			for (index = 0; index < iconTypesCnt; index++)
			{
				anErr = AEGetKeyDesc(&iconList,iconTypes[ index ],
									  typeWildCard,&iconDataDesc);
				if (noErr == anErr)
				{
					Handle tmpH;
					
					anErr = MoreAECopyDescriptorDataToHandle(&iconDataDesc,&tmpH);
					if (noErr == anErr) {
						anErr = AddIconToSuite(tmpH,*pIconSuiteHdl,iconTypes[index]);
						DisposeHandle(tmpH);
						assert(noErr == MemError());
					}
				}
			}
		}
	}
	MoreAEDisposeDesc(&iconList);

	return anErr;
}	// end MoreFECreateIconSuite

pascal OSErr MoreFEGetItemIconSuite(const FSSpecPtr pFSSpecPtr,
								  const AEIdleUPP pIdleProcUPP,
										Handle	 *pIconSuiteHdl)
{
	OSErr	anErr = noErr;
	
	AppleEvent	tAppleEvent = {typeNull,NULL};
	
	if (NULL == pIdleProcUPP)	// the idle proc is required
		return paramErr;

	if (NULL == pIconSuiteHdl)	// the icon suite handle is required
		return paramErr;

	anErr = MoreAECreateAppleEventSignatureTarget(kFinderFileType,kFinderCreatorType,
											  kAECoreSuite,kAEGetData,&tAppleEvent);
	if (noErr == anErr)
	{
		AEDesc 		itemObject = {typeNull,NULL};
		
		anErr = MoreAEOCreateObjSpecifierFromFSSpec(pFSSpecPtr,&itemObject);
		if (noErr == anErr)
		{
			AEDesc 		propertyObject = {typeNull,NULL};
			
			anErr = MoreAEOCreatePropertyObject(pIconBitmap,&itemObject,&propertyObject);
			MoreAEDisposeDesc(&itemObject);
			if (noErr == anErr)
			{
				anErr = AEPutParamDesc(&tAppleEvent,keyDirectObject,&propertyObject);
				MoreAEDisposeDesc(&propertyObject);
				if (noErr == anErr)
				{
					AEDescList tAEDescList = {typeNull,NULL};

					anErr = MoreAESendEventReturnAEDescList(pIdleProcUPP,&tAppleEvent,&tAEDescList);
					if (noErr == anErr)
					{
						anErr = MoreFECreateIconSuite(&tAEDescList,pIconSuiteHdl);

						MoreAEDisposeDesc(&tAEDescList);
					}
				}
			}
		}
		// always dispose of AEDescs when you are finished with them
		(void) MoreAEDisposeDesc(&tAppleEvent);
	}
	return anErr;
}	// end MoreFEGetItemIconSuite
