/* Copyright (c) 2004, Noah Sorscher
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 	¥ 	Redistributions of source code must retain the above copyright
 * 	notice, this list of conditions and the following disclaimer.
 * 	¥ 	Redistributions in binary form must reproduce the above copyright
 * 	notice, this list of conditions and the following disclaimer in the
 * 	documentation and/or other materials provided with the distribution.
 * 	¥ 	Neither the name of the Noah Sorscher nor the names of its
 * 	contributors may be used to endorse or promote products derived from
 * 	this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
#import "tPlayback.h"
#include "Movies.h"
//#include "tModel.h"
//#include "QTFullScreen.h"
#import "tWindow.h"
#import "tChapters.h"
#include "tController.h"
#import "tInit.h"
#import "MHHoldButton.h"
#import "MHMenuButton.h"
#import "OverlayView.h"

@interface tPlayback (private)
- (void)setPlaying:(BOOL)playing;
@end

@interface NSCell (extra)
- (void)setImageRow:(int)row;
@end

@implementation tPlayback

/////////////////////
//
//	GLOBALS
//
////////////////

//int currentPlayingMovieID;

id tPlayNibInstance;

//////////////////////////////////
//
//	FUNCTION DECLARATIONS
//
////////////////////////////

void setTimeIndex(MHMovie *theMovie, double timeIndex);

//////////////////////////////////
//
//	Methods
//
//////////////////////////////

+ (tPlayback *)nibInstance
{
    return tPlayNibInstance;
}

- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)size
{
    //printf("%gx%g --> ", size.width, size.height);
    if (sender != viewWindow) return size;
    unsigned int currentFlags = [[NSApp currentEvent] modifierFlags];
    if (currentFlags & NSShiftKeyMask || !currentMovie) return size;
    BOOL vis = [movieView isControllerVisible];
    int width = [[currentMovie objectForKey:@"Correct Width"] intValue];
    if (vis) width -= 10;
    int height = [[currentMovie objectForKey:@"Correct Height"] intValue];
    if (vis) height -= 16;
    size.height = size.width * (double)height / (double)width;
    if (vis) {
        //size.width += 10;
        size.height += 16;
    }
    size.height += 22;
    //printf("%gx%g\n", size.width, size.height);
    return size;
}

-(BOOL)windowShouldClose:(id)sender
{
    if (sender == viewWindow)
        [movieView pause:self];
    else if (sender == [controller mainWindow])
        [windowedMovieView pause:self];
    //[tracksDrawer close];
    [self setPlaying:NO];
    if (nil == currentMovie) return YES;
    [currentMovie saveCurrentHeight];
    [currentMovie setTimeIndex:[self getSampleTimeValue]];
    return YES;
}

- (NSView *)overlayViewWithParent:(NSWindow *)parent rect:(NSRect)rect
{
    NSWindow *newWindow = [[NSWindow alloc] initWithContentRect:rect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    [newWindow setBackgroundColor:[NSColor clearColor]];
    [newWindow setAlphaValue:1.0];
    [newWindow setOpaque:NO];
    [newWindow setHasShadow:NO];
    [newWindow setContentView:[[OverlayView alloc] initWithFrame:[[newWindow contentView] frame]]];
    [newWindow setIgnoresMouseEvents:YES];
    if (parent) [parent addChildWindow:newWindow ordered:NSWindowAbove];
    return [newWindow contentView];
}

- (void)keyDown:(NSEvent *)e
{
    if ([e isKindOfClass:[NSNotification class]]) {
        NSString *chars = [[NSApp currentEvent] characters];
        if ([chars length] && ' ' == [chars characterAtIndex:0])
            [playButton performClick:self];
        else
            [[(NSNotification *)e object] keyDown:(NSEvent *)self];
    }
}

- (void)flagsChanged:(NSEvent *)event
{
    if ([event isKindOfClass:[NSNotification class]])
        event = [(NSNotification *)event object];
    if (!event) return;
    unsigned int flags = [event modifierFlags];
    if (flags & NSAlternateKeyMask) {
        if (![ffButton isDepressed]) {
            [ffButton setImage:[NSImage imageNamed:@"fff"]];
            [ffButton setNormal:YES];
            [(NSButton *)ffButton setAction:@selector(fff:)];
	    [ffButton setToolTip:@"Faster Forward"];
        }
        if (![rwButton isDepressed]) {
            [rwButton setImage:[NSImage imageNamed:@"rrw"]];
            [rwButton setNormal:YES];
            [(NSButton *)rwButton setAction:@selector(rrw:)];
	    [rwButton setToolTip:@"Faster Rewind"];
        }
        [advButton setImage:[NSImage imageNamed:@"advance"]];
        [(NSButton *)advButton setAction:@selector(nextMovie:)];
	[advButton setToolTip:@"Next Movie"];
        [revButton setImage:[NSImage imageNamed:@"repeat"]];
        [(NSButton *)revButton setAction:@selector(lastMovie:)];
	[revButton setToolTip:@"Last Movie"];
        [playButton setImage:[NSImage imageNamed:@"slow"]];
        [(NSButton *)playButton setAction:@selector(slomo:)];
	[playButton setToolTip:@"Slow"];
    } else {
        if (![ffButton isDepressed]) {
            [ffButton setImage:[NSImage imageNamed:@"ff"]];
            [ffButton setNormal:NO];
            [(NSButton *)ffButton setAction:@selector(ff:)];
	    [ffButton setToolTip:@"Fast Forward"];
        }
        if (![rwButton isDepressed]) {
            [rwButton setImage:[NSImage imageNamed:@"rw"]];
            [rwButton setNormal:NO];
            [(NSButton *)rwButton setAction:@selector(rw:)];
	    [rwButton setToolTip:@"Rewind"];
        }
        [advButton setImage:[NSImage imageNamed:@"jumpF"]];
        [(NSButton *)advButton setAction:@selector(jumpF:)];
	[advButton setToolTip:@"Advance"];
        [revButton setImage:[NSImage imageNamed:@"jumpB"]];
        [(NSButton *)revButton setAction:@selector(jumpB:)];
	[revButton setToolTip:@"Replay"];
        if ([playingMovieView rate] == 1 && [playingMovieView isPlaying]) [self setPlaying:YES];
        else [self setPlaying:NO];
    }
}

- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender defaultFrame:(NSRect)defaultFrame
{
    [miniWin orderOut:self];
    //[movieControls removeFromSuperview];
    //[movieController removeFromSuperview];
    [controller refreshToolbarItems:[NSArray arrayWithObjects:@"Movie Controller", @"Movie Controls", nil]];
    [[controller mainWindow] makeKeyAndOrderFront:nil];
    return [miniWin frame];
}

- (void)windowDidBecomeMain:(NSNotification *)aNotification
{
    if ([aNotification object] == miniWin) [controller windowDidBecomeMain:aNotification];
}

- (void)windowDidResignMain:(NSNotification *)aNotification
{
    if ([aNotification object] == miniWin) [controller windowDidResignMain:aNotification];
}

- (void)showMini
{
    //if (![miniWin toolbar]) {
        NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:@"miniWindowToolbar"] autorelease];
        [toolbar setDelegate:controller];
        [toolbar setAllowsUserCustomization:NO];
        [toolbar setAutosavesConfiguration:NO];
        [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly];
        [miniWin setToolbar:toolbar];
    //}
    NSRect norm = [[controller mainWindow] frame];
    NSRect mini = [miniWin frame];
    mini.origin.x = norm.origin.x;
    mini.origin.y = norm.origin.y + norm.size.height - mini.size.height;
    [miniWin setFrame:mini display:YES];
    [miniWin makeKeyAndOrderFront:self];
}

BOOL ocontrolsShown = NO;

- (void)showOverlayControls
{
    return;
    if (ocontrolsShown) return;
    ocontrolsShown = YES;
    float w = 300, h = 100;
    NSRect frame = [bigWindow frame];
    //NSRect sframe = [[bigWindow screen] frame];
    frame.origin.x = frame.size.width / 2 - w / 2;
    frame.origin.y = frame.size.height / 3 - h / 2;
    //frame.origin.x = frame.origin.y = 0;
    frame.size.width = w;
    frame.size.height = h;
    NSView *oview = [bigWindow overlayViewWithRect:frame];
    [oview addSubview:movieController];
    [movieController setFrame:NSMakeRect(0,0,w,h)];
}

- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
    return 1;
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
    NSDictionary *dict = [[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"];
    return [dict objectForKey:[aTableColumn identifier]];
}

- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"]];
    if (anObject)
        [dict setObject:anObject forKey:[aTableColumn identifier]];
    else
        [dict removeObjectForKey:[aTableColumn identifier]];
    [[NSUserDefaults standardUserDefaults] setObject:dict forKey:@"controlSpeeds"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (NSWindow *)fullscreenWindow
{
    return bigWindow;
}

- (IBAction)scrubberAction:(id)sender
{
    if (!currentMovie) return;
    float value = [scrubber floatValue];
    TimeRecord tr;
	NSMovie *movie = [playingMovieView movie];
	Movie q = [movie quickTimeMovie];
    GetMovieTime(q, &tr);
    TimeValue dur = GetMovieDuration(q);
    tr.value.lo = value * (double)dur;
    SetMovieTime(q, &tr);
	if (timescale) {
		[timeE setStringValue:[MHUtil nSecondsToShortString:(double)tr.value.lo / (double)timescale]];
		[timeR setStringValue:[MHUtil nSecondsToShortString:(double)(dur - tr.value.lo) / (double)timescale]];
	}
}

- (IBAction)langMenu:(id)sender
{
    if (![sender isKindOfClass:[NSEvent class]]) return;
    if (!currentMovie) return;
    NSMenu *menu = [[[NSMenu alloc] init] autorelease];
    //NSMutableArray *array = [NSMutableArray array];
    //Movie mov = [currentMovie QTMovie];
    int i, n = [currentMovie trackCount];
    NSMutableArray *langs = [NSMutableArray array], *sounds = [NSMutableArray array], *enabled = [NSMutableArray array];
    int tally = 0;
    for (i=0;i<n;i++) {
        MHTrack *track = [currentMovie trackAtIndex:i];
        NSString *language = [track language];
        if (NSNotFound == [langs indexOfObject:language])
            [langs addObject:language];
        if ([track isSoundType]) {
            tally++;
            NSString *name = [track name];
            if (!name)
                name = [NSString stringWithFormat:@"Sound Track %d", tally];
            [sounds addObject:name];
            if ([track enabled]) {
                [enabled addObject:name];
                [enabled addObject:language];
            }
        }
    }
    n = [langs count];
    if (n > 1) {
        for (i=0;i<n;i++) {
            NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
            [item setTitle:[langs objectAtIndex:i]];
            [item setTarget:self];
            [item setAction:@selector(setLanguage:)];
            if (NSNotFound != [enabled indexOfObject:[langs objectAtIndex:i]])
                [item setState:YES];
            [menu addItem:item];
       } 
    } else if (tally > 1) {
        n = [sounds count];
        for (i=0;i<n;i++) {
            NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
            [item setTitle:[sounds objectAtIndex:i]];
            [item setTarget:self];
            [item setAction:@selector(setSoundTrack:)];
            if (NSNotFound != [enabled indexOfObject:[sounds objectAtIndex:i]])
                [item setState:YES];
            [menu addItem:item];
        }
    }
    if (n > 1)
        [NSMenu popUpContextMenu:menu withEvent:sender forView:nil];
}

- (IBAction)chapMenu:(id)sender
{
    if (![sender isKindOfClass:[NSEvent class]]) return;
    if (!currentMovie) return;
    NSMenu *menu = [[[NSMenu alloc] init] autorelease];
    NSString *lang = nil;
    if ([[currentMovie chapters] multilingual]) lang = [currentMovie currentLanguage];
    NSArray *chaps = [[currentMovie chapters] chapterNamesForLanguage:lang];
    NSArray *times = [[currentMovie chapters] chapterTimesForLanguage:lang];
    NSMenuItem *curChap = nil;
	Movie q = [[playingMovieView movie] quickTimeMovie];
	TimeRecord tr;
	TimeValue tv = GetMovieTime(q, &tr);
    double currTime = (double)tv / (double)tr.scale;
    int i, n = [chaps count];
    for (i=0;i<n;i++) {
        NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
        NSString *title = [chaps objectAtIndex:i];
        [item setTitle:title];
        [item setTarget:self];
        [item setAction:@selector(gotoChapter:)];
        if (!curChap && (i == n-1 || [[times objectAtIndex:i+1] doubleValue] > currTime)) curChap = item;
        [menu addItem:item];
    }
    [curChap setState:YES];
    [NSMenu popUpContextMenu:menu withEvent:sender forView:nil];
}

- (IBAction)cycleText:(id)sender
{
    timeDisplayMode++;
    if (timeDisplayMode > 2) timeDisplayMode = 0;
    [self tick:self];
}

- (IBAction)setLanguage:(id)sender
{
    NSString *title = [sender title];
    long aLang = [tLanguages stringToNumber:title];
    SetMovieLanguage([currentMovie QTMovie], aLang);
    SelectMovieAlternates([currentMovie QTMovie]);
    [self setLangState];
    if ([[currentMovie chapters] multilingual]) {
        if ([movieView isControllerVisible]) {
            [movieView showController:NO adjustingSize:NO];
            [movieView showController:YES adjustingSize:NO];
        }
        [self setChapterTicks];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"movieLanguageChangedNotification" object:self];
}

- (IBAction)setSoundTrack:(id)sender
{
    int i, n = [currentMovie trackCount];
    int tally = 0;
    for (i=0;i<n;i++) {
        MHTrack *track = [currentMovie trackAtIndex:i];
        if ([track isSoundType]) {
            tally++;
            NSString *name = [track name];
            if (!name)
                name = [NSString stringWithFormat:@"Sound Track %d", tally];
            if ([name isEqualToString:[sender title]])
                [track setEnabled:YES];
            else
                [track setEnabled:NO];
        }
    }
    [self setLangState];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"movieLanguageChangedNotification" object:self];
}

- (IBAction)playMovies:(id)sender
{
    float curSpeed = [playingMovieView rate];
    if (![playingMovieView isPlaying] && ![[playingMovieView window] isVisible])
        [self movieDidChangeTo:[[controller getModel] currentPlayingMovie]];
    if (curSpeed > 1 && [playingMovieView isPlaying])
        [self jump:0 - curSpeed * [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"Snap Back"] floatValue]];
    if ([ffMute state]) {
        short vol = GetMovieVolume([currentMovie QTMovie]);
        if (vol < 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
    }
    [playingMovieView setMovie:currentMovie];
    [[playingMovieView window] makeKeyAndOrderFront:self];
    [self makeMovieGoNow:thisMovie];
    [self setPlaying:YES];
    NSRect rect = [viewWindow frame];
    rect.size.width /= 2;
    rect.size.height /= 4;
    rect.origin.x += rect.size.width / 2;
    rect.origin.y += 5;
    return;
    NSView *oview = [viewWindow overlayViewWithRect:rect];
    [oview addSubview:movieControls];
    rect.origin = NSMakePoint(0,0);
    [movieControls setFrame:rect];
}

- (IBAction)stopMovies:(id)sender
{
    [playingMovieView pause:self];
    if (playingMovieView == fullscreenMovieView)
	[bigWindow exitFullScreen];
    [self setPlaying:NO];
}

- (void)setPlaying:(BOOL)playing
{
    if (playing && [playButton action] != @selector(pause:)) {
	[playButton setImage:[NSImage imageNamed:@"pause"]];
	[(NSButton *)playButton setAction:@selector(pause:)];
	[playButton setToolTip:@"Pause"];
    } else if (!playing && [playButton action] != @selector(playMovies:)) {
	[playButton setImage:[NSImage imageNamed:@"play2"]];
	[(NSButton *)playButton setAction:@selector(playMovies:)];
	[playButton setToolTip:@"Play"];
    }
}

- (IBAction)pause:(id)sender
{
    [playingMovieView pause:nil];
    [self setPlaying:NO];
    [currentMovie setTimeIndex:[self getSampleTimeValue]];
}

+ (IBAction)toggleController:(id)sender
{
    [tPlayNibInstance toggleController:sender];
}

- (IBAction)toggleController:(id)sender
{
    if (![sender respondsToSelector:@selector(title)]) sender = controllerMenuItem;
    //[viewWindow makeKeyAndOrderFront:nil];
    NSString *title = [sender title];
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSRect r = [viewWindow frame];
    NSRect s = [movieView frame];
    if ([title hasPrefix:@"Show"]) {
        [movieView showController:YES adjustingSize:NO];
        [defs setBool:NO forKey:@"hideController"];
        [sender setTitle:@"Hide Movie Controller"];
        //NSLog(@"Show");
        s.size.width -= 10;
        [movieView setFrame:s];
        r.size.width += 10;
        r.size.height += 16;
        [viewWindow performClose:self];
        [viewWindow makeKeyAndOrderFront:self];
    } else if ([title hasPrefix:@"Hide"]) {
        [movieView showController:NO adjustingSize:NO];
        [defs setBool:YES forKey:@"hideController"];
        [sender setTitle:@"Show Movie Controller"];
        //NSLog(@"Hide");
        s.size.width += 10;
        [movieView setFrame:s];
        r.size.width -= 10;
        r.size.height -= 16;
    }
    [viewWindow setFrame:r display:YES];
    [defs synchronize];
}

- (void) setPMovieView:(id)newView
{
    if (newView)
        playingMovieView = newView;
}

- (IBAction)nextMovie:(id)sender
{
    [self makeMovieGoNow:nextMovie];
    [self setPlaying:YES];
}

+ (void)nextMovie
{
    [tPlayNibInstance nextMovie:nil];
}

- (IBAction)lastMovie:(id)sender
{
    [self makeMovieGoNow:lastMovie];
    [self setPlaying:YES];
}

+ (void)lastMovie
{
    [tPlayNibInstance lastMovie:nil];
}

- (IBAction)fullScreen:(id)sender
{
    if (nil == currentMovie) return;
    NSArray *screens = [NSScreen screens];
    NSScreen *aScreen;
    int index = [whichScreen indexOfSelectedItem] - 1;
    if (index == -1)
        aScreen = [viewWindow screen];
    else {
        if (index >= [screens count])
            index = 0;
        aScreen = [screens objectAtIndex:index];
    }
    
    NSRect screenRect = [aScreen frame];
    [bigWindow setFrame:screenRect display:NO];
    screenRect.origin = NSMakePoint(0,0);
    playingMovieView = fullscreenMovieView;
    [bigWindow setHidesOnDeactivate:[hides state]];
    
    [self setMovieFrameInFrame:screenRect];
    
    int level = NSScreenSaverWindowLevel;
    int levels[] = { NSNormalWindowLevel, NSFloatingWindowLevel, NSSubmenuWindowLevel, NSTornOffMenuWindowLevel, NSModalPanelWindowLevel, NSMainMenuWindowLevel, NSStatusWindowLevel, NSPopUpMenuWindowLevel, NSScreenSaverWindowLevel };
    int chosen = [fullscreenLevelPopup indexOfSelectedItem];
    level = levels[chosen];
    [bigWindow setLevel:level];
    [bigWindow setAcceptsMouseMovedEvents:YES];
    [bigWindow makeKeyAndOrderFront:nil];
    [NSCursor setHiddenUntilMouseMoves:YES];
    wasAutoSleep = !IsAutoSlpControlDisabled();
    if (wasAutoSleep)
	AutoSleepControl(NO);
    [self setPlaying:YES];
}

+ (void) fullScreen
{
    [tPlayNibInstance fullScreen:nil];
}

- (IBAction)inMainWindow:(id)sender
{
    [windowedMovieView showController:NO adjustingSize:NO];
    NSRect frame = [mainTabView frame];
    frame.size.height -= 20;
    frame.origin.y = 20;
    [self setMovieFrameInFrame:frame];
    [controller setMainTabViewName:@"Movie"];
    [[controller mainWindow] makeKeyAndOrderFront:nil];
}

- (void) setMovieFrameInFrame:(NSRect)outerFrame
{
    double multiplier, newRatio, outerRatio = outerFrame.size.width / outerFrame.size.height;
    int w = [[currentMovie objectForKey:@"Original Width"] intValue];
    int h = [[currentMovie objectForKey:@"Original Height"] intValue];
    if ([playingMovieView isControllerVisible])
        h += 16;
    NSString *aspect = [fsAspect stringValue];
    NSRect movieRect;
    if ([aspect isEqualToString:@"fill"]) {
        movieRect.origin.x = movieRect.origin.y = 0;
        movieRect.size = outerFrame.size;
    } else {
        if ([aspect isEqualToString:@"native"] || [aspect doubleValue] == 0)
            newRatio = (double)w / (double)h;
        else
            newRatio = (double)w * [aspect doubleValue] / (double)h;
        w = h * newRatio;
        BOOL isWide = newRatio > outerRatio;
        if ([overscan state]) isWide = !isWide;
        if (isWide) {
            multiplier = outerFrame.size.width / w;
            movieRect.origin.x = outerFrame.origin.x;
            movieRect.origin.y = outerFrame.origin.y + (outerFrame.size.height - h * multiplier) / 2;
        } else {
            multiplier = outerFrame.size.height / h;
            movieRect.origin.x = outerFrame.origin.x + (outerFrame.size.width - w * multiplier) / 2;
            movieRect.origin.y = outerFrame.origin.y;
        }
        movieRect.size.width = w * multiplier;
        movieRect.size.height = h * multiplier;
    }
    
    [playingMovieView setFrame:movieRect];
    
    [[playingMovieView superview] setNeedsDisplay:YES];
    
    if (playingMovieView != movieView)
        [movieView setMovie:nil];
    [playingMovieView setMovie:nil];
    
    [playingMovieView setMovie:currentMovie];
}

- (IBAction)refreshMonitors:(id)sender
{
    NSRect screenFrame;
    NSArray *screens = [NSScreen screens];
    [whichScreen removeAllItems];
    int i, n = [screens count];
    [whichScreen addItemWithTitle:@"Current"];
    for (i=0;i<n;i++) {
        screenFrame = [[screens objectAtIndex:i] frame];
        [whichScreen addItemWithTitle:[NSString stringWithFormat:@"%g x %g", screenFrame.size.width, screenFrame.size.height]];
    }
    int monitorChoice = [[NSUserDefaults standardUserDefaults] integerForKey:@"whichScreen"];
    if (monitorChoice < 0 || monitorChoice >= [whichScreen numberOfItems])
	monitorChoice = 0;
    [whichScreen selectItemAtIndex:monitorChoice];
}

- (IBAction)pickMonitor:(id)sender
{
    int selection = [whichScreen indexOfSelectedItem];
    [[NSUserDefaults standardUserDefaults] setInteger:selection forKey:@"whichScreen"];
}

- (BOOL)playOnExitFullScreen
{
    return [exitPlay state];
}

- (IBAction)setRate:(id)sender
{
    NSMenu *menu = [sender menu];
    int i, n = [menu numberOfItems];
    for (i=0;i<n;i++) {
        NSMenuItem *item = [menu itemAtIndex:i];
        if (item == sender) {
            [item setState:YES];
            NSString *title = [sender title];
            if ([title hasSuffix:@"x"])
                title = [title substringToIndex:[title length]-1];
            NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
            NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[defs objectForKey:@"controlSpeeds"]];
            [dict setObject:title forKey:@"FF Speed"];
            [dict setObject:title forKey:@"RW Speed"];
            [defs setObject:dict forKey:@"controlSpeeds"];
            [defs synchronize];
        } else
            [item setState:NO];
    }
}

- (IBAction)halfSize:(id)sender
{
    [self setViewSize:0.5];
    [self setSizeMenuStates:sender];
    playingMovieView = movieView;
}

- (IBAction)origSize:(id)sender
{
    [self setViewSize:1.0];
    [self setSizeMenuStates:sender];
    playingMovieView = movieView;
}

- (IBAction)doubleSize:(id)sender
{
    [self setViewSize:2.0];
    [self setSizeMenuStates:sender];
    playingMovieView = movieView;
}

- (IBAction)fullscreenSize:(id)sender
{
    
    [self setSizeMenuStates:sender];
    playingMovieView = fullscreenMovieView;
}

- (IBAction)inMainWindowSize:(id)sender
{
    
    [self setSizeMenuStates:sender];
    playingMovieView = windowedMovieView;
}

- (void) setSizeMenuStates:(id)sender
{
    if (!sender) return;
    int i;
    id item;
    for (i=0;i<[sizeMenu numberOfItems];i++) {
        item = [sizeMenu itemAtIndex:i];
        if (item == sender) {
            [item setState:YES];
            [[NSUserDefaults standardUserDefaults] setInteger:i forKey:t_whichSize];
            [[NSUserDefaults standardUserDefaults] synchronize];
        } else
            [item setState:NO];
    }
}

- (IBAction)maxVolume:(id)sender
{
    NSMovie *movie = [playingMovieView movie];
	if (![movie isKindOfClass:[NSMovie class]])
		movie = [movie delegate];
    if (movie)
        SetMovieVolume([movie QTMovie], 256);
    [volScroll setDoubleValue:256];
}

- (IBAction)minVolume:(id)sender
{
    NSMovie *movie = [playingMovieView movie];
    if (movie)
        SetMovieVolume([movie QTMovie], 0);
    [volScroll setDoubleValue:0];
}

+ (IBAction)refreshVolume:(id)sender
{   [tPlayNibInstance refreshVolume:sender];    }

- (IBAction)refreshVolume:(id)sender
{
    short vol = GetMovieVolume([currentMovie QTMovie]);
    [volScroll setDoubleValue:vol];
}

- (IBAction)setVolume:(id)sender
{
    if ([sender respondsToSelector:@selector(doubleValue)]) {
        double input = [sender doubleValue];
        if (currentMovie)
            SetMovieVolume([currentMovie QTMovie], (short)input);
    }
}

- (IBAction)bigger:(id)sender
{
    if (nil == currentMovie) return;
    NSRect aRect = [movieView movieRect];
    int width = aRect.size.width;
    int height = aRect.size.height;
    if ([movieView isControllerVisible]) height -= 16;
    int origWidth = [[currentMovie objectForKey:@"Original Width"] intValue];
    int origHeight = [[currentMovie objectForKey:@"Original Height"] intValue];
    [self setViewWidth:width+origWidth height:height+origHeight];
}

- (IBAction)smaller:(id)sender
{
    if (nil == currentMovie) return;
    NSRect aRect = [movieView movieRect];
    int width = aRect.size.width;
    int height = aRect.size.height;
    if ([movieView isControllerVisible]) height -= 16;
    int origWidth = [[currentMovie objectForKey:@"Original Width"] intValue];
    int origHeight = [[currentMovie objectForKey:@"Original Height"] intValue];
    [self setViewWidth:width-origWidth height:height-origHeight];
}

// sets the view window to "size" times the movie's preferred size.
- (void)setViewSize:(double)size
{
    //NSSize aSize;
    int width, height;
    
    width = (double)[[currentMovie objectForKey:@"Original Width"] intValue] * size;
    height = (double)[[currentMovie objectForKey:@"Original Height"] intValue] * size;
    [self setViewWidth:width height:height];
    
}

- (void)setViewWidth:(int)w height:(int)h
{
    NSSize aSize;
	NSPoint p = [viewWindow frame].origin;
    aSize.width = w;
    aSize.height = h;
    if (aSize.width < 16) aSize.width = 174;
    if (aSize.height < 16) aSize.height = 16;
    if ([movieView isControllerVisible]) {
        aSize.width += 10;
        aSize.height += 16;
    }
	NSRect sFrame = [[viewWindow screen] frame];
	if ([viewWindow screen] == [[NSScreen screens] objectAtIndex:0]) sFrame.size.height -= 22;
	NSSize sSize = sFrame.size;
	if (aSize.width > sSize.width) aSize.width = sSize.width;
	if (aSize.height > sSize.height) aSize.height = sSize.height;
	if (p.x + aSize.width > sSize.width + sFrame.origin.x) p.x = sSize.width - aSize.width + sFrame.origin.x;
	if (p.y + aSize.height > sSize.height + sFrame.origin.y) p.y = sSize.height - aSize.height + sFrame.origin.y;
	[viewWindow setFrameOrigin:p];
    [viewWindow setContentSize:aSize];
}

- (double)getTimeValue
{
    MHMovie *movie = (MHMovie *)[playingMovieView movie];
	if (![movie isKindOfClass:[NSMovie class]])
		movie = [movie delegate];
    if (nil == movie) return 0;
    return [movie currentTimeIndexSeconds];
}

- (long)getSampleTimeValue
{
    MHMovie *movie = (MHMovie *)[playingMovieView movie];
	if (![movie isKindOfClass:[NSMovie class]])
		movie = [movie delegate];
    if (nil == movie) return 0;
    return [movie currentTimeIndex];
}

- (IBAction)savePrefs:(id)sender
{
    //NSLog(@"playback");
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    [defs setBool:[overscan state] forKey:@"overscan"];
    [defs setBool:[ffMute state] forKey:@"ffMute"];
    [defs setInteger:[fullscreenLevelPopup indexOfSelectedItem] forKey:@"fullscreenLevel"];
    [defs synchronize];
}

- (IBAction)chapScroll:(id)sender
{
    int selected = [chapScroll indexOfSelectedItem];
    [[NSUserDefaults standardUserDefaults] setInteger:selected forKey:@"chapScroll"];
    //if (0 == selected) [menuChap startScrolling];
    //else [menuChap stopScrolling];
    if (1 == selected)
        [menuChap setTitle:@"Chapters"];
    else [self tick:nil];
}

- (void)awakeFromNib
{
    //[viewWindow setAlphaValue:0.5];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(flagsChanged:) name:@"flagsChangedNotification" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyDown:) name:@"keyDownNotification" object:nil];
    //[[NSNotificationCenter defaultCenter] addObserver:controller selector:@selector(windowDidBecomeMain:) name:@"NSWindowDidBecomeMainNotification" object:nil];
    //[[NSNotificationCenter defaultCenter] addObserver:controller selector:@selector(windowDidResignMain:) name:@"NSWindowDidResignMainNotification" object:nil];
    timeE = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 14, 38, 12)];
    [iLeft addSubview:timeE];
    [timeE setEditable:NO];
    [timeE setDrawsBackground:NO];
    [timeE setBezeled:NO];
    [timeE setAlignment:NSRightTextAlignment];
    [timeE setStringValue:@""];
    [[timeE cell] setFont:[NSFont labelFontOfSize:9]];
    [[timeE cell] setWraps:NO];
    
    timeR = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 14, 38, 12)];
    [iRight addSubview:timeR];
    [timeR setEditable:NO];
    [timeR setDrawsBackground:NO];
    [timeR setBezeled:NO];
    [timeR setStringValue:@""];
    [[timeR cell] setFont:[NSFont labelFontOfSize:9]];
    [[timeR cell] setWraps:NO];
    
    tPlayNibInstance = self;
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSNumber *num = [defs objectForKey:t_whichSize];
    if (!num)
        num = [NSNumber numberWithInt:1];
    [ffMute setState:[defs boolForKey:@"ffMute"]];
    [overscan setState:[defs boolForKey:@"overscan"]];
    NSNumber *level = [defs objectForKey:@"fullscreenLevel"];
    if (!level) level = [NSNumber numberWithInt:8];
    [fullscreenLevelPopup selectItemAtIndex:[level intValue]];
    int preference = [defs integerForKey:@"chapScroll"];
    if (preference >= [chapScroll numberOfItems]) preference = [chapScroll numberOfItems]-1;
    [chapScroll selectItemAtIndex:preference];
    //if (!preference) [menuChap startScrolling];
    //else
    if (preference == 1) [menuChap setTitle:@"Chapters"];
    int i;
    for (i=0;i<[sizeMenu numberOfItems];i++)
        [[sizeMenu itemAtIndex:i] setState:i==[num intValue]];
    if ([num intValue] == 3)
        playingMovieView = fullscreenMovieView;
    else if ([num intValue] == 4)
        playingMovieView = windowedMovieView;
    else playingMovieView = movieView;
    [exit selectItemAtIndex:[defs integerForKey:@"whichExit"]];
    if ([defs boolForKey:@"hideController"]) {
        //[viewWindow makeKeyAndOrderFront:nil];
        //[viewWindow orderOut:nil];
        [self performSelector:@selector(toggleController:) withObject:controllerMenuItem afterDelay:0];
    }
    
    bigWindow = [[tWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO screen:[NSScreen mainScreen]];
    
    //[bigWindow setAcceptsMouseMovedEvents:YES];
    //[bigWindow setLevel:CGShieldingWindowLevel()];
    [bigWindow setBackgroundColor:[NSColor blackColor]];
    [bigWindow setContentView:fullscreenContentView];
    [bigWindow setHidesOnDeactivate:[hides state]];
    currentMovie = nil;
    wasAutoSleep = NO;
    currentTitle = @"";
    timeDisplayMode = 0;
    timescale = 0;
    oldSpeed = 0;
    [fullscreenMovieView showController:NO adjustingSize:NO];
    [self performSelector:@selector(maxVolume:) withObject:nil afterDelay:0];
    [self performSelector:@selector(movieDidChangeTo:) withObject:controller afterDelay:0];
    
    //[movieView setPlayer:self];
    [movieView setEditable:NO];
    
    [self refreshMonitors:nil];
}

- (IBAction)setWhichExit:(id)sender
{
    [[NSUserDefaults standardUserDefaults] setInteger:[exit indexOfSelectedItem] forKey:@"whichExit"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)shouldExitFullScreen
{
    if (CGDisplayRelease( kCGDirectMainDisplay ) != kCGErrorSuccess)
        NSLog( @"Couldn't release the display!");
    [[bigWindow contentView] retain];
    [bigWindow orderOut:nil];
    [playingMovieView pause:self];
    [bigWindow setAcceptsMouseMovedEvents:NO];
    [self setPlaying:NO];
    if (wasAutoSleep)
	AutoSleepControl(YES);
    //playingMovieView = movieView;
}

+ (void)shouldExitFullScreen
{
    [tPlayNibInstance shouldExitFullScreen];
}

- (MHMovie *)currentMovie
{
    return currentMovie;
}

void setTimeIndex(MHMovie *theMovie, double timeIndex) {
    [theMovie setCurrentTimeIndex:timeIndex];
}

- (void)movieDidChangeTo:(MHMovie *)aMovie
{
    //NSLog(@"tPlayback movieDidChangeTo %@", aMovie);
    if (aMovie && ![aMovie isKindOfClass:[MHMovie class]]) aMovie = [(tController *)aMovie currentMovie];
    currentMovie = aMovie;
    [scrubName setStringValue:@""];
    [timeE setStringValue:@""];
    [timeR setStringValue:@""];
    [scrubber setMarkers:nil];
    [self setLangState];
    if (nil != aMovie) {
        [currentTitle release];
        currentTitle = [[aMovie stringValue] retain];
        [scrubName setStringValue:currentTitle];
        timescale = GetMovieTimeScale([aMovie QTMovie]);
    } else {
        currentTitle = @"";
        timescale = 0;
		[playingMovieView stop:self];
		[viewWindow orderOut:self];
        [movieView setMovie:nil];
        [fullscreenMovieView setMovie:nil];
        [windowedMovieView setMovie:nil];
    }
    [self setChapterTicks];
    //NSLog(@"superview: %@", [[playingMovieView superview] className]);
    if ([[playingMovieView window] isVisible] || (playingMovieView == windowedMovieView && ![[[mainTabView selectedTabViewItem] identifier] isEqualToString:@"Movie"]))
        [playingMovieView setMovie:aMovie];
    else
        [playingMovieView setMovie:nil];
    [self setPlaying:NO];
    if (aMovie) {
        //short vol = GetMovieVolume([aMovie QTMovie]);
        //[volScroll setDoubleValue:vol];
        SetMovieVolume([aMovie QTMovie], (short)[volScroll doubleValue]);
    }
    TimeRecord tr;
    [scrubber setFloatValue:(float)GetMovieTime([currentMovie QTMovie], &tr) / (float)GetMovieDuration([currentMovie QTMovie])];
    
    int row = [[controller getModel] indexForMovie:currentMovie];
    [[controller getModel] setCurrentPlayingIndex:row];
    //[[[theTable tableColumnWithIdentifier:@"Order"] dataCell] setImageRow:row];
    [theTable setNeedsDisplay:YES];
    [self performSelector:@selector(tick:) withObject:self afterDelay:0];
}

- (void)setChapterTicks
{
    NSMutableArray *markers = [NSMutableArray array];
    NSString *lang = nil;
    if ([[currentMovie chapters] multilingual]) lang = [currentMovie currentLanguage];
    NSArray *times = [[currentMovie chapters] chapterTimesForLanguage:lang];
    [menuChap setTransparent:![times count]];
    double total = [[currentMovie objectForKey:@"Seconds"] doubleValue];
    int i, n = [times count];
    for (i=0;i<n;i++) {
        double time = [[times objectAtIndex:i] doubleValue] / total;
        [markers addObject:[NSNumber numberWithDouble:time]];
    }
    [scrubber setMarkers:markers];
}

- (void)setLangState
{
    if ([self numLangs:currentMovie] < 2) {
        [menuLang setImage:nil];
        //[menuLang setTransparent:YES];
        //[menuLang setEnabled:NO];
        NSString *title = [currentMovie stringValue];
        if (!title) title = @"";
        [menuLang setTitle:title];
    } else {
        [menuLang setImage:[NSImage imageNamed:@"menuArrow"]];
        //[menuLang setTransparent:NO];
        //[menuLang setEnabled:YES];
        int i, n = [currentMovie trackCount];
        for (i=0;i<n;i++) {
            MHTrack *track = [currentMovie trackAtIndex:i];
            if ([track isSoundType] && [track enabled]) {
                NSString *lang = [track language];
                NSString *title = [currentMovie objectForKey:@"Full Name" language:lang];
                if (!title)
                    title = [currentMovie stringValue];
                if (!title) title = @"";
                lang = [tLanguages abbrev:lang];
                if (lang)
                    title = [title stringByAppendingFormat:@" (%@)", lang];
                    /*
                    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSFont systemFontOfSize:10], NSFontAttributeName, nil];
                                //[NSColor colorWithCalibratedRed:0.418 green:0.426 blue:0.371 alpha:1],
                                    //NSBackgroundColorAttributeName,
                                //[NSColor colorWithCalibratedRed:0.836 green:0.855 blue:0.746 alpha:1],
                                    //NSForegroundColorAttributeName, nil];
                    NSAttributedString *title = [[NSAttributedString alloc] initWithString:lang attributes:attributes];
                    [menuLang setAttributedTitle:title];
                    */
                [menuLang setTitle:title];
                break;
            }
        }
    }
}

