/* 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.
 */
//
//  MHBB.m
//  Hootenanny
//
//  Created by Noah Sorscher on Wed Mar 26 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//

/* Jan Devos says:
 * As I understand it, this object does the actual search of the chapters on barnes and noble?
 * However the results should be passed on to the tChapters object which is the mediator for the interface?
 * Although it looks like tChapters does some heavy lifting as well ...
 * Conceptually speaking, I've used MHBB to do the web lookup and tChapters for the displaying
 */

#import "MHBB.h"

// this variable stores a handle to the parent object so we can send messages back
id chapterInterfaceController;

/* Jan Devos says:
 * This interface specifies the methods tChapters support so we don't get compile warnings.
 * This is effecively specifying an informal protocol on NSObject called tChapters.
 */
@interface NSObject (tChapters)
- (void)webSearchComplete;
@end


@implementation MHBB

- (MHBB *)init
{
    self = [super init];
    bbResults = [[NSMutableArray alloc] init];
    bbResults2 = [[NSMutableArray alloc] init];
    chapterList = [[NSMutableArray alloc] init];
    picField = nil;
	bbText = nil;
    bbImage = bbLocalImage = nil;
    linkButton = nil;
    timeScale = 600;
    return self;
}

- (void)setChapterInterfaceController:(id)theChapterInterfaceController
{
	// 'set' access method for private chapterInterfaceController
	if(theChapterInterfaceController)
		chapterInterfaceController = theChapterInterfaceController;
}

- (NSMutableArray *)bbResults
{
	// 'get' access method for public bbResults
	if(bbResults)
		return bbResults;
	else
		return nil;
}

- (NSString *)fixlink:(NSString *)link
{
	if (!link) return nil;
	NSMutableString *fixedlink = [NSMutableString stringWithString:link];
	[fixedlink replaceOccurrencesOfString:@"&amp;" withString:@"&" options:0 range:NSMakeRange(0, [fixedlink length])];
	return fixedlink;
}

- (BOOL)search:(NSString *)searchString
{
    if (searchString == nil || [searchString isEqualToString:@""]) return NO;
    //NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    //[dict setObject:searchString forKey:@"string"];
    [NSThread detachNewThreadSelector:@selector(runSearch:) toTarget:self withObject:searchString];
    return YES;
}

