//////////
//
//	File:		MyObject.m
//  Project:    iView
//	Contains:	Implementation file for the MyObject class.
//
//////////


#import <QuickTime/QuickTime.h>
#import <Carbon/Carbon.h>

#import "MyObject.h"
#import "MyQuickDrawView.h"


NSTimer *theTimer;

@implementation MyObject

#define BailErr(x) {err = x; if(err != noErr) goto bail;}


/**********************************************************************
*  FUNCTION: init
*  PURPOSE : Our controller's initialization method. Well
*            add our self as an observer for application
*            termination notifications, so we can perform
*            cleanup when the application quits
***********************************************************************/
- (id)init
{
    /* we'll want to be called when the application
     quits so we can do any cleanup */
     
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(applicationWillTerminate:)
        name:@"NSApplicationWillTerminateNotification" object:NSApp];

    return self;
}

/**********************************************************************
*  FUNCTION: record
*  PURPOSE : Prompts for the movie filename and records movie
***********************************************************************/
-(IBAction)record: (id)sender;
{
    OSErr err = noErr;
    
    // Create and initialise gCaption
    gCaption = [[NSMutableArray alloc] init];
    if (!gCaption)
		BailErr(kMyErrorCode);
    
    // Create and initialise gMyVideo
    gMyVideo = [[MyVideo alloc] init];
    if (!gMyVideo)
		BailErr(kMyErrorCode);
    
    // Pass gMyVideo object to MyQuickDrawViewClass because
    // we need to use the same MyVideo object over there for recording
    [view setMyMovie:gMyVideo];
    
    // Get the filename from user, but we must first relinquish the old one
    [gMovieFilename release];					
    gMovieFilename = [[gMyVideo promptMovieFilename] retain];   
    if (!gMovieFilename)
		BailErr(kMyErrorCode);
    
    // Create the movie file
    err = [gMyVideo createMovie:[view boundsRect] gWorld:[view gworld] 
		    filename:gMovieFilename];
    BailErr(err);
    
    // Configure the user interface accordingly
    [recordButton setEnabled:NO];	// disable record button
    [pauseButton setEnabled:YES];	// enable pause button
    [stopButton setEnabled:YES];	// enable stop button
    [textInput setEnabled:YES];		// enable text input
    [view setRecording:YES];		// start recording
    
	// start time of recording, used in addTextToMovie()
    gLastInsertTime = [[NSDate date] retain];

	if (!gLastInsertTime)
		BailErr(kMyErrorCode);
	
    
bail:
    // Cleanup code if something goes wrong
    if (err != noErr)
    {
		if (gCaption)
			[gCaption release];
		
		if (gMyVideo)
		{
			[gMyVideo closeMovie];
			[gMyVideo release];
		}
    }
}

/**********************************************************************
*  FUNCTION: pause
*  PURPOSE : Pauses/resumes movie recording
***********************************************************************/
-(IBAction)pause: (id)sender;
{
    BOOL recording;		// previous state of record operation

    // If the application is recording, pause it
    // if the record operation is being paused, resumes recording
    recording = [view recording];
	
	// If it was in record mode previously, we want to pause the movie
	// and disable the text box
	if (recording == YES)
		[textInput setEnabled:NO];
	else
		[textInput setEnabled:YES];
	
    [view setRecording:!recording];
}

/**********************************************************************
*  FUNCTION: stop
*  PURPOSE : Stops movie recording and adds caption to movie
***********************************************************************/
-(IBAction)stop: (id)sender;
{
    [view setRecording:NO];		// stop recording
    [gMyVideo closeMovie];		// close movie file
    [gMyVideo release];			// free resources used by gMyVideo
	[stopButton setEnabled:NO];		// disable stop button
    [recordButton setEnabled:YES];	// enable record button
    [pauseButton setEnabled:NO];	// disable pause button

    gStopTime = [NSDate date];		// stop time of recording
	
	// Add caption to movie (if we have any)
	if ([gCaption count] > 0)
		[self addTextToMovie];
	[gCaption release];
}

	
/**********************************************************************
*  FUNCTION: zoomOut
*  PURPOSE : Enlarge the image by a factor 'kZoomFactor'
***********************************************************************/
-(IBAction)zoomIn: (id)sender
{
	NSSize oldSize, newSize;
	
	[[view superview] setNeedsDisplayInRect:[view frame]];
	oldSize = [view frame].size;
	newSize.width = oldSize.width * kZoomFactor;
	newSize.height = oldSize.height * kZoomFactor;
	[view setFrameSize:newSize];
	[view setNeedsDisplay:YES];
}