- (int)numLangs:(MHMovie *)aMovie
{
    int tally = 0;
    int i, n = [aMovie trackCount];
    for (i=0;i<n;i++)
        if ([[aMovie trackAtIndex:i] isSoundType])
            tally++;
    return tally;
}

- (void) makeMovieGoNow:(movieOrderT)whichMovie
{
    int index, nRows;
    double timeValue; // = [whichSize indexOfSelectedItem];
    MHMovie *theMovie = nil;
    tPlaylist *model = [theTable dataSource];
    
    timeValue = [self getSampleTimeValue];
    nRows = [theTable numberOfRows];
    if (nRows == 0) return;
    
    theMovie = (MHMovie *)[playingMovieView movie];
	if (![theMovie isKindOfClass:[NSMovie class]])
		theMovie = [theMovie delegate];
    if (theMovie) index = [model indexForMovie:theMovie];
    else index = [theTable selectedRow];
    if (theMovie != nil) {
        [theMovie saveCurrentHeight];
        if (timeValue < GetMovieDuration([theMovie QTMovie]) - GetMovieTimeScale([theMovie QTMovie]))
            [theMovie setTimeIndex:timeValue];
        else
            [theMovie setTimeIndex:0];
    }
    switch (whichMovie) {
        case thisMovie: if (index < 0) index = 0;
                        break;
        case nextMovie:	index++;
                        break;
        case lastMovie: index--;
                        break;
        default: break;
    }
    if (index < 0) index = nRows - 1;
    if (index >= nRows) index = 0;
    theMovie = [model movieForIndex:index];
    
    // Set the place in the movie
    timeValue = [[theMovie objectForKey:@"Seconds Elapsed"] doubleValue] * GetMovieTimeScale([theMovie QTMovie]);
    if ((int)timeValue != 0) setTimeIndex(theMovie, timeValue);
    
    // Keep the selection right
    //[model tableView:theTable shouldSelectRow:index];
    //[theTable selectRow:index byExtendingSelection:NO];
    //[theTable scrollRowToVisible:index];
    
    // Chapter Skipping
    if ([tInit boolForKey:@"skip"]) {
        MHChapters *ch = [theMovie chapters];
        int i;
        if (nil != ch) {
            NSString *string = [tInit stringForKey:@"skipText"];
            if (nil != string && ![string isEqualToString:@""]) {
                for (i=0;i<2;i++)
                    skips[i] = [ch rangeOfChapterContainingString:string index:i];
            }
        }
    }
    
    
    [self movieDidChangeTo:theMovie];
    
    [playingMovieView setMovie:theMovie];
    
    // Play the movie
    if ([toSize state]) {
        int i;
        for (i=0;i<[sizeMenu numberOfItems];i++)
            if ([[sizeMenu itemAtIndex:i] state])
                break;
        switch (i) {
            case 0: [self setViewSize:0.5]; break;
            case 1: case 2: [self setViewSize:i]; break;
            default: break;
        }
        switch (i) {
            case 0: case 1: case 2: [viewWindow setTitle:currentTitle];
                if (![viewWindow isVisible])
                    [viewWindow makeKeyAndOrderFront:nil];
                break;
            case 3:  [self fullScreen:nil]; break;
            case 4:  [self inMainWindow:nil]; break;
            default: break;
        }
    }
    
    SetMovieVolume([theMovie QTMovie], (short)[volScroll doubleValue]);
    
    [playingMovieView setRate:1.0];
    
    [playingMovieView play:self];
    
    [iconDrawer close];
}