- (void)runSearch:(NSString *)input
{
    //NSLog(@"bbSearch");
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if (nil == input || [input isEqualToString:@""]) return;
    NSString *link = nil, *title = nil;
    NSDictionary *aResult;
    
    NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBkeys"];
    if (!path)
        path = [[NSBundle mainBundle] pathForResource:@"BBkeys" ofType:@"xml"];
    NSDictionary *keys = [NSDictionary dictionaryWithContentsOfFile:path];
    if (!keys) {
        NSLog(@"BBKeys file mis-formed!");
        return;
    }
    NSString *searchAddress = [keys objectForKey:@"searchAddress"];
    
    //  Get the Search Results
    [bbResults removeAllObjects];
    [bbResults2 removeAllObjects];
    input = [MHUtil spaceToPlus:input];
    NSString *htmlString = nil;
    NSString *address = [NSString stringWithFormat:searchAddress, input];
    if (bbText != nil)
        //[bbText setStringValue:[NSString stringWithFormat:@"Downloading from %@...", address]];
        [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:[NSString stringWithFormat:@"Downloading from %@...", address] waitUntilDone:NO];
    if (linkButton)
        [linkButton setTitle:address];
    htmlString = [NSString stringWithContentsOfURL:[NSURL URLWithString:address]];
	//[htmlString writeToFile:@"/html.html" atomically:NO];
    if (!htmlString)
        htmlString = [NSString stringWithContentsOfCURL:[NSURL URLWithString:address]];
    //  Get the Page Link and Title
    if (htmlString == nil) {
        if (bbText != nil)
            //[bbText setStringValue:[NSString stringWithFormat:@"error: no data in document at %@", address]];
            [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:[NSString stringWithFormat:@"error: no data in document at %@", address] waitUntilDone:NO];
        [pool release];
        return;
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"mhWebPageDownloadedNotification" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:address, @"link", htmlString, @"string", nil]];
    NSString *confirm = [[keys objectForKey:@"titles"] objectForKey:@"confirmResults"];
    if (confirm && ![htmlString rangeOfString:confirm].length) { // direct hit
        aResult = [NSDictionary dictionaryWithObjectsAndKeys:address, @"link", input, @"title", nil];
        [bbResults addObject:aResult];
    } else { // search results
        NSScanner *scan = [[NSScanner alloc] initWithString:htmlString];
        [scan setCaseSensitive:NO];
        NSArray *skip1 = [[keys objectForKey:@"titles"] objectForKey:@"skip"], *skip2;
        int i, n = [skip1 count];
        NSString *buf = nil;
        int loc = 0;
        for (i=0;i<n;i++) {
            buf = [skip1 objectAtIndex:i];
            [scan scanPastString:[skip1 objectAtIndex:i]];
            loc = [scan scanLocation];
        }
        //[scan scanUpToString:@"<!-- begin movie browse results" intoString:nil];
        NSDictionary *titles = [[keys objectForKey:@"titles"] objectForKey:@"titles"];
        skip1 = [titles objectForKey:@"link skip"];
        skip2 = [titles objectForKey:@"title skip"];
        NSString *end1 = [titles objectForKey:@"link end"], *end2 = [titles objectForKey:@"title end"];
        while (![scan isAtEnd]) {
            aResult = nil;
            link = title = nil;
            n = [skip1 count];
            for (i=0;i<n;i++) {
                buf = [skip1 objectAtIndex:i];
                [scan scanPastString:[skip1 objectAtIndex:i]];
                loc = [scan scanLocation];
            }
            [scan scanUpToString:end1 intoString:&link];
            link = [self fixlink:[link stringRelativeToString:address]];
            n = [skip2 count];
            for (i=0;i<n;i++) {
                buf = [skip2 objectAtIndex:i];
                [scan scanPastString:[skip2 objectAtIndex:i]];
                loc = [scan scanLocation];
            }
            [scan scanUpToString:end2 intoString:&title];
            title = [MHUtil fixIMDB:title];
            if (!link)
                break;
            aResult = [NSDictionary dictionaryWithObjectsAndKeys:link, @"link", title, @"title", nil];
            [bbResults addObject:aResult];
        }
    }
    // Find Results
	/*
	cancelled = NO;
    for (bbResultsIndex = 0; bbResultsIndex < [bbResults count]; bbResultsIndex++) {
        link = title = nil;
        if (cancelled) break;
        aResult = [bbResults objectAtIndex:bbResultsIndex];
        link = [aResult objectForKey:@"link"];
        title = [aResult objectForKey:@"title"];
        if ([self getDVDFeatures:link])
            break;
    }
	*/
    // Display Results
    //if (title == nil) title = input;
	
	/* Jan Devos says:
	 * Time to send a message to the chapterGUIController that the lookup was complete. 
	 */
	[chapterInterfaceController webSearchComplete];
    
	//[self displayResultsForTitle:title];
    [pool release];
}

- (void) cancel
{
    cancelled = YES;
}

