//  Created by Allen Ingling on Wed Mar 31 2004.
//  Copyright (c) 2004 New York University. All rights reserved.



#import "HipsHelpers.h"
#import "PlayMovie.h"
#import "HipsViewer.h"		

@implementation PlayMovie

+ (void)connectWithPorts:(NSArray *)portArray

{
    NSAutoreleasePool   *pool;
    NSConnection		*serverConnection;
    PlayMovie			*serverObject;
	
    pool = [[NSAutoreleasePool alloc] init];
    serverConnection = [NSConnection connectionWithReceivePort:[portArray objectAtIndex:0]
	sendPort:[portArray objectAtIndex:1]];
    serverObject = [[self alloc] init];
    [(id)[serverConnection rootProxy] setServer:serverObject];
    [serverObject release];
    [[NSRunLoop currentRunLoop] run];
    [pool release];
    return;
}




- (oneway void)play:(HipsViewer*)viewer;
{
	int						localFrameIncrement, lapCounter, frameNumber, numMovieFrames;
	BOOL					goMovieFlag, palindromeBounceFlag, limitNumLoopPasses, hitBackstop, hitFrontstop, wrap, palendromic, reboundFromStop, goMovieFlagLocal, realtimeMode;
	BOOL					exitOnKeypress;



//	numTimeSamples=0;
//	[self disableDisplayChoiceControls];
	[viewer enableNonPlaytimeControls:FALSE];
	frameNumber=[viewer getFrameNumber];
	goMovieFlag=TRUE;
	lapCounter=0;
	limitNumLoopPasses=[viewer getNumPlayLoops];
	palindromeBounceFlag=[viewer getPalindromeSwitchOutletState]; //have not yet  bounced
	localFrameIncrement=[viewer getFrameIncrement];
	numMovieFrames=[viewer getNumFrames];
	realtimeMode=[viewer getRealtimeMode];
	exitOnKeypress=[viewer getExitOnKeypress];
	if([viewer getSampleBlitTimesSwitch]==NSOnState)
		[viewer setSampleBlitTimesFlag:TRUE];
	//insert call here to convert either the forwared or reverse play  button into a pause button.
//	[self setBackgroundColor:[self getFullscreeBackgroundModeFromButtons] FALSE];
//	keyscanMovieStartTime=GetSecs();
//	if(recordKeysFlag)
//		[controlPanelWindowOutlet setEventTimeReference];
	//raise this thread's priority
	if(playThreadPriority>0){
		SetRealtimePriority(playThreadPriority);		//raise this thread's priority now.
		[viewer activateRealtimeImmediate:TRUE];		//ask the viewer thread to raise its priority asap.
	}
	//set the viewer thread's priority
	while(1){
	
		if(exitOnKeypress){
			if([viewer checkForKeypress])
				[viewer printKeysAndExit];
		}

		// Other threads can set variables.  Make  local copies of global state to assure coherent state for duration of a loop pass. (There are better ways to do this.)
		wrap=[viewer getLoopSwitchOutletState]==NSOnState;
		palendromic=[viewer getPalindromeSwitchOutletState] == NSOnState;

		[viewer blitFrame];
		[viewer setFrameNumber:frameNumber];
		
		//update the controls display
		[viewer setFrameNumberControls];

		//test for end stop hit and stop
	    hitBackstop= frameNumber+1==numMovieFrames && localFrameIncrement==1;
		hitFrontstop= frameNumber == 0 && localFrameIncrement==-1;   
		reboundFromStop= palendromic && wrap || palendromic && palindromeBounceFlag;
		goMovieFlagLocal= [viewer getGoMovieFlag] && !( (hitBackstop || hitFrontstop) && !(reboundFromStop || wrap)); 
		if((hitBackstop || hitFrontstop) && !wrap)
			palindromeBounceFlag =  FALSE;
		if((hitBackstop || hitFrontstop) && limitNumLoopPasses)
			lapCounter=lapCounter+1;
		if(limitNumLoopPasses && lapCounter==limitNumLoopPasses)
			break;
		//quit if necessary
		if(!goMovieFlagLocal)
			break;

		//for next looop pass, increment or decrement frame number and flip play increment sign if necessary
		if(!(hitBackstop || hitFrontstop)){
			frameNumber=frameNumber + localFrameIncrement;
		}else if(hitBackstop && reboundFromStop){
			//insert call here to reverse activate the play direction button on the UI.
			localFrameIncrement=-1;
			frameNumber=frameNumber + localFrameIncrement;
		}else if(hitBackstop && !reboundFromStop){
			frameNumber=0;
		}else if(hitFrontstop && reboundFromStop){
			//insert call here to reverse activate the play direction button on the UI.
			localFrameIncrement=1;
			frameNumber=frameNumber + localFrameIncrement;
		}else if(hitFrontstop && !reboundFromStop){
			frameNumber=numMovieFrames - 1;
		}

	}
	if(playThreadPriority>0){
		SetRealtimePriority(0);		// lower this thread's priority now.
		[viewer activateRealtimeImmediate:FALSE];		// ask the viewer thread to lower its priority.
	}
	[viewer setSampleBlitTimesFlag:FALSE];
	[viewer setFrameIncrement:localFrameIncrement];
	[viewer setThreadLock:FALSE];
	[viewer setNumPlayLoopPasses:0];	//zero means no limit.  Only the command line loader sets this > 0.  Clear it for subsequent gui dorking.
	[viewer enableNonPlaytimeControls:TRUE];
	[viewer turnOffPlayButton];
}


- (oneway void)playTest:(HipsViewer*)viewer
{
	int		i;
	
	for(i=0;i<80;i++){
//      [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)framePeriodSecs]];
		[viewer setFrameNumber:i];
		[viewer blitFrame];
		[viewer setFrameNumberControls];
	}
	[viewer setThreadLock:FALSE];
}


- (oneway void)activateRealtimeDeferred:(BOOL)turnOn
{
	if(turnOn)
		playThreadPriority=4;
	else
		playThreadPriority=0;
}


- (id)init
{
    self = [super init];
    if (self != nil){
		//initialize instance variables here
		framePeriodSecs=(double)1/(double)60;
    }
    return (self);
}

- (oneway void)setFramePeriod:(double)periodSecs
{
	framePeriodSecs=periodSecs;
}


@end