- (IBAction) slomo:(id)sender
{
    float speed = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"SloMo Speed"] floatValue];
    if (!speed) speed = .3;
    if (speed < 0) speed = 0 - speed;
    [playingMovieView play:nil];
    [playingMovieView setRate:speed];
}

- (IBAction) ff:(id)sender
{
    //float curSpeed = [playingMovieView rate];
    //[playingMovieView start:nil];
    float speed = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"FF Speed"] floatValue];
    if (!speed) speed = 2;
    if (speed < 0) speed = 0 - speed;
    if ([sender respondsToSelector:@selector(isDepressed)] && ![sender isDepressed]) {
            speed = oldSpeed;
            [self jump:0 - [playingMovieView rate] * [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"Snap Back"] floatValue]];
            if ([ffMute state]) {
                short vol = GetMovieVolume([currentMovie QTMovie]);
                if (vol < 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
            }
    } else {
        oldSpeed = [playingMovieView rate];
        if (![playingMovieView isPlaying])
            oldSpeed = 0;
        if ([ffMute state]) {
            short vol = GetMovieVolume([currentMovie QTMovie]);
            if (vol > 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
        }
    }
    if (0 == speed) {
        [playingMovieView pause:nil];
        [self setPlaying:NO];
    } else {
        [playingMovieView play:nil];
        [playingMovieView setRate:speed];
        [self setPlaying:YES];
    }
}

