// Graphics Importer and Exporter Samples
// This example opens a movie file, allows you to save
// the movie as a sequence of frames. It then creates a new
// reference movie from those images and saves it.
// Originally written by Sam Bushell for QuickTime "Live" '99
// WWDC 2000 Introduction to QuickTime

#include "MacShell.h"

void MovieToImage( void )
{
	OSErr  err = noErr;
	Handle hOpenTypeList = NewHandle(0);
	long  numTypes = 0;
	FSSpec theFSSpec;
	Boolean isSelected, isReplacing;
	Rect naturalBounds, windowBounds;
	WindowPtr window = NULL;
	short refNum = -1, resID = NULL;
	Movie movie = 0;
	MovieExportComponent movieExporter = 0;
	Boolean canceled = true;
	MovieImportComponent movieImporter = 0;
	Track usedTrack;
	TimeValue addedDuration;
	long outFlags;
	
    if ( !BuildMovieValidFileTypes( hOpenTypeList, &numTypes ) ) {
        HLock( hOpenTypeList );
    } else {
        DisposeHandle( hOpenTypeList );
        return;
    }

	err = GetOneFileWithPreview(numTypes, (OSTypePtr)*hOpenTypeList, &theFSSpec, NULL);
	DisposeHandle( hOpenTypeList );
	if ( err ) return;
	
	// open a movie file
	err = OpenMovieFile( &theFSSpec, &refNum, fsRdPerm );
	err = NewMovieFromFile( &movie, refNum, &resID, NULL, newMovieActive, NULL );
	err = CloseMovieFile( refNum );
	refNum = -1;
	
	GetMovieBox( movie, &naturalBounds );
	windowBounds = naturalBounds;
	OffsetRect( &windowBounds, 10, 45 );
	window = NewCWindow( NULL, &windowBounds, "\pMovie <-> Images", true, documentProc, (WindowPtr)-1, true, 0);
	SetPortWindowPort( window );
	
	// play the movie
	SetMovieGWorld( movie, GetWindowPort( window), NULL );
	GoToBeginningOfMovie( movie );
	StartMovie( movie );
	while( false == IsMovieDone( movie ) ) {
		MoviesTask( NULL, 0 );
	}
	StopMovie( movie );
	
	pause();

	// save the movie as a sequence of image files.
	err = PutFile( "\pSave as image sequence:", "\psequence", &theFSSpec, &isSelected, &isReplacing);
	if (err) return;
	
	// open a movie exporter
// Step 1. Insert OpenADefaultComponent1.clp here...

	
	// configure the export component by showing the dialog box
// Step 2. Insert MovieExportDoUserDialog.clp here...

	if( canceled ) return;
	
	// attach a progress function; -1 for default progress function
	SetMovieProgressProc( movie, (MovieProgressUPP)-1, 0 );
	
	// convert the movie into a specified file(s) and type
// Step 3. Insert ConvertMovieToFile.clp here...
	
	CloseComponent( movieExporter );
	DisposeMovie( movie );
	movie = 0;
	EraseRect( &naturalBounds );
	
    hOpenTypeList = NewHandle(0);
	// now re-open the sequence of image files as a reference movie
	if ( !BuildGraphicsImporterValidFileTypes( hOpenTypeList, &numTypes ) ) {
        HLock( hOpenTypeList );
    } else {
        DisposeHandle( hOpenTypeList );
        return;
    }

	err = GetOneFileWithPreview(numTypes, (OSTypePtr)*hOpenTypeList, &theFSSpec, NULL);
	DisposeHandle( hOpenTypeList );
	if ( err ) return;

	// open a movie importer
// Step 4. Insert OpenADefaultComponent2.clp here...
	
	// we're using a movie importer that imports images using graphics importers
	// this subType-specific call enables the "Import Image Sequence..." behaviour,
	// letting the movie importer search for adjacent files with names matching a numeric pattern.					 
	GraphicsImageImportSetSequenceEnabled( movieImporter, true );
	canceled = true;
	
	// configure the import component by showing the user dialog box
// Step 5. Insert MovieImportDoUserDialog.clp here...

	if( canceled ) return;
	
	// create the new movie
	movie = NewMovie(newMovieActive);
	
	// do the import of the sequence
// Step 6. Insert MovieImportFile.clp here...

	CloseComponent( movieImporter );

	// play the reference movie.
	SetMovieGWorld(movie, GetWindowPort(window), NULL);
	GoToBeginningOfMovie( movie );
	StartMovie( movie );
	while( false == IsMovieDone( movie ) ) {
		MoviesTask( NULL, 0 );
	}
	StopMovie( movie );
	
	// save the reference movie.
	err = PutFile( "\pSave as reference movie:", "\preference movie.mov", &theFSSpec, &isSelected, &isReplacing);
	if (err) return;

	// create a movie file; has options controled by flags
// Step 7. Insert CreateMovieFile.clp here...


// Step 8. Insert Step8.clp here...
	
	UpdateMovie( movie );
	MoviesTask( NULL, 0 );
	DisposeMovie( movie );
}
