/*
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "WK1BrowserWindowController.h"

#import "AppDelegate.h"
#import "SettingsController.h"
#import <WebKit/WebInspector.h>
#import <WebKit/WebKit.h>
#import <WebKit/WebNSURLExtras.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <WebKit/WebPreferenceKeysPrivate.h>
#import <WebKit/WebViewPrivate.h>

@interface WK1BrowserWindowController () <WebFrameLoadDelegate, WebPolicyDelegate, WebResourceLoadDelegate, WebUIDelegate>
@end

@implementation WK1BrowserWindowController

- (void)awakeFromNib
{
    _webView = [[WebView alloc] initWithFrame:[containerView bounds] frameName:nil groupName:@"MiniBrowser"];
    [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];

    _webView.editable = self.isEditable;

    [_webView setFrameLoadDelegate:self];
    [_webView setUIDelegate:self];
    [_webView setResourceLoadDelegate:self];
    [_webView setPolicyDelegate:self];

    [[WebPreferences standardPreferences] setFullScreenEnabled:YES];
    [[WebPreferences standardPreferences] setDeveloperExtrasEnabled:YES];
    [[WebPreferences standardPreferences] setImageControlsEnabled:YES];
    [[WebPreferences standardPreferences] setServiceControlsEnabled:YES];
    [[WebPreferences standardPreferences] setJavaScriptCanOpenWindowsAutomatically:YES];

    [_webView _listenForLayoutMilestones:WebDidFirstLayout | WebDidFirstVisuallyNonEmptyLayout | WebDidHitRelevantRepaintedObjectsAreaThreshold];

    SettingsController *settingsController = [[NSApplication sharedApplication] browserAppDelegate].settingsController;
    if (settingsController.customUserAgent)
        _webView.customUserAgent = settingsController.customUserAgent;

    [self didChangeSettings];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userAgentDidChange:) name:kUserAgentChangedNotificationName object:nil];

    [containerView addSubview:_webView];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [_webView setFrameLoadDelegate:nil];
    [_webView setUIDelegate:nil];
    [_webView setResourceLoadDelegate:nil];
    [_webView release];

    [super dealloc];
}

- (void)userAgentDidChange:(NSNotification *)notification
{
    SettingsController *settingsController = [[NSApplication sharedApplication] browserAppDelegate].settingsController;
    _webView.customUserAgent = settingsController.customUserAgent;
    [_webView reload:nil];
}

- (void)loadURLString:(NSString *)urlString
{
    // FIXME: We shouldn't have to set the url text here.
    [urlText setStringValue:urlString];
    [self fetch:nil];
}

- (void)loadHTMLString:(NSString *)HTMLString
{
    [_webView.mainFrame loadHTMLString:HTMLString baseURL:nil];
}

- (IBAction)fetch:(id)sender
{
    [urlText setStringValue:[self addProtocolIfNecessary:urlText.stringValue]];
    NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlText.stringValue];
    [[_webView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
}

- (IBAction)setPageScale:(id)sender
{
    CGFloat scale = [self pageScaleForMenuItemTag:[sender tag]];
    [_webView _scaleWebView:scale atOrigin:NSZeroPoint];
}

- (IBAction)setViewScale:(id)sender
{
}

- (IBAction)reload:(id)sender
{
    [_webView reload:sender];
}

- (IBAction)forceRepaint:(id)sender
{
    [_webView setNeedsDisplay:YES];
}

- (IBAction)goBack:(id)sender
{
    [_webView goBack:sender];
}

- (IBAction)goForward:(id)sender
{
    [_webView goForward:sender];
}

static BOOL areEssentiallyEqual(double a, double b)
{
    double tolerance = 0.001;
    return (fabs(a - b) <= tolerance);
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
#pragma GCC diagnostic pop
{
    SEL action = [menuItem action];

    if (action == @selector(saveAsPDF:))
        return NO;
    if (action == @selector(saveAsWebArchive:))
        return NO;

    if (action == @selector(zoomIn:))
        return [self canZoomIn];
    if (action == @selector(zoomOut:))
        return [self canZoomOut];
    if (action == @selector(resetZoom:))
        return [self canResetZoom];

    if (action == @selector(showHideWebView:))
        [menuItem setTitle:[_webView isHidden] ? @"Show Web View" : @"Hide Web View"];
    else if (action == @selector(removeReinsertWebView:))
        [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"];
    else if (action == @selector(toggleFullWindowWebView:))
        [menuItem setTitle:[self webViewFillsWindow] ? @"Inset Web View" : @"Fit Web View to Window"];
    else if (action == @selector(toggleZoomMode:))
        [menuItem setState:_zoomTextOnly ? NSControlStateValueOn : NSControlStateValueOff];
    else if (action == @selector(toggleEditable:))
        [menuItem setState:self.isEditable ? NSControlStateValueOn : NSControlStateValueOff];
    else if (action == @selector(showHideWebInspector:))
        [menuItem setTitle:_webView.inspector.isOpen ? @"Close Web Inspector" : @"Show Web Inspector"];
    else if (action == @selector(toggleAlwaysShowsHorizontalScroller:))
        menuItem.state = _webView.alwaysShowHorizontalScroller ? NSControlStateValueOn : NSControlStateValueOff;
    else if (action == @selector(toggleAlwaysShowsVerticalScroller:))
        menuItem.state = _webView.alwaysShowVerticalScroller ? NSControlStateValueOn : NSControlStateValueOff;

    if (action == @selector(setPageScale:))
        [menuItem setState:areEssentiallyEqual([_webView _viewScaleFactor], [self pageScaleForMenuItemTag:[menuItem tag]])];

    return YES;
}

- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
{
    SEL action = [item action];

    if (action == @selector(goBack:))
        return [_webView canGoBack];

    if (action == @selector(goForward:))
        return [_webView canGoForward];

    if (action == @selector(showCertificate:))
        return NO;

    return YES;
}

- (void)validateToolbar
{
    [toolbar validateVisibleItems];
}

- (BOOL)windowShouldClose:(id)sender
{
    return YES;
}

- (void)windowWillClose:(NSNotification *)notification
{
    [[[NSApplication sharedApplication] browserAppDelegate] browserWindowWillClose:self.window];
    [self autorelease];
}

- (double)currentZoomFactor
{
    return 1;
}

- (BOOL)canZoomIn
{
    return [_webView canMakeTextLarger];
}

- (void)zoomIn:(id)sender
{
    if (![self canZoomIn])
        return;

    if (_zoomTextOnly)
        [_webView makeTextLarger:sender];
    else
        [_webView zoomPageIn:sender];

}

- (BOOL)canZoomOut
{
    return [_webView canMakeTextSmaller];
}

- (void)zoomOut:(id)sender
{
    if (![self canZoomIn])
        return;

    if (_zoomTextOnly)
        [_webView makeTextSmaller:sender];
    else
        [_webView zoomPageOut:sender];
}

- (BOOL)canResetZoom
{
    return _zoomTextOnly ? [_webView canMakeTextStandardSize] : [_webView canResetPageZoom];
}

- (void)resetZoom:(id)sender
{
    if (![self canResetZoom])
        return;

    if (_zoomTextOnly)
        [_webView makeTextStandardSize:sender];
    else
        [_webView resetPageZoom:sender];
}

- (IBAction)toggleZoomMode:(id)sender
{
    // FIXME: non-text zoom not implemented.
    _zoomTextOnly = !_zoomTextOnly;
}

- (IBAction)toggleShrinkToFit:(id)sender
{
}

- (IBAction)dumpSourceToConsole:(id)sender
{
}

- (IBAction)showHideWebInspector:(id)sender
{
    WebInspector *inspector = _webView.inspector;
    if (inspector.isOpen)
        [inspector close:sender];
    else
        [inspector show:sender];
}

- (IBAction)toggleAlwaysShowsHorizontalScroller:(id)sender
{
    _webView.alwaysShowHorizontalScroller = !_webView.alwaysShowHorizontalScroller;
}

- (IBAction)toggleAlwaysShowsVerticalScroller:(id)sender
{
    _webView.alwaysShowVerticalScroller = !_webView.alwaysShowVerticalScroller;
}

- (NSURL *)currentURL
{
    return _webView.mainFrame.dataSource.request.URL;
}

- (NSView *)mainContentView
{
    return _webView;
}

- (void)setEditable:(BOOL)editable
{
    [super setEditable:editable];
    _webView.editable = editable;
}

- (void)didChangeSettings
{
    SettingsController *settings = [[NSApplication sharedApplication] browserAppDelegate].settingsController;

    [[WebPreferences standardPreferences] setShowDebugBorders:settings.layerBordersVisible];
    [[WebPreferences standardPreferences] setSimpleLineLayoutEnabled:settings.simpleLineLayoutEnabled];
    [[WebPreferences standardPreferences] setLegacyLineLayoutVisualCoverageEnabled:settings.legacyLineLayoutVisualCoverageEnabled];
    [[WebPreferences standardPreferences] setShowRepaintCounter:settings.layerBordersVisible];
    [[WebPreferences standardPreferences] setSuppressesIncrementalRendering:settings.incrementalRenderingSuppressed];
    [[WebPreferences standardPreferences] setAcceleratedDrawingEnabled:settings.acceleratedDrawingEnabled];
    [[WebPreferences standardPreferences] setSubpixelAntialiasedLayerTextEnabled:settings.subpixelAntialiasedLayerTextEnabled];
    [[WebPreferences standardPreferences] setResourceLoadStatisticsEnabled:settings.resourceLoadStatisticsEnabled];
    [[WebPreferences standardPreferences] setLargeImageAsyncDecodingEnabled:settings.largeImageAsyncDecodingEnabled];
    [[WebPreferences standardPreferences] setAnimatedImageAsyncDecodingEnabled:settings.animatedImageAsyncDecodingEnabled];
    [[WebPreferences standardPreferences] setColorFilterEnabled:settings.appleColorFilterEnabled];
    [[WebPreferences standardPreferences] setPunchOutWhiteBackgroundsInDarkMode:settings.punchOutWhiteBackgroundsInDarkMode];

    _webView._useSystemAppearance = settings.useSystemAppearance;

    [self setWebViewFillsWindow:settings.webViewFillsWindow];

    BOOL useTransparentWindows = settings.useTransparentWindows;
    if (useTransparentWindows != !self.window.isOpaque) {
        [self.window setOpaque:!useTransparentWindows];
        [self.window setBackgroundColor:[NSColor clearColor]];
        [self.window setHasShadow:!useTransparentWindows];

        [_webView setBackgroundColor:useTransparentWindows ? [NSColor clearColor] : [NSColor whiteColor]];

        [self.window display];
    }

    BOOL usePaginatedMode = settings.usePaginatedMode;
    if (usePaginatedMode != (_webView._paginationMode != WebPaginationModeUnpaginated)) {
        if (usePaginatedMode) {
            [_webView _setPaginationMode:WebPaginationModeLeftToRight];
            [_webView _setPageLength:_webView.bounds.size.width / 2];
            [_webView _setGapBetweenPages:10];
        } else
            [_webView _setPaginationMode:WebPaginationModeUnpaginated];
    }
}

- (IBAction)printWebView:(id)sender
{
    [[[[_webView mainFrame] frameView] printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]] runOperationModalForWindow:self.window delegate:nil didRunSelector:nil contextInfo:nil];
}

- (void)webView:(WebView *)sender didLayout:(WebLayoutMilestones)milestones
{
    if (milestones & WebDidFirstLayout)
        LOG(@"layout milestone: %@", @"first layout");

    if (milestones & WebDidFirstVisuallyNonEmptyLayout)
        LOG(@"layout milestone: %@", @"first non-empty layout");

    if (milestones & WebDidHitRelevantRepaintedObjectsAreaThreshold)
        LOG(@"layout milestone: %@", @"relevant repainted objects area threshold");
}

- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
{
    [listener use];
}

// WebFrameLoadDelegate Methods
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
{
}

- (void)updateTitle:(NSString *)title
{
    if (!title) {
        NSURL *url = _webView.mainFrame.dataSource.request.URL;
        title = url.lastPathComponent ?: url._web_userVisibleString;
    }

    [self.window setTitle:[title stringByAppendingFormat:@" [WK1]%@", _webView.editable ? @" [Editable]" : @""]];
}

- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
{
    WK1BrowserWindowController *newBrowserWindowController = [[WK1BrowserWindowController alloc] initWithWindowNibName:@"BrowserWindow"];
    [newBrowserWindowController.window makeKeyAndOrderFront:self];

    return newBrowserWindowController->_webView;
}

- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
{
    if (frame != [sender mainFrame])
        return;

    NSURL *committedURL = [[[frame dataSource] request] URL];
    urlText.stringValue = committedURL._web_userVisibleString;

    [self updateTitle:nil];
}

- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame
{
    if (frame != [sender mainFrame])
        return;

    NSURL *committedURL = [[[frame dataSource] request] URL];
    urlText.stringValue = committedURL._web_userVisibleString;
}

- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
{
    if (frame != [sender mainFrame])
        return;

    [self updateTitle:title];
}

- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
{
    return defaultMenuItems;
}

- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
{
    NSAlert *alert = [[NSAlert alloc] init];
    [alert addButtonWithTitle:@"OK"];

    alert.messageText = [NSString stringWithFormat:@"JavaScript alert dialog from %@.", frame.dataSource.request.URL.absoluteString];
    alert.informativeText = message;

    [alert runModal];
    [alert release];
}

- (BOOL)webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
{
    NSAlert *alert = [[NSAlert alloc] init];

    alert.messageText = [NSString stringWithFormat:@"JavaScript before unload dialog from %@.", frame.dataSource.request.URL.absoluteString];
    alert.informativeText = message;

    [alert addButtonWithTitle:@"Leave Page"];
    [alert addButtonWithTitle:@"Stay On Page"];

    NSModalResponse response = [alert runModal];
    
    [alert release];

    return response == NSAlertFirstButtonReturn;
}

- (NSUInteger)webView:(WebView *)webView dragDestinationActionMaskForDraggingInfo:(id <NSDraggingInfo>)draggingInfo
{
    return WebDragDestinationActionAny;
}

@end