- (IBAction) fff:(id)sender
{
    float speed = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"FF Speed"] floatValue];
    if (!speed) speed = 2;
    if (speed < 0) speed = 0 - speed;
    if ([playingMovieView rate] >= speed) speed = [playingMovieView rate] * 2;
    if ([ffMute state]) {
        short vol = GetMovieVolume([currentMovie QTMovie]);
        if (vol > 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
    }
    [playingMovieView play:nil];
    [playingMovieView setRate:speed];
    [self setPlaying:NO];
}

- (IBAction) rw:(id)sender
{
    float speed = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"RW Speed"] floatValue];
    if (!speed) speed = 2;
    if (speed > 0) speed = 0-speed;
    if ([sender respondsToSelector:@selector(isDepressed)] && ![sender isDepressed]) {
            speed = oldSpeed;
            if ([ffMute state]) {
                short vol = GetMovieVolume([currentMovie QTMovie]);
                if (vol < 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
            }
    } else {
        oldSpeed = [playingMovieView rate];
        if (![playingMovieView isPlaying])
            oldSpeed = 0;
        if ([ffMute state]) {
            short vol = GetMovieVolume([currentMovie QTMovie]);
            if (vol > 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
        }
    }
    if (0 == speed) {
        [playingMovieView pause:nil];
        [self setPlaying:NO];
    } else {
        [playingMovieView play:nil];
        [playingMovieView setRate:speed];
        [self setPlaying:YES];
    }
}

- (IBAction) rrw:(id)sender
{
    float speed = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"RW Speed"] floatValue];
    if (!speed) speed = 2;
    if (speed > 0) speed = 0 - speed;
    if ([playingMovieView rate] <= speed) speed = [playingMovieView rate] * 2;
    if ([ffMute state]) {
        short vol = GetMovieVolume([currentMovie QTMovie]);
        if (vol > 0) SetMovieVolume([currentMovie QTMovie], 0 - vol);
    }
    [playingMovieView play:nil];
    [playingMovieView setRate:speed];
    [self setPlaying:NO];
}

