//
//  AppController.m
//  NativeHost
//
//  Created by Francisco Tolmasky on 6/4/09.
//  Copyright 2009 280 North, Inc. All rights reserved.
//

#import "Console.h"
#import "Server.h"
#import "AppController.h"
#import "NSURL+Additions.h"
#import "BridgedMethods.h"
#import "WebWindow.h"
#import "WebScripObject+Objective-J.h"

extern int interactive;

int SERVER_PORT = 9191;
NSString *SERVER_PASSWORD = nil;
NSString *SERVER_USER = nil;


@implementation AppController

- (id)init
{
    self = [super init];

    if (self)
        openingURLStrings = [NSMutableArray new];

    return self;
}

- (void)dealloc
{
    [webView release];
    [webViewWindow release];

    [openingURLStrings release];

    [super dealloc];
}

- (BOOL)application:(NSApplication *)anApplication openFile:(NSString *)aFilename
{
    id canOpenFilesImmediately = [[webView windowScriptObject] evaluateWebScript:@"CPApp && CPApp._finishedLaunching"];

    NSString *path = [[[NSURL fileURLWithPath:aFilename] HTTPFileSystemURL] absoluteString];
    if ([canOpenFilesImmediately isKindOfClass:[NSNumber class]] && [canOpenFilesImmediately boolValue])
        [[webView windowScriptObject] evaluateObjectiveJ:[NSString stringWithFormat:@"[CPApp _openURL:[CPURL URLWithString:\"%@\"]]", path]];
    else
        [openingURLStrings addObject:path];

    return NO;
}

- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    NSUserDefaults  * defaults = [NSUserDefaults standardUserDefaults];

    [defaults registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"WebKitDeveloperExtras"]];

    [self startServer];
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    [self startCappuccinoApplication];
}

- (void)applicationDidResignActive:(NSNotification *)aNotification
{
    // FIXME: handle this better.
    [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _willResignActive];"];
    [[self windowScriptObject] evaluateObjectiveJ:@"CPApp._isActive = NO;"];
    [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _didResignActive];"];
}

- (void)applicationDidBecomeActive:(NSNotification *)aNotification
{
    // FIXME: handle this better.
    [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _willBecomeActive];"];
    [[self windowScriptObject] evaluateObjectiveJ:@"CPApp._isActive = YES;"];
    [[self windowScriptObject] evaluateObjectiveJ:@"[CPApp _didBecomeActive];"];
}

- (NSArray *)openingURLStrings
{
    return openingURLStrings;
}

- (NSView *)keyView
{
    return [[[webView mainFrame] frameView] documentView];
}

- (WebView *)webView
{
    return webView;
}

- (WebScriptObject *)windowScriptObject
{
    return [webView windowScriptObject];
}

- (void)startServer
{
    server = [[Server alloc] init];

    if (![server start])
        exit(0);

	if (interactive)
	{
        stdinFileHandle = [[NSFileHandle fileHandleWithStandardInput] retain];
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(didReadStdin:)
         name:NSFileHandleReadCompletionNotification
         object:stdinFileHandle];

        fprintf(stdout, "objj> ");
        fflush(stdout);
        [stdinFileHandle readInBackgroundAndNotify];
    }
}

- (void)didReadStdin:(NSNotification *)aNotification
{
    NSString *string = [[NSString alloc] initWithData:[[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem] encoding:NSASCIIStringEncoding];
    NSString *result = [[self windowScriptObject] evaluateObjectiveJReturningString:string];
    [string release];
    if ([result respondsToSelector:@selector(UTF8String)])
        fprintf(stdout, "%s\n", [result UTF8String]);
    fprintf(stdout, "objj> ");
    fflush(stdout);
    [stdinFileHandle readInBackgroundAndNotify];
}

- (NSURL *)baseURL
{
    return baseURL;
}

- (void)startCappuccinoApplication
{
    NSString *initialURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialURL"];
    BOOL prependServer = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialURLPrependServer"] boolValue];

    if (!initialURL)
    {
        NSString *initialResource = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialResource"];
        
        if (!initialResource)
            initialResource = @"Application/index.html";

        initialURL = [[NSString stringWithFormat:@"file://%@/%@", [[NSBundle mainBundle] resourcePath], initialResource] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        baseURL = [[NSURL alloc] initWithString:@"file:///"];
    }
    else if (prependServer)
    {
        initialURL = [NSString stringWithFormat:@"http://127.0.0.1:%d/%@", SERVER_PORT, initialURL];
        baseURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", SERVER_PORT]];
    }

	NHLog(@"STARTUP", [initialURL description]);
	
    [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:initialURL]]];
}

- (void)applicationWillTerminate:(NSNotification *)aNotification
{
    [server stop];
}

- (void)configureLocalStorage
{
    WebPreferences *webConfiguration = [WebPreferences standardPreferences];
    NSBundle *mainBundle = [NSBundle mainBundle];
    NSString *cappBundleName = [mainBundle objectForInfoDictionaryKey:@"CPBundleName"];
    NSString *applicationSupportFile = [@"~/Library/Application Support/" stringByExpandingTildeInPath];
    NSString *savePath = [NSString pathWithComponents:[NSArray arrayWithObjects:applicationSupportFile, cappBundleName, @"LocalStorage", nil]];
    
    if ([webConfiguration respondsToSelector:@selector(setLocalStorageDatabasePath:)])
        [webConfiguration setLocalStorageDatabasePath:savePath];
    else
        [webConfiguration _setLocalStorageDatabasePath:savePath];
    
    [webView setPreferences:webConfiguration];
}

- (void)awakeFromNib
{
    webView = [[WebView alloc] init];

    [webView setUIDelegate:self];
    [webView setFrameLoadDelegate:self];
    [webView setResourceLoadDelegate:self];
    [webView setPolicyDelegate:self];
	
	[self configureLocalStorage];
	
    webViewWindow = [[NSWindow alloc] init];

    [webViewWindow setContentView:webView];
}

@end

void NHLog(NSString *type, NSString *message)
{
    NSArray *lines = [message componentsSeparatedByString:@"\n"];
    for (NSString *line in lines)
    {
        if ([line length] > 0)
            NSLog(@"%10@: %@", type, line);
    }
}