- (void)displayResultsForTitle:(NSString *)title
{
    //NSLog(@"displayBBResultsForTitle");
    if (bbText == nil) return;
    int i, n = [chapterList count];
    //int totalSeconds = 0;
    NSMutableString *result = [NSMutableString stringWithCapacity:128*n];
    //[result appendFormat:@"(result %d of %d)\n", bbResultsIndex + 1, [bbResults count]];
    if (title != nil)
        [result appendString:[NSString stringWithFormat:@"\"%@\":\n", title]];
    for (i=0;i<n;i++) {
        int seconds = [[[chapterList objectAtIndex:i] objectForKey:@"nSeconds"] intValue];
        [result appendString:[NSString stringWithFormat:@"%@, %d:%02d\n", [[chapterList objectAtIndex:i] objectForKey:@"Content"], seconds / 60, seconds % 60]];
    }
    if (0 == n)
        [result appendString:@"search error.  no valid results"];
    if (nil != bbImage && picField != nil) {
        //if (nil == title) title = input;
        NSRange aRange = [bbImage rangeOfString:@"/" options:NSBackwardsSearch];
        if (aRange.length) {
            [bbLocalImage release];
            bbLocalImage = [[NSString alloc] initWithFormat:@"%@bb%@.%@", [MHUtil supportDir], title, [bbImage substringFromIndex:aRange.location+1]];
            BOOL isDir;
            if (![[NSFileManager defaultManager] fileExistsAtPath:bbLocalImage isDirectory:&isDir] || isDir) {
                NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:bbImage]];
                if (nil != data)
                    [data writeToFile:bbLocalImage atomically:NO];
            }
            NSImage *image = [[NSImage alloc] initWithContentsOfFile:bbLocalImage];
            [picField performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
            //NSAttributedString *picString = [NSAttributedString attributedStringWithAttachment:[[NSTextAttachment alloc] initWithFileWrapper:[[NSFileWrapper alloc] initWithPath:path]]];
            //[picField setStringValue:(NSString *)picString];
            //[picField performSelectorOnMainThread:@selector(setStringValue:) withObject:picString waitUntilDone:NO];
        }
    }
    //[bbText setStringValue:result];
    [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:result waitUntilDone:NO];
}

- (BOOL)getDVDFeatures:(NSString *)address
{
	address = [self fixlink:address];
    NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBkeys"];
    if (!path)
        path = [[NSBundle mainBundle] pathForResource:@"BBkeys" ofType:@"xml"];
    NSDictionary *keys = [NSDictionary dictionaryWithContentsOfFile:path];
    if (!keys) {
        NSLog(@"BBKeys file mis-formed!");
        return NO;
    }

    //NSLog(@"tWWW getDVDFeatures");
    NSString *htmlString = nil;
    if (bbText != nil)
        //[bbText setStringValue:[NSString stringWithFormat:@"Downloading From %@...", address]];
        [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:[NSString stringWithFormat:@"Downloading From %@...", address] waitUntilDone:NO];
    if (linkButton)
        [linkButton setTitle:address];
    htmlString = [NSString stringWithContentsOfURL:[NSURL URLWithString:address]];
    if (!htmlString)
        htmlString = [NSString stringWithContentsOfCURL:[NSURL URLWithString:address]];
    if (bbText != nil)
        //[bbText setStringValue:@""];
        [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:@"" waitUntilDone:NO];
    if (nil == htmlString) {
        if (bbText != nil)
            //[bbText setStringValue:[NSString stringWithFormat:@"error: no data in document at %@", address]];
            [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:[NSString stringWithFormat:@"error: no data in document at %@", address] waitUntilDone:NO];
        return NO;
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"mhWebPageDownloadedNotification" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:address, @"link", htmlString, @"string", nil]];
    //[htmlString writeToFile:@"/string.html" atomically:NO];
	
	
    NSScanner *scan = [NSScanner scannerWithString:htmlString];
    [scan setCaseSensitive:NO];
    NSArray *skip = [[keys objectForKey:@"dvd features"] objectForKey:@"skip"];
    int i, n = [skip count];
    NSString *buf = nil;
    for (i=0;i<n;i++) {
        buf = [skip objectAtIndex:i];
        [scan scanPastString:[skip objectAtIndex:i]];
    }
    if ([scan isAtEnd])
        return NO;
    NSString *name = [[keys objectForKey:@"dvd features"] objectForKey:@"linkName"];
	if (!name) {
        NSLog(@"BBkeys.xml -> dvd features -> links -> end  not found");
        return NO;
	}
	
	
	NSRange r = [htmlString rangeOfString:name];
	NSString	* link = NULL;
		
	if (r.length) {
		link = [htmlString substringToIndex:r.location];
		NSString *start = [[keys objectForKey:@"dvd features"] objectForKey:@"linkStart"];
		if (start) {
			r = [link rangeOfString:start options:NSBackwardsSearch];
			if (r.length) {
				link = [link substringFromIndex:r.location + r.length];
				NSString *end = [[keys objectForKey:@"dvd features"] objectForKey:@"linkEnd"];
				if (end) {
					r = [link rangeOfString:end];
					if (r.length) {
						link = [self fixlink:[link substringToIndex:r.location]];
						link = [link stringRelativeToString:address];
						if (link) {
							//[self getImageFromHTML:link];
							[bbResults2 addObject:link];
						}
					}
				}
			}
		}
	}
	
    // get the chapters
	if(link)
	{
		[self getChaptersFromURL:link];
		return YES;
    }
	
	//for (bbResultsIndex2 = 0; bbResultsIndex2 < [bbResults2 count]; bbResultsIndex2++) {
    //    if ([self getChaptersFromURL:[bbResults2 objectAtIndex:bbResultsIndex2]])
    //        return YES;
    //}
	
    return NO;

}

