/* 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.
 */
//
//  MHWeb.m
//  Hootenanny
//
//  Created by Noah Sorscher on Thu Apr 03 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//

#import "MHWeb.h"

@interface NSObject (mhwAdditions)
- (void)webSelectionMade:(id)anObject;
- (void)webOptionsButtonPressed;
- (NSDictionary *)metadata;
- (BOOL)expand;
@end

@interface MHWeb (private)
- (void) setTitle:(NSString *)aTitle;
@end

@implementation MHWeb

NSMutableArray *webListeners = nil, *optionsListeners = nil;
BOOL downloadImages;
id mhWebNibInstance;
NSString *defaultText;
BOOL asleep = YES;

+ (void) go
{
     //NSLog(@"MHWeb go");
    if (asleep) {
        NSWindowController *winCon = [[NSWindowController alloc] initWithWindowNibName:@"Web"];
        [winCon showWindow:self];
        
    } else {
        [mhWebNibInstance open];
    }
    [mhWebNibInstance setOptionsButton];
}

+ (void) setTitle:(NSString *)aTitle
{
    [mhWebNibInstance setTitle:aTitle];
}

+ (void) addWebSelectionListener:(id)listener
{
    //NSLog(@"MHWeb addWebSelectionListener");
    if (nil == listener)
        return;
    if (nil == webListeners)
        webListeners = [[NSMutableArray alloc] init];
    [webListeners addObject:listener];
}

- (void)controlTextDidChange:(NSNotification *)aNotification
{
    [self setTitle:myTitle];
}

- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
    [self setTitle:myTitle];
}

- (BOOL)windowShouldClose:(id)sender
{
    [bb cancel];
    [webWindow saveFrameUsingName:@"web"];
    return YES;
}

- (void)guessWholeSeries:(id)sender
{
    int i, n = [webListeners count];
    for (i=0;i<n;i++)
        if ([[webListeners objectAtIndex:i] respondsToSelector:@selector(guessWholeSeries:)])
            [[webListeners objectAtIndex:i] guessWholeSeries:sender];
}   
/*
- (MHChapters *)chapters
{
    return [bb chapters];
}

- (MHChapters *)chaptersScaledToMovie:(NSMovie *)aMovie
{
    return [bb chaptersScaledToMovie:aMovie];
}

+ (void)setDownloadsImages:(BOOL)flag
{
    downloadImages = flag;
}
*/
+ (void)addOptionsButtonListener:(id)listener
{
    if (nil == listener) return;
    if (nil == optionsListeners)
        optionsListeners = [[NSMutableArray alloc] init];
    [optionsListeners addObject:listener];
}

+ (void)setSearchText:(NSString *)input
{
    if (input)
        [mhWebNibInstance setString:input];
}

- (void) awakeFromNib
{
    //NSLog(@"MHWeb");
    mhWebNibInstance = self;
    downloadImages = YES;
    defaultText = @"";
    [optionsButton setEnabled:NO];
    asleep = NO;
    myTitle = nil;
    
    imdb = nil; // [[MHIMDB alloc] init];
    [imdb setTextField:resultText];
    [imdb setTableView:resultTable];
    [imdb setDownloadsImages:downloadImages];
    [imdb setLinkButton:sourceLink];
    [resultTable setDataSource:imdb];
    [resultTable setDelegate:imdb];
    
    epg = nil; // [[MHEPGTVT alloc] init];
    [epg setDelegate:self];
    [epg setTextField:epgText];
    [epg setOutlineView:theOutline];
    [epg setDownloadsImages:downloadImages];
    [epg setLinkButton:sourceLink];
    [theOutline setDataSource:epg];
    [theOutline setDelegate:epg];
    //[tSeriesObject setTextField:epgText];
    //[tSeriesObject setDownloadsImages:downloadImages];
    
    bb = nil; // [[MHBB alloc] init];
    [bb setTextField:bbText];
    [bb setTextFieldForImage:picField];
    [bb setLinkButton:sourceLink];
    
    expandingLock = [[NSLock alloc] init];
    
    [webWindow setFrameUsingName:@"web"];
    
    //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageLoaded:) name:@"mhWebPageDownloadedNotification" object:nil];
}

