+#pragma mark *** Movie Playback Scrubber and time code methods ***
+
+/* Since MacOSX Leopard QTKit has taken over some responsibility for assessing movie playback
+ * information from the old QuickTime carbon api ( time code information as well as fps, etc.).
+ * However, the QTKit devs at apple were not really big on documentation and further ...
+ * QuickTimes ability to playback HB's largely variable framerate output makes perfectly frame
+ * accurate information at best convoluted. Still, for the purpose of a custom hud based custom
+ * playback scrubber slider this has so far proven to be as accurate as I have found. To say it
+ * could use some better accuracy is not understating it enough probably.
+ * Most of this was gleaned from this obscure Apple Mail list thread:
+ * http://www.mailinglistarchive.com/quicktime-api@lists.apple.com/msg05642.html
+ * Now as we currently do not show a QTKit control bar with scrubber for display sizes > container
+ * size, this seems to facilitate playback control from the HB custom HUD controller fairly close
+ * to the built in controller bar.
+ * Further work needs to be done to try to get accurate frame by frame playback display if we want it.
+ * Note that the keyboard commands for frame by frame step through etc. work as always.
+ */
+
+// Returns a human readable string from the currentTime of movie playback
+- (NSString*) calculatePlaybackSMTPETimecodeForDisplay
+{
+ QTTime time = [aMovie currentTime];
+
+ NSString *smtpeTimeCodeString;
+ int days, hour, minute, second, frame;
+ long long result;
+
+ result = time.timeValue / time.timeScale; // second
+ frame = (time.timeValue % time.timeScale) / 100;
+
+ second = result % 60;
+
+ result = result / 60; // minute
+ minute = result % 60;
+
+ result = result / 60; // hour
+ hour = result % 24;
+ days = result;
+
+ smtpeTimeCodeString = [NSString stringWithFormat:@"Time: %02d:%02d:%02d", hour, minute, second]; // hh:mm:ss
+ return smtpeTimeCodeString;
+
+}
+
+
+// Initialize the preview scrubber min/max to appropriate values for the current movie
+-(void) initPreviewScrubberForMovie
+{
+ if (aMovie)
+ {
+
+ QTTime duration = [aMovie duration];
+ float result = duration.timeValue / duration.timeScale;
+
+ [fMovieScrubberSlider setMinValue:0.0];
+ [fMovieScrubberSlider setMaxValue: (float)result];
+ [fMovieScrubberSlider setFloatValue: 0.0];
+ }
+}
+
+
+-(void) adjustPreviewScrubberForCurrentMovieTime
+{
+ if (aMovie)
+ {
+ QTTime time = [aMovie currentTime];
+
+ float result = (float)time.timeValue / (float)time.timeScale;;
+ [fMovieScrubberSlider setFloatValue:result];
+ }
+}
+
+- (IBAction) previewScrubberChanged: (id) sender
+{
+ if (aMovie)
+ {
+ [fMovieView pause:aMovie]; // Pause the movie
+ QTTime time = [aMovie currentTime];
+ [self setTime: time.timeScale * [fMovieScrubberSlider floatValue]];
+ [self calculatePlaybackSMTPETimecodeForDisplay];
+ }
+}
+#pragma mark *** Movie Notifications ***
+
+- (void) installMovieCallbacks
+{
+
+
+/*Notification for any time the movie rate changes */
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(movieRateDidChange:)
+ name:@"QTMovieRateDidChangeNotification"
+ object:aMovie];
+ /*Notification for when the movie ends */
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(movieDidEnd:)
+ name:@"QTMovieDidEndNotification"
+ object:aMovie];
+}
+
+- (void)removeMovieCallbacks
+{
+ if (aMovie)
+ {
+ /*Notification for any time the movie rate changes */
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:@"QTMovieRateDidChangeNotification"
+ object:aMovie];
+ /*Notification for when the movie ends */
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:@"QTMovieDidEndNotification"
+ object:aMovie];
+ }
+}
+
+- (void)movieRateDidChange:(NSNotification *)notification
+{
+ if (aMovie != nil)
+ {
+ /* For some stupid reason there is no "isPlaying" method for a QTMovie
+ * object, given that, we detect the rate to determine whether the movie
+ * is playing or not.
+ */
+ //[self adjustPreviewScrubberForCurrentMovieTime];
+ if ([aMovie rate] != 0) // we are playing
+ {
+ [fPlayPauseButton setTitle: @"||"];
+ }
+ else // we are paused or stopped
+ {
+ [fPlayPauseButton setTitle: @">"];
+ }
+ }
+}
+/* This notification is not currently used. However we should keep it "just in case" as
+ * live preview playback is enhanced.
+ */
+- (void)movieDidEnd:(NSNotification *)notification
+{
+
+ //[fHBController writeToActivityLog: "Movie DidEnd Notification Received"];
+}
+
+
+#pragma mark *** QTTime Utilities ***
+
+ // convert a time value (long) to a QTTime structure
+-(void)timeToQTTime:(long)timeValue resultTime:(QTTime *)aQTTime
+{
+ NSNumber *timeScaleObj;
+ long timeScaleValue;
+
+ timeScaleObj = [aMovie attributeForKey:QTMovieTimeScaleAttribute];
+ timeScaleValue = [timeScaleObj longValue];
+
+ *aQTTime = QTMakeTime(timeValue, timeScaleValue);
+}
+
+ // set the movie's current time
+-(void)setTime:(int)timeValue
+{
+ QTTime movieQTTime;
+ NSValue *valueForQTTime;
+
+ [self timeToQTTime:timeValue resultTime:&movieQTTime];
+
+ valueForQTTime = [NSValue valueWithQTTime:movieQTTime];
+
+ [aMovie setAttribute:valueForQTTime forKey:QTMovieCurrentTimeAttribute];
+}
+