- (BOOL)getChaptersFromURL:(NSString *)address
{
    NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBkeys"];
    if (!path)
        path = [[NSBundle mainBundle] pathForResource:@"BBkeys" ofType:@"xml"];
    NSDictionary *keys = [NSDictionary dictionaryWithContentsOfFile:path];
    if (!keys) {
        NSLog(@"BBKeys file mis-formed!");
        return NO;
    }
	
    if (!address) return NO;
    //NSLog(@"tWWW getChaptersFromURL:");
    NSString *buffer, *htmlString = nil;
    BOOL valid = NO;
    if (bbText != nil)
        //[bbText setStringValue:[NSString stringWithFormat:@"Downloading From %@...", address]];
        [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:[NSString stringWithFormat:@"Downloading From %@...", address] waitUntilDone:NO];
    if (linkButton)
        [linkButton setTitle:address];
    htmlString = [NSString stringWithContentsOfURL:[NSURL URLWithString:address]];
    if (!htmlString)
        htmlString = [NSString stringWithContentsOfCURL:[NSURL URLWithString:address]];
    if (bbText != nil)
        //[bbText setStringValue:@""];
        [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:@"" waitUntilDone:NO];
    if (nil == htmlString) {
        if (bbText != nil)
            //[bbText setStringValue:[NSString stringWithFormat:@"error: no data in document at %@", address]];
            [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:[NSString stringWithFormat:@"error: no data in document at %@", address] waitUntilDone:NO];
        return NO;
    }
	
    [[NSNotificationCenter defaultCenter] postNotificationName:@"mhWebPageDownloadedNotification" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:address, @"link", htmlString, @"string", nil]];
    htmlString = [MHUtil newLines:htmlString];
    NSScanner *scan = [NSScanner scannerWithString:htmlString];
    [scan setCaseSensitive:NO];
    NSDictionary *chapters = [keys objectForKey:@"chapters"];
    NSArray *skip = [chapters objectForKey:@"skip"];
    int i, n = [skip count];
    for (i=0;i<n;i++)
        [scan scanPastString:[skip objectAtIndex:i]];
    //[scan scanUpToString:@"<!-- begin dvd features" intoString:nil];
    [chapterList removeAllObjects];
    int strikes = 0, start = [scan scanLocation];
    NSDictionary *dict = [chapters objectForKey:@"chaps"];
    NSMutableArray *strings = [NSMutableArray array];
    NSArray *sKeys = [NSArray arrayWithObjects:@"cue", @"end", @"time start", @"time stop", @"trim", nil];
    n = [sKeys count];
    for (i=0;i<n;i++) {
        buffer = [dict objectForKey:[sKeys objectAtIndex:i]];
        if (!buffer) {
            NSLog(@"BBkeys.xml -> chapters -> chaps -> %@  not found", [sKeys objectAtIndex:i]);
            return NO;
        }
        [strings addObject:buffer];
    }
	
    i=1;
    while (strikes < 5) {
        buffer = nil;
        [scan setScanLocation:start];
        [scan scanUpToString:[NSString stringWithFormat:[strings objectAtIndex:0], i++] intoString:nil];
        char ch = [[scan string] characterAtIndex:[scan scanLocation]-1];
        if (ch < '1' || ch > '9')
            [scan scanUpToString:[strings objectAtIndex:1] intoString:&buffer];
        if (nil != buffer) {
            NSDictionary *aChapter = [self parseChapter:buffer];
            if (aChapter) {
                [chapterList addObject:aChapter];
                valid = YES;
            }
        }
        if ([scan isAtEnd])
            strikes++;
        else
            strikes = 0;
    }
	
    return valid;
}

