/*
 * Copyright (C) 2010, 2011 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 "config.h"
#import "PDFViewController.h"

#import "DataReference.h"
#import "WKAPICast.h"
#import "WKView.h"
#import "WebData.h"
#import "WebEventFactory.h"
#import "WebPageGroup.h"
#import "WebPageProxy.h"
#import "WebPreferences.h"
#import <PDFKit/PDFKit.h>
#import <WebCore/LocalizedStrings.h>
#import <wtf/text/WTFString.h>

// Redeclarations of PDFKit notifications. We can't use the API since we use a weak link to the framework.
#define _webkit_PDFViewDisplayModeChangedNotification @"PDFViewDisplayModeChanged"
#define _webkit_PDFViewScaleChangedNotification @"PDFViewScaleChanged"
#define _webkit_PDFViewPageChangedNotification @"PDFViewChangedPage"

using namespace WebKit;

@class PDFDocument;
@class PDFView;

@interface PDFDocument (PDFDocumentDetails)
- (NSPrintOperation *)getPrintOperationForPrintInfo:(NSPrintInfo *)printInfo autoRotate:(BOOL)doRotate;
@end

extern "C" NSString *_NSPathForSystemFramework(NSString *framework);

// MARK: C UTILITY FUNCTIONS

static void _applicationInfoForMIMEType(NSString *type, NSString **name, NSImage **image)
{
    ASSERT(name);
    ASSERT(image);
    
    CFURLRef appURL = 0;

    OSStatus error = LSCopyApplicationForMIMEType((CFStringRef)type, kLSRolesAll, &appURL);
    if (error != noErr)
        return;

    NSString *appPath = [(NSURL *)appURL path];
    if (appURL)
        CFRelease(appURL);

    *image = [[NSWorkspace sharedWorkspace] iconForFile:appPath];
    [*image setSize:NSMakeSize(16, 16)];

    *name = [[NSFileManager defaultManager] displayNameAtPath:appPath];
}

// FIXME 4182876: We can eliminate this function in favor if -isEqual: if [PDFSelection isEqual:] is overridden
// to compare contents.
static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selectionB)
{
    NSArray *aPages = [selectionA pages];
    NSArray *bPages = [selectionB pages];

    if (![aPages isEqual:bPages])
        return NO;

    NSUInteger count = [aPages count];
    for (NSUInteger i = 0; i < count; ++i) {
        NSRect aBounds = [selectionA boundsForPage:[aPages objectAtIndex:i]];
        NSRect bBounds = [selectionB boundsForPage:[bPages objectAtIndex:i]];
        if (!NSEqualRects(aBounds, bBounds))
            return NO;
    }

    return YES;
}

@interface WKPDFView : NSView
{
    PDFViewController* _pdfViewController;

    RetainPtr<NSView> _pdfPreviewView;
    PDFView *_pdfView;
    BOOL _ignoreScaleAndDisplayModeAndPageNotifications;
    BOOL _willUpdatePreferencesSoon;
}

- (id)initWithFrame:(NSRect)frame PDFViewController:(PDFViewController*)pdfViewController;
- (void)invalidate;
- (PDFView *)pdfView;
- (void)setDocument:(PDFDocument *)pdfDocument;

- (void)_applyPDFPreferences;
- (PDFSelection *)_nextMatchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag fromSelection:(PDFSelection *)initialSelection startInSelection:(BOOL)startInSelection;
@end

@implementation WKPDFView

- (id)initWithFrame:(NSRect)frame PDFViewController:(PDFViewController*)pdfViewController
{
    if ((self = [super initWithFrame:frame])) {
        _pdfViewController = pdfViewController;

        [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];

        Class previewViewClass = PDFViewController::pdfPreviewViewClass();
        ASSERT(previewViewClass);

        _pdfPreviewView.adoptNS([[previewViewClass alloc] initWithFrame:frame]);
        [_pdfPreviewView.get() setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
        [self addSubview:_pdfPreviewView.get()];

        _pdfView = [_pdfPreviewView.get() performSelector:@selector(pdfView)];
        [_pdfView setDelegate:self];
    }

    return self;
}

- (void)invalidate
{
    _pdfViewController = 0;
}

- (PDFView *)pdfView
{
    return _pdfView;
}

- (void)setDocument:(PDFDocument *)pdfDocument
{
    _ignoreScaleAndDisplayModeAndPageNotifications = YES;
    [_pdfView setDocument:pdfDocument];
    [self _applyPDFPreferences];
    _ignoreScaleAndDisplayModeAndPageNotifications = NO;
}

- (void)_applyPDFPreferences
{
    if (!_pdfViewController)
        return;

    WebPreferences *preferences = _pdfViewController->page()->pageGroup()->preferences();

    CGFloat scaleFactor = preferences->pdfScaleFactor();
    if (!scaleFactor)
        [_pdfView setAutoScales:YES];
    else {
        [_pdfView setAutoScales:NO];
        [_pdfView setScaleFactor:scaleFactor];
    }
    [_pdfView setDisplayMode:preferences->pdfDisplayMode()];
}

- (void)_updatePreferences:(id)ignored
{
    _willUpdatePreferencesSoon = NO;

    if (!_pdfViewController)
        return;

    WebPreferences* preferences = _pdfViewController->page()->pageGroup()->preferences();

    CGFloat scaleFactor = [_pdfView autoScales] ? 0 : [_pdfView scaleFactor];
    preferences->setPDFScaleFactor(scaleFactor);
    preferences->setPDFDisplayMode([_pdfView displayMode]);
}

- (void)_updatePreferencesSoon
{   
    if (_willUpdatePreferencesSoon)
        return;

    [self performSelector:@selector(_updatePreferences:) withObject:nil afterDelay:0];
    _willUpdatePreferencesSoon = YES;
}

- (void)_scaleOrDisplayModeOrPageChanged:(NSNotification *)notification
{
    ASSERT_ARG(notification, [notification object] == _pdfView);
    if (!_ignoreScaleAndDisplayModeAndPageNotifications)
        [self _updatePreferencesSoon];
}

- (void)_openWithFinder:(id)sender
{
    _pdfViewController->openPDFInFinder();
}

- (PDFSelection *)_nextMatchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag fromSelection:(PDFSelection *)initialSelection startInSelection:(BOOL)startInSelection
{
    if (![string length])
        return nil;

    int options = 0;
    if (!forward)
        options |= NSBackwardsSearch;

    if (!caseFlag)
        options |= NSCaseInsensitiveSearch;

    PDFDocument *document = [_pdfView document];

    PDFSelection *selectionForInitialSearch = [initialSelection copy];
    if (startInSelection) {
        // Initially we want to include the selected text in the search.  So we must modify the starting search 
        // selection to fit PDFDocument's search requirements: selection must have a length >= 1, begin before 
        // the current selection (if searching forwards) or after (if searching backwards).
        int initialSelectionLength = [[initialSelection string] length];
        if (forward) {
            [selectionForInitialSearch extendSelectionAtStart:1];
            [selectionForInitialSearch extendSelectionAtEnd:-initialSelectionLength];
        } else {
            [selectionForInitialSearch extendSelectionAtEnd:1];
            [selectionForInitialSearch extendSelectionAtStart:-initialSelectionLength];
        }
    }
    PDFSelection *foundSelection = [document findString:string fromSelection:selectionForInitialSearch withOptions:options];
    [selectionForInitialSearch release];

    // If we first searched in the selection, and we found the selection, search again from just past the selection
    if (startInSelection && _PDFSelectionsAreEqual(foundSelection, initialSelection))
        foundSelection = [document findString:string fromSelection:initialSelection withOptions:options];

    if (!foundSelection && wrapFlag)
        foundSelection = [document findString:string fromSelection:nil withOptions:options];

    return foundSelection;
}

- (NSUInteger)_countMatches:(NSString *)string caseSensitive:(BOOL)caseFlag
{
    if (![string length])
        return 0;

    int options = caseFlag ? 0 : NSCaseInsensitiveSearch;

    return [[[_pdfView document] findString:string withOptions:options] count];
}

// MARK: NSView overrides

- (void)viewDidMoveToWindow
{
    if (![self window])
        return;

    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter addObserver:self selector:@selector(_scaleOrDisplayModeOrPageChanged:) name:_webkit_PDFViewScaleChangedNotification object:_pdfView];
    [notificationCenter addObserver:self selector:@selector(_scaleOrDisplayModeOrPageChanged:) name:_webkit_PDFViewDisplayModeChangedNotification object:_pdfView];
    [notificationCenter addObserver:self selector:@selector(_scaleOrDisplayModeOrPageChanged:) name:_webkit_PDFViewPageChangedNotification object:_pdfView];
}

- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
    if (![self window])
        return;

    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:_webkit_PDFViewScaleChangedNotification object:_pdfView];
    [notificationCenter removeObserver:self name:_webkit_PDFViewDisplayModeChangedNotification object:_pdfView];
    [notificationCenter removeObserver:self name:_webkit_PDFViewPageChangedNotification object:_pdfView];
}

- (NSView *)hitTest:(NSPoint)point
{
    // Override hitTest so we can override menuForEvent.
    NSEvent *event = [NSApp currentEvent];
    NSEventType type = [event type];
    if (type == NSRightMouseDown || (type == NSLeftMouseDown && ([event modifierFlags] & NSControlKeyMask)))
        return self;

    return [super hitTest:point];
}

- (NSMenu *)menuForEvent:(NSEvent *)theEvent
{
    NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];

    NSEnumerator *menuItemEnumerator = [[[_pdfView menuForEvent:theEvent] itemArray] objectEnumerator];
    while (NSMenuItem *item = [menuItemEnumerator nextObject]) {
        NSMenuItem *itemCopy = [item copy];
        [menu addItem:itemCopy];
        [itemCopy release];

        if ([item action] != @selector(copy:))
            continue;

        // Add in an "Open with <default PDF viewer>" item
        NSString *appName = nil;
        NSImage *appIcon = nil;

        _applicationInfoForMIMEType(@"application/pdf", &appName, &appIcon);
        if (!appName)
            appName = WEB_UI_STRING("Finder", "Default application name for Open With context menu");

        // To match the PDFKit style, we'll add Open with Preview even when there's no document yet to view, and
        // disable it using validateUserInterfaceItem.
        NSString *title = [NSString stringWithFormat:WEB_UI_STRING("Open with %@", "context menu item for PDF"), appName];

        item = [[NSMenuItem alloc] initWithTitle:title action:@selector(_openWithFinder:) keyEquivalent:@""];
        if (appIcon)
            [item setImage:appIcon];
        [menu addItem:[NSMenuItem separatorItem]];
        [menu addItem:item];
        [item release];
    }

    return [menu autorelease];
}

// MARK: NSUserInterfaceValidations PROTOCOL IMPLEMENTATION

- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
{
    SEL action = [item action];
    if (action == @selector(_openWithFinder:))
        return [_pdfView document] != nil;
    return YES;
}

// MARK: PDFView delegate methods

- (void)PDFViewWillClickOnLink:(PDFView *)sender withURL:(NSURL *)URL
{
    _pdfViewController->linkClicked([URL absoluteString]);
}

- (void)PDFViewOpenPDFInNativeApplication:(PDFView *)sender
{
    _pdfViewController->openPDFInFinder();
}

- (void)PDFViewSavePDFToDownloadFolder:(PDFView *)sender
{
    _pdfViewController->savePDFToDownloadsFolder();
}

@end

namespace WebKit {

PassOwnPtr<PDFViewController> PDFViewController::create(WKView *wkView)
{
    return adoptPtr(new PDFViewController(wkView));
}

PDFViewController::PDFViewController(WKView *wkView)
    : m_wkView(wkView)
    , m_wkPDFView(AdoptNS, [[WKPDFView alloc] initWithFrame:[m_wkView bounds] PDFViewController:this])
    , m_pdfView([m_wkPDFView.get() pdfView])
    , m_hasWrittenPDFToDisk(false)
{
    [m_wkView addSubview:m_wkPDFView.get()];
}

PDFViewController::~PDFViewController()
{
    [m_wkPDFView.get() removeFromSuperview];
    [m_wkPDFView.get() invalidate];
    m_wkPDFView = nullptr;
}

WebPageProxy* PDFViewController::page() const
{
    return toImpl([m_wkView pageRef]);
}

NSView* PDFViewController::pdfView() const
{ 
    return m_wkPDFView.get(); 
}
    
static RetainPtr<CFDataRef> convertPostScriptDataSourceToPDF(const CoreIPC::DataReference& dataReference)
{
    // Convert PostScript to PDF using Quartz 2D API
    // http://developer.apple.com/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_ps_convert/chapter_16_section_1.html
    
    CGPSConverterCallbacks callbacks = { 0, 0, 0, 0, 0, 0, 0, 0 };    
    RetainPtr<CGPSConverterRef> converter(AdoptCF, CGPSConverterCreate(0, &callbacks, 0));
    ASSERT(converter);

    RetainPtr<NSData> nsData(AdoptNS, [[NSData alloc] initWithBytesNoCopy:const_cast<uint8_t*>(dataReference.data()) length:dataReference.size() freeWhenDone:NO]);   

    RetainPtr<CGDataProviderRef> provider(AdoptCF, CGDataProviderCreateWithCFData((CFDataRef)nsData.get()));
    ASSERT(provider);

    RetainPtr<CFMutableDataRef> result(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0));
    ASSERT(result);
    
    RetainPtr<CGDataConsumerRef> consumer(AdoptCF, CGDataConsumerCreateWithCFData(result.get()));
    ASSERT(consumer);
    
    CGPSConverterConvert(converter.get(), provider.get(), consumer.get(), 0);

    if (!result)
        return 0;

    return result;
}

void PDFViewController::setPDFDocumentData(const String& mimeType, const String& suggestedFilename, const CoreIPC::DataReference& dataReference)
{
    if (equalIgnoringCase(mimeType, "application/postscript")) {
        m_pdfData = convertPostScriptDataSourceToPDF(dataReference);
        if (!m_pdfData)
            return;
    } else {
        // Make sure to copy the data.
        m_pdfData.adoptCF(CFDataCreate(0, dataReference.data(), dataReference.size()));
    }

    m_suggestedFilename = suggestedFilename;

    RetainPtr<PDFDocument> pdfDocument(AdoptNS, [[pdfDocumentClass() alloc] initWithData:(NSData *)m_pdfData.get()]);
    [m_wkPDFView.get() setDocument:pdfDocument.get()];
}

double PDFViewController::zoomFactor() const
{
    return [m_pdfView scaleFactor];
}

void PDFViewController::setZoomFactor(double zoomFactor)
{
    [m_pdfView setScaleFactor:zoomFactor];
}

Class PDFViewController::pdfDocumentClass()
{
    static Class pdfDocumentClass = [pdfKitBundle() classNamed:@"PDFDocument"];
    
    return pdfDocumentClass;
}

Class PDFViewController::pdfPreviewViewClass()
{
    static Class pdfPreviewViewClass = [pdfKitBundle() classNamed:@"PDFPreviewView"];
    
    return pdfPreviewViewClass;
}
    
NSBundle* PDFViewController::pdfKitBundle()
{
    static NSBundle *pdfKitBundle;
    if (pdfKitBundle)
        return pdfKitBundle;

    NSString *pdfKitPath = [_NSPathForSystemFramework(@"Quartz.framework") stringByAppendingString:@"/Frameworks/PDFKit.framework"];
    if (!pdfKitPath) {
        LOG_ERROR("Couldn't find PDFKit.framework");
        return nil;
    }

    pdfKitBundle = [NSBundle bundleWithPath:pdfKitPath];
    if (![pdfKitBundle load])
        LOG_ERROR("Couldn't load PDFKit.framework");
    return pdfKitBundle;
}

NSPrintOperation *PDFViewController::makePrintOperation(NSPrintInfo *printInfo)
{
    return [[m_pdfView document] getPrintOperationForPrintInfo:printInfo autoRotate:YES];
}

void PDFViewController::openPDFInFinder()
{
    // We don't want to open the PDF until we have a document to write. (see 4892525).
    if (![m_pdfView document]) {
        NSBeep();
        return;
    }

    NSString *path = pathToPDFOnDisk();
    if (!path)
        return;

    if (!m_hasWrittenPDFToDisk) {
        // Create a PDF file with the minimal permissions (only accessible to the current user, see 4145714).
        RetainPtr<NSNumber> permissions(AdoptNS, [[NSNumber alloc] initWithInt:S_IRUSR]);
        RetainPtr<NSDictionary> fileAttributes(AdoptNS, [[NSDictionary alloc] initWithObjectsAndKeys:permissions.get(), NSFilePosixPermissions, nil]);

        if (![[NSFileManager defaultManager] createFileAtPath:path contents:(NSData *)m_pdfData.get() attributes:fileAttributes.get()])
            return;

        m_hasWrittenPDFToDisk = true;
    }

    [[NSWorkspace sharedWorkspace] openFile:path];
}

static void releaseCFData(unsigned char*, const void* data)
{
    ASSERT(CFGetTypeID(data) == CFDataGetTypeID());

    // Balanced by CFRetain in savePDFToDownloadsFolder.
    CFRelease(data);
}

void PDFViewController::savePDFToDownloadsFolder()
{
    // We don't want to write the file until we have a document to write. (see 5267607).
    if (![m_pdfView document]) {
        NSBeep();
        return;
    }

    ASSERT(m_pdfData);

    // Balanced by CFRelease in releaseCFData.
    CFRetain(m_pdfData.get());

    RefPtr<WebData> data = WebData::createWithoutCopying(CFDataGetBytePtr(m_pdfData.get()), CFDataGetLength(m_pdfData.get()), releaseCFData, m_pdfData.get());

    page()->saveDataToFileInDownloadsFolder(m_suggestedFilename.get(), page()->mainFrame()->mimeType(), page()->mainFrame()->url(), data.get());
}

static NSString *temporaryPDFDirectoryPath()
{
    static NSString *temporaryPDFDirectoryPath;

    if (!temporaryPDFDirectoryPath) {
        NSString *temporaryDirectoryTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"WebKitPDFs-XXXXXX"];
        CString templateRepresentation = [temporaryDirectoryTemplate fileSystemRepresentation];

        if (mkdtemp(templateRepresentation.mutableData()))
            temporaryPDFDirectoryPath = [[[NSFileManager defaultManager] stringWithFileSystemRepresentation:templateRepresentation.data() length:templateRepresentation.length()] copy];
    }

    return temporaryPDFDirectoryPath;
}

NSString *PDFViewController::pathToPDFOnDisk()
{
    if (m_pathToPDFOnDisk)
        return m_pathToPDFOnDisk.get();

    NSString *pdfDirectoryPath = temporaryPDFDirectoryPath();
    if (!pdfDirectoryPath)
        return nil;

    NSString *path = [pdfDirectoryPath stringByAppendingPathComponent:m_suggestedFilename.get()];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        NSString *pathTemplatePrefix = [pdfDirectoryPath stringByAppendingString:@"XXXXXX-"];
        NSString *pathTemplate = [pathTemplatePrefix stringByAppendingPathComponent:m_suggestedFilename.get()];
        CString pathTemplateRepresentation = [pathTemplate fileSystemRepresentation];

        int fd = mkstemps(pathTemplateRepresentation.mutableData(), pathTemplateRepresentation.length() - strlen([pathTemplatePrefix fileSystemRepresentation]) + 1);
        if (fd < 0)
            return nil;

        close(fd);
        path = [fileManager stringWithFileSystemRepresentation:pathTemplateRepresentation.data() length:pathTemplateRepresentation.length()];
    }

    m_pathToPDFOnDisk.adoptNS([path copy]);
    return path;
}

void PDFViewController::linkClicked(const String& url)
{
    NSEvent* nsEvent = [NSApp currentEvent];
    WebMouseEvent event;
    switch ([nsEvent type]) {
    case NSLeftMouseUp:
    case NSRightMouseUp:
    case NSOtherMouseUp:
        event = WebEventFactory::createWebMouseEvent(nsEvent, m_pdfView);
    default:
        // For non mouse-clicks or for keyboard events, pass an empty WebMouseEvent
        // through.  The event is only used by the WebFrameLoaderClient to determine
        // the modifier keys and which mouse button is down.  These queries will be
        // valid with an empty event.
        break;
    }
    
    page()->linkClicked(url, event);
}

void PDFViewController::findString(const String& string, FindOptions options, unsigned maxMatchCount)
{
    BOOL forward = !(options & FindOptionsBackwards);
    BOOL caseFlag = !(options & FindOptionsCaseInsensitive);
    BOOL wrapFlag = options & FindOptionsWrapAround;

    PDFSelection *selection = [m_wkPDFView.get() _nextMatchFor:string direction:forward caseSensitive:caseFlag wrap:wrapFlag fromSelection:[m_pdfView currentSelection] startInSelection:NO];
    NSUInteger matchCount = [m_wkPDFView.get() _countMatches:string caseSensitive:caseFlag];
    if (matchCount > maxMatchCount)
        matchCount = maxMatchCount;

    if (!selection) {
        page()->didFailToFindString(string);
        return;
    }

    [m_pdfView setCurrentSelection:selection];
    [m_pdfView scrollSelectionToVisible:nil];
    page()->didFindString(string, matchCount);
}

void PDFViewController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
{
    BOOL caseFlag = !(options & FindOptionsCaseInsensitive);

    NSUInteger matchCount = [m_wkPDFView.get() _countMatches:string caseSensitive:caseFlag];
    if (matchCount > maxMatchCount)
        matchCount = maxMatchCount;
    page()->didCountStringMatches(string, matchCount);
}

} // namespace WebKit