- (IBAction)search:(id)sender
{
    //NSLog(@"MHWeb search");
    [imdb setDownloadsImages:downloadImages];
    [epg setDownloadsImages:downloadImages];
    //[tSeriesObject setDownloadsImages:downloadImages];
    if (downloadImages)
        [bb setTextFieldForImage:picField];
    else
        [bb setTextFieldForImage:nil];
    NSString *input = [searchField stringValue];
    switch ([webTab indexOfTabViewItem:[webTab selectedTabViewItem]]) {
        case 0: // IMDB
            [imdb search:input];
            break;
        case 1: // EPG/TVT
            if ([epgtvt selectedRow] == 0)
                input = [@"EPG:" stringByAppendingString:input];
            else
                input = [@"TVT:" stringByAppendingString:input];
            [epg search:input];
            break;
        case 2: // Blockbuster
            [bb search:input];
            break;
        default:
            [resultText setStringValue:@"Internal Error!"];
    }
}


- (IBAction)bbSearchAgain:(id)sender
{
    if (nil == bb) return;
    [bb bbSearchAgain:nil];
}

- (IBAction)flush:(id)sender
{
    //NSLog(@"tWWW flush");
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSString *path = [defs objectForKey:@"cacheLocation"];
    [[NSFileManager defaultManager] removeFileAtPath:path handler:nil];
    //[defs removeObjectForKey:@"Cache"];
    [epg removeSeries];
    //[[tSeriesObject rootNode] removeChildren];
    [theOutline reloadData];
}

- (IBAction)okay:(id)sender
{
    //NSLog(@"MHWeb okay");
    id choice, selectedEp = nil;
    int choiceIndex, selectedTab, i, n = [webTab numberOfTabViewItems];
    for (i=0;i<n;i++) {
        if ([[webTab tabViewItemAtIndex:i] tabState] == NSSelectedTab) {
            selectedTab = i;
            break;
        }
    }
    
    //[webWindow orderOut:nil];
    switch (selectedTab) {
        case 0: // IMDB
            choiceIndex = [resultTable selectedRow];
            if (nil == imdb || -1 == choiceIndex) return;
            choice = [imdb result:choiceIndex];
            if (nil == choice) return;
            break;
        case 1: // EPGuide
            selectedEp = [theOutline itemAtRow:[theOutline selectedRow]];
            if (selectedEp == nil) return;
            choice = [selectedEp metadata];
            if (nil == choice) return;
            break;
        case 2: // Blockbuster
            //choice = [NSDictionary dictionaryWithObject:bb forKey:@"Chapters"];
            choice = self;
            break;
    }
    [okayButton setTitle:@"Updated"];
    if (choice == nil) return;
    if (nil == webListeners) return;
    n = [webListeners count];
    for (i=0;i<n;i++) {
        [[webListeners objectAtIndex:i] webSelectionMade:choice];
    }
}

- (IBAction)options:(id)sender
{
    //NSLog(@"MHWeb options");
    if (nil == optionsListeners) return;
    int i, n = [optionsListeners count];
    for (i=0;i<n;i++) {
        [[optionsListeners objectAtIndex:i] webOptionsButtonPressed];
    }
}


/*
- (NSString *)cacheString:(NSString *)input
{
    int tabNum = [webTab indexOfTabViewItem:[webTab selectedTabViewItem]];
    NSTextField *tf = nil;
    switch (tabNum) {
        case 0: tf = resultText; break;
        case 1: tf = epgText; break;
        default: tf = bbText; break;
    }
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *cache = [[NSMutableDictionary alloc] initWithCapacity:100];
    [cache addEntriesFromDictionary:[defs objectForKey:@"Cache"]];
    NSString *htmlString = nil;
    NSString *address = [[input componentsSeparatedByString:@"#"] objectAtIndex:0];
    htmlString = [cache objectForKey:address];
    if (nil == htmlString) {
        if ([input hasPrefix:@"EPG:"])
            address = [NSString stringWithFormat:@"http://epguides.master.com/texis/master/search/mysite.html?q=%@", [input substringFromIndex:4]];
        else if ([input hasPrefix:@"TVT:"])
            address = [NSString stringWithFormat:@"http://www.tvtome.com/tvtome/servlet/Search?searchType=show&searchString=%@", [input substringFromIndex:4]];
        [tf setStringValue:[NSString stringWithFormat:@"Downloading from %@...", address]];
        htmlString = [NSString stringWithContentsOfURL:[NSURL URLWithString:address]];
        [tf setStringValue:@""];
        if (htmlString != nil) {
            if ([input hasPrefix:@"EPG:"] || [input hasPrefix:@"TVT:"])
                address = input;
            [cache setObject:htmlString forKey:address];
            [defs setObject:cache forKey:@"Cache"];
            [defs synchronize];
        }
    }
    [cache release];
    return htmlString;
}

*/

- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item {
    return nil;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return NO;
}

- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    return 0;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    return @"/";
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
    //[NSThread detachNewThreadSelector:@selector(selectItem:) toTarget:self withObject:item];
    return YES;
}

- (void)selectItem:(id)item
{
    /*
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *summary = [item summary];
    if (summary != nil)
        //[epgText setStringValue:summary];
        [epgText performSelectorOnMainThread:@selector(setStringValue:) withObject:summary waitUntilDone:NO];
    else
        //[epgText setStringValue:@"no data"];
        [epgText performSelectorOnMainThread:@selector(setStringValue:) withObject:@"no data" waitUntilDone:NO];
    [pool release];
    */
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item
{  // expandingLock will be locked if and only if the expandItem method is the one calling for this expand.  so if it's locked, return YES.  but since the only way to check if it's locked involves locking it, unlock afterwards.
    //NSLog(@"MHWeb outlineView:shouldExpandItem:");
    if (![expandingLock tryLock]) return YES;
    [expandingLock unlock];
    [NSThread detachNewThreadSelector:@selector(expandItem:) toTarget:self withObject:item];
    return NO;
}

- (void)expandItem:(id)item
{
    //NSLog(@"MHWeb expandItem");
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    if (item != nil)
        if (![item expand])
            //[epgText setStringValue:@"error.  check internet connection"];
            [epgText performSelectorOnMainThread:@selector(setStringValue:) withObject:@"error -- check internet connection" waitUntilDone:NO];
    [expandingLock tryLock];
    [theOutline expandItem:item];
    [expandingLock unlock];
    [pool release];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    return NO;
}


- (IBAction)followLink:(id)sender
{
    NSString *string = [sourceLink title];
    //if (!string || [string isEqualToString:@""])
    //    string = [sourceLink stringValue];
    if (string)
        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:string]];
}

- (void)pageLoaded:(NSNotification *)note
{
    NSDictionary *dict = [note userInfo];
    NSString *link = [dict objectForKey:@"link"];
    NSString *string = [dict objectForKey:@"string"];
    //NSDictionary *attrsDict = [NSDictionary dictionaryWithObject:[NSURL URLWithString:link] forKey:NSLinkAttributeName];
    //NSAttributedString *astring = [[[NSAttributedString alloc] initWithString:link attributes:attrsDict] autorelease];
    if (link)
        [sourceLink setTitle:link];
    if (string)
        [sourceText setString:string];
}

- (void)setString:(NSString *)input
{
    defaultText = [input copy];
    [searchField setStringValue:input];
}

- (void)setOptionsButton
{
    [optionsButton setEnabled:(optionsListeners != nil && [optionsListeners count])];
}

- (void)open
{
    [searchField setStringValue:defaultText];
    [webWindow makeKeyAndOrderFront:nil];
}

- (void) setTitle:(NSString *)aTitle
{
    myTitle = [aTitle copy];
    if (!aTitle || [aTitle isEqualToString:@""]) {
        [webWindow setTitle:@"Internet Lookup"];
        [okayButton setTitle:@"Update Movie"];
    } else {
        [webWindow setTitle:[NSString stringWithFormat:@"Internet Lookup: \"%@\"", aTitle]];
        [okayButton setTitle:[NSString stringWithFormat:@"Update Movie: \"%@\"", aTitle]];
    }
}

@end