- (void)getImageFromHTML:(NSString *)input
{
    NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBkeys"];
    if (!path)
        path = [[NSBundle mainBundle] pathForResource:@"BBkeys" ofType:@"xml"];
    NSDictionary *keys = [NSDictionary dictionaryWithContentsOfFile:path];
    if (!keys) {
        NSLog(@"BBKeys file mis-formed!");
        return;
    }
    if (!picField) {
        bbImage = nil;
        [bbLocalImage release];
        bbLocalImage = nil;
        return;
    }
    NSString *tag, *buffer;
    NSScanner *s, *scan = [NSScanner scannerWithString:input];
    [scan setCaseSensitive:NO];
    NSArray *skip = [[[keys objectForKey:@"dvd features"] objectForKey:@"image"] objectForKey:@"skip"];
    int i, n = [skip count];
    for (i=0;i<n;i++)
        [scan scanPastString:[skip objectAtIndex:i]];
    //[scan scanUpToString:@"class=\"detailTitle\">" intoString:nil];
    while (![scan isAtEnd]) {
        buffer = nil;
        [scan scanUpToString:@"<img" intoString:nil];
        [scan scanUpToString:@">" intoString:&tag];
        s = [NSScanner scannerWithString:tag];
        [s setCaseSensitive:NO];
        [s scanUpToString:[[[keys objectForKey:@"dvd features"] objectForKey:@"image"] objectForKey:@"tag contains"] intoString:nil];
        if (![s isAtEnd]) {
            [s setScanLocation:0];
            [s scanUpToString:@"src=\"" intoString:nil];
            [s scanString:@"src=\"" intoString:nil];
            //[s scanString:@"src=\"" intoString:nil];
            [s scanUpToString:@"\"" intoString:&buffer];
            break;
        }
    }
    [bbImage release];
    bbImage = [buffer retain];
}

- (NSDictionary *)parseChapter:(NSString *)input
{
    NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBkeys"];
    if (!path)
        path = [[NSBundle mainBundle] pathForResource:@"BBkeys" ofType:@"xml"];
    NSDictionary *keys = [[[NSDictionary dictionaryWithContentsOfFile:path] objectForKey:@"chapters"] objectForKey:@"chaps"];
    if (!keys) {
        NSLog(@"BBKeys file mis-formed!");
        return nil;
    }
    //NSLog(@"tWWW parseChapter:");
    if (input == nil || ![input isKindOfClass:[NSString class]]) return nil;
    NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:3];
    // Time Length
    const char *cString = [input cString];
    char ch, timeStart = [[keys objectForKey:@"time start"] characterAtIndex:0], timeStop = [[keys objectForKey:@"time stop"] characterAtIndex:0], trim = [[keys objectForKey:@"trim"] characterAtIndex:0];
    int total, colTal, dig, i, n = [input length];
    total = colTal = dig = 0;
    BOOL timeOn = NO;
    for (i=n-1; i>=0; i--) {
        ch = cString[i];
        if (timeOn && ch >= '0' && ch <= '9')
            total += (ch - '0') * [MHUtil expon:10 toThe:dig++] * [MHUtil expon:60 toThe:colTal];
        else if (timeOn && ch == ':') {
            dig = 0;
            colTal++;
        } else if (ch == timeStop)
            timeOn = YES;
        else if (ch == timeStart)
            break;
    }
    //[result setObject:[NSNumber numberWithLong:samples] forKey:@"Start"];
    [result setObject:[NSNumber numberWithInt:total] forKey:@"nSeconds"];
    // Text
    if (i<=0) i=n;
    for (i--; i>=0; i--) {
        if (cString[i] != trim) break;
    }
    NSString *s = [NSString stringWithCString:cString length:i+1];
    NSRange aRange = [s rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\r\n"]];
    if (aRange.location != NSNotFound)
        s = [s substringToIndex:aRange.location];
    s = [MHUtil fixIMDB:s];
    [result setObject:s forKey:@"Content"];
    return result;
}