- (IBAction) jumpF:(id)sender
{
    float jumpBy = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"Forward Jump"] floatValue];
    if (jumpBy < 0) jumpBy = 0 - jumpBy;
    [self jump:jumpBy];
}

- (IBAction) jumpB:(id)sender
{
    float jumpBy = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"controlSpeeds"] objectForKey:@"Reverse Jump"] floatValue];
    if (jumpBy > 0) jumpBy = 0 - jumpBy;
    [self jump:jumpBy];
}

- (IBAction)jumpToSheet: (id)sender
{
	if ( [viewWindow isKeyWindow] == NO)
	{
		[viewWindow makeKeyAndOrderFront:sender];
	}

	//else [[controller getPlayer] playMovies:self]
	[jumpToText setStringValue: [MHUtil nSecondsToString:[self getTimeValue]]];
	[NSApp beginSheet: jumpSheet
	modalForWindow: viewWindow
		modalDelegate: nil
	didEndSelector: nil
			contextInfo: nil];
}

- (IBAction)endJumpToSheet: (id)sender
{
    [jumpSheet orderOut: NULL];
    [NSApp endSheet: jumpSheet];
}

- (IBAction)jumpTo: (id)sender
{
    NSString *input = [jumpToText stringValue];
    double seconds = [(tController *)controller stringToNSeconds:input];
    //if (seconds == 0 ) return;
    
    MHMovie *theMovie = (MHMovie *)[movieView movie];
	if (![theMovie isKindOfClass:[NSMovie class]])
		theMovie = [theMovie delegate];
    if (nil == theMovie || ![theMovie isKindOfClass:[MHMovie class]]) return;
    [theMovie setCurrentTimeIndexSeconds:seconds];
	/*
	selectText is only useful if you keep the JumpSheet active
	[jumpToText selectText:sender];
	 */
    [jumpToText setStringValue: [MHUtil nSecondsToString: seconds]];
    [self endJumpToSheet: sender];
    [self tick:self];
}

