//////////
//
//	File:		QTFlattenToHandle.c
//
//	Contains:	Handle data handler sample code.
//
//	Written by:	Tim Monroe
//				Based on the existing code revised by Deeje Cooley.
//
//	Copyright:	© 1998 by Apple Computer, Inc., all rights reserved.
//
//	Change History (most recent first):
//
//	   <4>	 	03/21/00	rtm		changed QTHandle_OpenMovieFileAndFlattenToHandle to use FSSpec parameter
//	   <3>	 	02/01/99	rtm		reworked window title handling to remove "\p" sequences
//	   <2>	 	05/15/98	rtm		added support for passing 0-length handles to FlattenMovieData
//	   <1>	 	04/09/98	rtm		first file; integrated existing code with shell framework
//	 
//
// A data handler is a component (of type DataHandlerType) that is responsible for reading and writing
// a media's data. In other words, a data handler provides data input and output services to the media's
// media handler. Originally, QuickTime included a file data handler. QuickTime version 2.0 introduced
// the handle data handler (component subtype HandleDataHandlerSubType), which allows you to play movie
// data stored in memory rather than in a file. This sample code shows how to work with the handle data
// handler.
//
// Here, we will open a movie file and then flatten the movie data into a handle. Then we will play the
// movie from the handle. The essential step is to create a data reference record describing the handle
// and then pass that record, instead of an FSSpec record, to FlattenMovieData. To do this, set the
// flattenFSSpecPtrIsDataRefRecordPtr flag when calling FlattenMovieData.
//
//////////

#include "QTFlattenToHandle.h"


//////////
//
// QTHandle_OpenMovieFileAndFlattenToHandle
// Open the specified movie file, and write the movie data into a handle.
// Then play the memory-based movie.
//
//////////

OSErr QTHandle_OpenMovieFileAndFlattenToHandle (FSSpecPtr theFSSpecPtr)
{
	short					myResRefNum;
	Movie					mySrcMovie;
	Movie					myMemMovie;			// the movie in our handle
	Handle					myHandle = NULL;	// the handle that contains the movie data
	long					mySize = 0L;
	long					myFlags = 0L;
	DataReferenceRecord		myDataRefRec;
	FSSpec					*myFile;
	OSErr					myErr = noErr;
	
	// open the movie file and create a movie from that file
	myErr = OpenMovieFile(theFSSpecPtr, &myResRefNum, fsRdPerm);
	if (myErr != noErr)
		goto bail;
	
	myErr = NewMovieFromFile(&mySrcMovie, myResRefNum, NULL, NULL, newMovieActive, NULL);
	if (myErr != noErr)
		goto bail;
		
	// create a 0-length handle
	myHandle = NewHandleClear(mySize);
	if (myHandle == NULL)
		goto bail;
		
	// fill in the data reference record
    myDataRefRec.dataRefType = HandleDataHandlerSubType;
    myDataRefRec.dataRef = NewHandle(sizeof(Handle));
    if (myDataRefRec.dataRef == NULL)
    	goto bail;

	*((Handle *)*(myDataRefRec.dataRef)) = myHandle;

	myFlags = flattenFSSpecPtrIsDataRefRecordPtr;
    myFile = (FSSpec *)&myDataRefRec;

	// flatten the source movie into the handle
    myMemMovie = FlattenMovieData(mySrcMovie, myFlags, myFile, 0L, smSystemScript, 0L);

	// play the movie once thru
	myErr = QTHandle_PlayMovieResource(myMemMovie);

bail:
	if (myResRefNum != 0)
		CloseMovieFile(myResRefNum);

	if (myHandle != NULL)
		DisposeHandle(myHandle);

	if (mySrcMovie != NULL)
		DisposeMovie(mySrcMovie);
	
	return(myErr);
}


//////////
//
// QTHandle_PlayMovieResource
// Play a movie.
//
//////////

OSErr QTHandle_PlayMovieResource (Movie theMovie)
{
	WindowPtr				myWindow = NULL;
	Rect					myBounds = {50, 50, 100, 100};
	Rect					myRect;
	StringPtr				myTitle = QTUtils_ConvertCToPascalString(kWindowTitle);
	OSErr					myErr = memFullErr;

	myWindow = NewCWindow(NULL, &myBounds, myTitle, false, 0, (WindowPtr)-1, false, 0);
	if (myWindow == NULL)
		goto bail;
		
	myErr = noErr;
	
	MacSetPort(myWindow);

	GetMovieBox(theMovie, &myRect);
	MacOffsetRect(&myRect, -myRect.left, -myRect.top);
	SetMovieBox(theMovie, &myRect);

	SizeWindow(myWindow, myRect.right, myRect.bottom, false);
	MacShowWindow(myWindow);

	SetMovieGWorld(theMovie, GetWindowPort(myWindow), NULL);
	GoToBeginningOfMovie(theMovie);
	MoviesTask(theMovie, 0);
	StartMovie(theMovie);
	
	myErr = GetMoviesError();
	if (myErr != noErr)
		goto bail;
	
	while (!IsMovieDone(theMovie))
		MoviesTask(theMovie, 0);

bail:
	free(myTitle);
	
	if (theMovie != NULL)
		DisposeMovie(theMovie);

	if (myWindow != NULL)
		DisposeWindow(myWindow);
		
	return(myErr);
}