- (MHChapters *)chapters
{
    return [self chaptersScaledToMovie:nil];
}

- (MHChapters *)chaptersScaledToMovie:(NSMovie *)movie
{
    //NSLog(@"addUpChapters");
    int nSeconds, i, n = [chapterList count];
    long total = 0;
    NSMutableDictionary *aChapter, *newChapter;
    NSMutableArray *newList = [NSMutableArray array];
    for (i=0;i<n;i++) {
        aChapter = [chapterList objectAtIndex:i];
        newChapter = [NSMutableDictionary dictionary];
        [newChapter setObject:[aChapter objectForKey:@"Content"] forKey:@"Content"];
        [newChapter setObject:[NSNumber numberWithDouble:total] forKey:@"Start"];
        nSeconds = [[aChapter objectForKey:@"nSeconds"] longValue];
        //[aChapter removeObjectForKey:@"nSeconds"];
        total += nSeconds;
        if (i == n-1)
            [newChapter setObject:[NSNumber numberWithDouble:nSeconds] forKey:@"nSeconds"];
        [newList addObject:newChapter];
    }
    if (nil != movie) {
        double scalar = (double)GetMovieDuration([movie QTMovie]) / (double)total / (double)GetMovieTimeScale([movie QTMovie]);
        for (i=0;i<n;i++) {
            aChapter = [newList objectAtIndex:i];
            [aChapter setObject:[NSNumber numberWithDouble:[[aChapter objectForKey:@"Start"] doubleValue] * scalar] forKey:@"Start"];
        }
    }
    //[chapters setChapters:chapterList];
    MHChapters *ch = [[MHChapters alloc] init];
    //[ch setTimeScale:timeScale];
    [ch addObjectsFromArray:newList];
    if (bbLocalImage)
        [[NSNotificationCenter defaultCenter] postNotificationName:@"CoverImageFoundNotification" object:bbLocalImage];
    return ch;
}

- (IBAction)bbSearchAgain:(id)sender
{
    [NSThread detachNewThreadSelector:@selector(bbSearchAgainThreaded:) toTarget:self withObject:nil];
}

- (void)bbSearchAgainThreaded:(id)input
{
    //NSLog(@"search again threaded");
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *link, *title;
    cancelled = NO;
    for (bbResultsIndex2++; bbResultsIndex2 < [bbResults2 count] && bbResultsIndex < [bbResults count]; bbResultsIndex++) {
        link = title = nil;
        if (cancelled) goto bail;
        link = [bbResults2 objectAtIndex:bbResultsIndex2];
        title = [[bbResults objectAtIndex:bbResultsIndex] objectForKey:@"title"];
        if ([self getChaptersFromURL:link]) {
            [self displayResultsForTitle:title];
            goto bail;
        }
    }
    for (bbResultsIndex++; bbResultsIndex < [bbResults count]; bbResultsIndex++) {
        if (cancelled) goto bail;
        NSDictionary *result = [bbResults objectAtIndex:bbResultsIndex];
        link = [result objectForKey:@"link"];
        title = [result objectForKey:@"title"];
        if ([self getDVDFeatures:link]) {
            [self displayResultsForTitle:title];
            goto bail;
        }
    }
    [bbText performSelectorOnMainThread:@selector(setStringValue:) withObject:@"No More Results" waitUntilDone:NO];
bail:
    [pool release];
    //[self displayBBResultsForTitle:title];
}

- (void)setTextField:(NSTextField *)field
{
    bbText = field;
}

- (void)setTextFieldForImage:(NSImageView *)field
{
    picField = field;
}

- (void)setLinkButton:(NSButton *)button
{
    linkButton = button;
}

- (void)setTimeScale:(TimeScale)ts
{
    timeScale = ts;
}

- (void)setTimeScaleFromMovie:(NSMovie *)movie
{
    if (movie == nil) return;
    timeScale = GetMovieTimeScale([movie QTMovie]);
}

@end