- (void) jump:(double)seconds
{
    MHMovie *theMovie = (MHMovie *)[playingMovieView movie];
	//if (![theMovie isKindOfClass:[NSMovie class]])
	//	theMovie = [theMovie delegate];
    Movie qtMovie = nil;
	if ([theMovie respondsToSelector:@selector(quickTimeMovie)])
		qtMovie = [theMovie quickTimeMovie];
	if (!qtMovie) return;
    TimeRecord tr;
    TimeValue tv;
    
    tv = GetMovieTime(qtMovie, &tr);
    tr.value.lo += seconds * (double)tr.scale;
    if (tr.value.lo < 0) tr.value.lo = 0;
    SetMovieTime(qtMovie, &tr);
    [self tick:self];
}

- (IBAction)gotoChapter:(id)sender
{
    if ([sender respondsToSelector:@selector(menu)]) {
        NSMenu *menu = [sender menu];
        int index = [menu indexOfItem:sender];
        NSString *lang = nil;
        if ([[currentMovie chapters] multilingual]) lang = [currentMovie currentLanguage];
        double time = [[currentMovie chapters] timeForChapterAtIndex:index language:lang];
        if (time >= 0) {
            TimeRecord tr;
			Movie q = [[playingMovieView movie] quickTimeMovie];
			TimeValue tv = GetMovieTime (q, &tr);
			tr.value.lo = time * (double)tr.scale;
			SetMovieTime(q, &tr);
            [scrubber setFloatValue:(float)GetMovieTime(q, &tr) / (float)GetMovieDuration(q)];
        }
        //NSLog(@"%@", title);
    } else NSLog(@"gotoChapter: sender is does not respond to -menu!");
}