/**********************************************************************
*  FUNCTION: zoomOut
*  PURPOSE : Reduce the image by a factor 'kZoomFactor'
***********************************************************************/
-(IBAction)zoomOut: (id)sender
{
	NSSize oldSize, newSize;
	
	[[view superview] setNeedsDisplayInRect:[view frame]];
	oldSize = [view frame].size;
	newSize.width = oldSize.width / kZoomFactor;
	newSize.height = oldSize.height / kZoomFactor;
	[view setFrameSize:newSize];
	[view setNeedsDisplay:YES];
}

/**********************************************************************
*  FUNCTION: inputText
*  PURPOSE : Retrieves user text from the NSTextField,
*            saves it in an array together with the pause duration 
***********************************************************************/
-(IBAction)inputText: (id)sender
{
    NSString *inputStr = [textInput stringValue];
    if (![inputStr isEqualToString:@""])
    {
		NSTimeInterval pauseDuration;
		UserText *textData;

		// lastInsertTime will always be earlier than current time
		// we take the absolute value because the result of timeIntervalSinceNow
		// will always be negative
		pauseDuration = fabs([gLastInsertTime timeIntervalSinceNow]);
		
		// Create a UserText object and add it to the gCaption array
		textData = [[UserText alloc] init];
		if (textData)
		{
			[textData setDuration:pauseDuration];
			[textData setText:inputStr];
			[gCaption addObject:textData];
			[textData release];
		}
		
		[gLastInsertTime release];
		gLastInsertTime = [[NSDate date] retain];		// Set lastInsertTime to now
    }
    
    // Make the text field active again after user hitting Enter
    [window makeFirstResponder: textInput];
}

/**********************************************************************
*  FUNCTION: addTextToMovie
*  PURPOSE : Adds user text to movie when recording is done
***********************************************************************/
-(OSErr)addTextToMovie
{
    MyMovieText *movieText = nil;
    OSErr err = noErr;
    
	movieText = [[MyMovieText alloc] init];
	NSAssert(movieText, @"movieText couldn't not be created");
	
	err = [movieText addCaptionToMovie:gCaption filename:gMovieFilename];
	if (err != noErr)
	{
		NSRunAlertPanel(@"Error", @"addCaptionToMovie failed", @"OK", nil, nil);
		return err;
	}
	
	return err;
}
    
/**********************************************************************
*  FUNCTION: awakeFromNib
*  PURPOSE : Called after all our objects are unarchived and
*            connected but just before the interface is made visible
*            to the user. We will do custom initialization of our
*            objects here
***********************************************************************/
- (void)awakeFromNib
{
    NSDictionary 	*dict;
    NSString 		*windowTitle;
    OSErr 			err;

    /* grab the name string for our window */
    NSString *filePath	= [[NSBundle mainBundle] pathForResource:@"InfoPlist" ofType:@"strings"];
    dict 				= [NSDictionary dictionaryWithContentsOfFile:filePath];
    windowTitle 		= [dict objectForKey:@"MiniMungWindowTitleString"];

    // disable stop button, pause button and text field
    [pauseButton setEnabled:NO];
    [stopButton setEnabled:NO];
    [textInput setEnabled:NO];

    /* set the window title */
    [window setTitle:windowTitle];
    
    /* pass our view object to our MyQuickDrawView class so we can access methods
        in this class from our C code routines */
    saveQDViewObjectForCallback(view);

    /* now lets create a window and display the video data passed to us by the sequence grabber */
    err = [view doSeqGrab:[view bounds]];

    /* put up an error dialog to display any errors */
    if (err != noErr)
    {
        NSString *errorStr = [[NSString alloc] initWithFormat:@"%d" , err];
        int choice;

        /* now display error dialog and quit */
        choice = NSRunAlertPanel(@"Error", errorStr, @"OK", nil, nil);
        [errorStr release];
    }
    
}


/**********************************************************************
*  FUNCTION: applicationWillTerminate
*  PURPOSE : Releases any objects we initialized
*            in our init method.
***********************************************************************/
- (void)applicationWillTerminate:(NSNotification *)notification
{
    [view endGrab];
	[gLastInsertTime release];
    [gMovieFilename release];
}


@end
