//
//  XspfQTPlayer.m
//  XspfQT
//
//  Created by Hori,Masaki on 2013/06/21.
//  Copyright (c) 2013年 masakih. All rights reserved.
//

#import "XspfQTPlayer.h"

#import <QTKit/QTKit.h>

#import "HMXSPFComponent.h"
#import "NSURL-HMExtensions.h"
#import "XspfQTMovieLoader.h"
#import "XspfQTMovieTimer.h"
#import "XspfQTPreference.h"




static NSString *XspfQTCurrentTrackKey = @"currentTrack";


@interface XspfQTPlayer ()

@property (retain) XspfQTMovieLoader *loader;
@property BOOL didPreloading;

@end

@implementation XspfQTPlayer
@synthesize loader = _loader;
@synthesize didPreloading = _didPreloading;


static XspfQTMovieTimer* timer = nil;
+ (void)initialize
{
	static BOOL isFirst = YES;
	if(isFirst) {
		isFirst = NO;
		timer = [[XspfQTMovieTimer movieTimerWithFireInterval:0.5] retain];
	}
}

- (id)init
{
	self = [super init];
	if(self) {
		_loader = [[XspfQTMovieLoader loaderWithMovieURL:nil] retain];
		[timer put:self];
	}
	
	return self;
}

- (void)dealloc
{
	[_loader release];
	[timer remove:self];
	
	[[_playlist childAtIndex:0] removeObserver:self forKeyPath:XspfQTCurrentTrackKey];
	[_playlist release];
	
	NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
	[nc removeObserver:self];
	[_playingMovie release];
	
	[super dealloc];
}

- (void)setPlaylist:(HMXSPFComponent *)newList
{
	if(_playlist == newList) return;
	
	[[_playlist childAtIndex:0] removeObserver:self forKeyPath:XspfQTCurrentTrackKey];
	[_playlist autorelease];
	_playlist = [newList retain];
	[[_playlist childAtIndex:0] addObserver:self
								 forKeyPath:XspfQTCurrentTrackKey
									options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
									context:NULL];
	
	if(!newList) {
		[timer remove:self];
	}
}
- (HMXSPFComponent *)playlist
{
	return _playlist;
}

- (HMXSPFComponent *)trackList
{
	return [self.playlist childAtIndex:0];
}

+ (NSSet *)keyPathsForValuesAffectingPlayingMovieDuration
{
	return [NSSet setWithObject:@"playingMovie"];
}
- (void)setPlayingMovie:(QTMovie *)newMovie
{
	NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
	if(_playingMovie) {
		[nc removeObserver:self
					  name:nil
					object:_playingMovie];
	}
	
	[_playingMovie autorelease];
	_playingMovie = [newMovie retain];
	self.playingMovieDuration = 0;
	
	if(_playingMovie) {
		[nc addObserver:self
			   selector:@selector(notifee:)
				   name:QTMovieRateDidChangeNotification
				 object:_playingMovie];
	}
}
- (QTMovie *)playingMovie
{
	return _playingMovie;
}
- (void)setPlayingMovieDuration:(NSTimeInterval)playingMovieDuration
{
	_playingMovieDuration = playingMovieDuration;
}
- (NSTimeInterval)playingMovieDuration
{
	if(_playingMovieDuration == 0) {
		QTTime qttime = [self.playingMovie duration];
		if(!QTGetTimeInterval(qttime, &_playingMovieDuration)) _playingMovieDuration = 0;
	}
	
	return _playingMovieDuration;
}
- (void)loadMovie
{
	NSURL *location = self.trackList.movieLocation;
	
	if(self.playingMovie) {
		id movieURL = [self.playingMovie attributeForKey:QTMovieURLAttribute];
		if([location isEqualUsingLocalhost:movieURL]) return;
	}
	
	self.loader.movieURL = location;
	[self.loader load];
	QTMovie *newMovie = self.loader.qtMovie;
	self.playingMovie = newMovie;
	
	QTTime qttime = [newMovie duration];
	id t = [NSValueTransformer valueTransformerForName:@"XspfQTTimeDateTransformer"];
	[self.trackList setCurrentTrackDuration:[t transformedValue:[NSValue valueWithQTTime:qttime]]];
	
	self.didPreloading = NO;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
					  ofObject:(id)object
						change:(NSDictionary *)change
					   context:(void *)context
{
	if([keyPath isEqualToString:XspfQTCurrentTrackKey]) {
		[self loadMovie];
	}
}


- (void)notifee:(id)notification
{
	HMXSPFComponent *track = self.trackList.currentTrack;
	NSNumber *rateValue = [[notification userInfo] objectForKey:QTMovieRateDidChangeNotificationParameter];
	if(rateValue) {
		float rate = [rateValue floatValue];
		if(rate == 0) {
			track.isPlayed = NO;
			[timer suspend:self];
		} else {
			track.isPlayed = YES;
			[timer resume:self];
		}
	}
}

// call from XspfQTMovieTimer.
- (void)fire
{
	if(![XspfQTPref preloadingEnabled]) return;
	if(self.didPreloading) return;
	
	NSTimeInterval duration;
	NSTimeInterval current;
	QTTime qttime = [self.playingMovie currentTime];
	if(!QTGetTimeInterval(qttime, &current)) return;
	
	duration = self.playingMovieDuration;
	
	if( current / duration > XspfQTPref.beginingPreloadPercent ) {
		self.didPreloading = YES;
		HMXSPFComponent *list = self.trackList;
		NSUInteger nextIndex = list.selectionIndex + 1;
		NSUInteger max = list.childrenCount;
		if(max <= nextIndex) return;
		
		HMXSPFComponent *nextTrack = [list childAtIndex:nextIndex];
		NSURL *nextMovieURL = nextTrack.movieLocation;
		self.loader.movieURL = nextMovieURL;
		[self.loader load];
	}
}

@end