- (void)tick:(id)info
{
	NSMovie *movie = [playingMovieView movie];
	
	Movie q = nil;
	if ([movie isKindOfClass:[NSMovie class]]) q = [movie QTMovie];
	else q = [movie quickTimeMovie];
	double seconds = 0;
	if (timescale) {
		TimeRecord tr;
		TimeValue elapsed = GetMovieTime(q, &tr);
		TimeValue dur = GetMovieDuration(q);
		TimeValue remaining = dur - elapsed;
		seconds = (double)elapsed / (double)timescale;
		[scrubber setFloatValue:(double)elapsed / (double)dur];
		NSString *timeStringE = [MHUtil nSecondsToShortString:seconds];
		NSString *timeStringR = [MHUtil nSecondsToShortString:remaining / timescale];
		[viewWindow setTitle:[NSString stringWithFormat:@"%@ - %@", currentTitle, timeStringE]];
		[timeE setStringValue:timeStringE];
		[timeR setStringValue:timeStringR];
	}
	
	if (![movie isKindOfClass:[NSMovie class]])
		movie = [movie delegate];
    if ([playOn state] && IsMovieDone([movie QTMovie]))
            [self makeMovieGoNow:nextMovie];
    if (nil == currentMovie && !info) return;
    unsigned int flags = [[NSApp currentEvent] modifierFlags];
    if (!(flags & NSAlternateKeyMask)) {
        if ([playingMovieView rate] == 1 && [playingMovieView isPlaying]) [self setPlaying:YES];
        else [self setPlaying:NO];
    }
    if (![playingMovieView isPlaying] && !info) return;
    if (!currentMovie) return;
    if ([tInit boolForKey:@"skip"]) {
        long time = [self getSampleTimeValue];
        int i;
        NSRange aRange;
        for (i=0;i<2;i++) {
            aRange = skips[i];
            if (aRange.length == 'end')
                aRange.length = GetMovieDuration([currentMovie QTMovie]) - aRange.location;
            if (time > aRange.location && time < aRange.location + aRange.length) {
                [currentMovie setCurrentTimeIndex:aRange.location + aRange.length];
                break;
            }
        }
    }
    
    if ([chapScroll indexOfSelectedItem] < 1) {
        NSString *language = nil;
        if ([[currentMovie chapters] multilingual]) language = [currentMovie currentLanguage];
        NSString *chapName = [[currentMovie chapters] nameForTime:seconds language:language];
        if (!chapName) chapName = @"Chapters";
        [menuChap setTitle:[chapName whitespaceTrimmed]];
    }
    [self refreshVolume:nil];
}

- (int)whichExit
{
    return [exit indexOfSelectedItem];
}

+ (int)whichExit
{
    return [tPlayNibInstance whichExit];
}

- (void)shouldFreeMovie:(MHMovie *)aMovie
{
    if (aMovie == currentMovie || aMovie == nil)
        currentMovie = nil;
}

@end
