/*
 * Copyright (C) 2007, 2009, 2012-2020 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. ``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
 * 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 "DragImage.h"

#if ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)

#import "BitmapImage.h"
#import "ColorMac.h"
#import "Element.h"
#import "FloatRoundedRect.h"
#import "FontCascade.h"
#import "FontDescription.h"
#import "FontSelector.h"
#import "GraphicsContext.h"
#import "Image.h"
#import "LocalDefaultSystemAppearance.h"
#import "Page.h"
#import "StringTruncator.h"
#import "TextIndicator.h"
#import "WebKitNSImageExtras.h"
#import <pal/spi/cg/CoreGraphicsSPI.h>
#import <pal/spi/cocoa/CoreTextSPI.h>
#import <pal/spi/cocoa/URLFormattingSPI.h>
#import <wtf/SoftLinking.h>
#import <wtf/URL.h>

#if !HAVE(URL_FORMATTING)
SOFT_LINK_PRIVATE_FRAMEWORK_OPTIONAL(LinkPresentation)
#endif

namespace WebCore {

IntSize dragImageSize(RetainPtr<NSImage> image)
{
    return (IntSize)[image size];
}

void deleteDragImage(RetainPtr<NSImage>)
{
    // Since this is a RetainPtr, there's nothing additional we need to do to
    // delete it. It will be released when it falls out of scope.
}

RetainPtr<NSImage> scaleDragImage(RetainPtr<NSImage> image, FloatSize scale)
{
    NSSize originalSize = [image size];
    NSSize newSize = NSMakeSize((originalSize.width * scale.width()), (originalSize.height * scale.height()));
    newSize.width = roundf(newSize.width);
    newSize.height = roundf(newSize.height);
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    [image setScalesWhenResized:YES];
    ALLOW_DEPRECATED_DECLARATIONS_END
    [image setSize:newSize];
    return image;
}
    
RetainPtr<NSImage> dissolveDragImageToFraction(RetainPtr<NSImage> image, float delta)
{
    if (!image)
        return nil;

    RetainPtr<NSImage> dissolvedImage = adoptNS([[NSImage alloc] initWithSize:[image size]]);
    
    [dissolvedImage lockFocus];
    [image drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, [image size].width, [image size].height) operation:NSCompositingOperationCopy fraction:delta];
    [dissolvedImage unlockFocus];

    return dissolvedImage;
}

RetainPtr<NSImage> createDragImageFromImage(Image* image, ImageOrientation orientation)
{
    if (is<BitmapImage>(*image)) {
        BitmapImage& bitmapImage = downcast<BitmapImage>(*image);

        if (orientation == ImageOrientation::FromImage)
            orientation = bitmapImage.orientationForCurrentFrame();

        if (orientation != ImageOrientation::None) {
            // Construct a correctly-rotated copy of the image to use as the drag image.
            FloatSize imageSize = image->size(orientation);
            RetainPtr<NSImage> rotatedDragImage = adoptNS([[NSImage alloc] initWithSize:(NSSize)(imageSize)]);
            [rotatedDragImage lockFocus];

            // ImageOrientation uses top-left coordinates, need to flip to bottom-left, apply...
            CGAffineTransform transform = CGAffineTransformMakeTranslation(0, imageSize.height());
            transform = CGAffineTransformScale(transform, 1, -1);
            transform = CGAffineTransformConcat(orientation.transformFromDefault(imageSize), transform);

            if (orientation.usesWidthAsHeight())
                imageSize = imageSize.transposedSize();

            // ...and flip back.
            transform = CGAffineTransformTranslate(transform, 0, imageSize.height());
            transform = CGAffineTransformScale(transform, 1, -1);

            RetainPtr<NSAffineTransform> cocoaTransform = adoptNS([[NSAffineTransform alloc] init]);
            [cocoaTransform setTransformStruct:*(NSAffineTransformStruct*)&transform];
            [cocoaTransform concat];

            FloatRect imageRect(FloatPoint(), imageSize);
            [image->snapshotNSImage() drawInRect:imageRect fromRect:imageRect operation:NSCompositingOperationSourceOver fraction:1.0];

            [rotatedDragImage unlockFocus];

            return rotatedDragImage;
        }
    }

    FloatSize imageSize = image->size();
    auto dragImage = image->snapshotNSImage();
    [dragImage setSize:(NSSize)imageSize];
    return dragImage;
}
    
RetainPtr<NSImage> createDragImageIconForCachedImageFilename(const String& filename)
{
    NSString *extension = nil;
    size_t dotIndex = filename.reverseFind('.');
    
    if (dotIndex != notFound && dotIndex < (filename.length() - 1)) // require that a . exists after the first character and before the last
        extension = filename.substring(dotIndex + 1);
    else {
        // It might be worth doing a further lookup to pull the extension from the MIME type.
        extension = @"";
    }
    
    return [[NSWorkspace sharedWorkspace] iconForFileType:extension];
}

const CGFloat linkImagePadding = 10;
const CGFloat linkImageDomainBaselineToTitleBaseline = 18;
const CGFloat linkImageCornerRadius = 5;
const CGFloat linkImageMaximumWidth = 400;
const CGFloat linkImageFontSize = 11;
const CFIndex linkImageTitleMaximumLineCount = 2;
const int linkImageShadowRadius = 0;
const int linkImageShadowOffsetY = 0;
const int linkImageDragCornerOutsetX = 6 - linkImageShadowRadius;
const int linkImageDragCornerOutsetY = 10 - linkImageShadowRadius + linkImageShadowOffsetY;

IntPoint dragOffsetForLinkDragImage(DragImageRef dragImage)
{
    IntSize size = dragImageSize(dragImage);
    return { linkImageDragCornerOutsetX, size.height() + linkImageDragCornerOutsetY };
}

FloatPoint anchorPointForLinkDragImage(DragImageRef dragImage)
{
    IntSize size = dragImageSize(dragImage);
    return { -static_cast<float>(linkImageDragCornerOutsetX) / size.width(), -static_cast<float>(linkImageDragCornerOutsetY) / size.height() };
}

struct LinkImageLayout {
    LinkImageLayout(URL&, const String& title);

    struct Label {
        FloatPoint origin;
        RetainPtr<CTFrameRef> frame;
    };
    Vector<Label> labels;

    FloatRect boundingRect;
};

LinkImageLayout::LinkImageLayout(URL& url, const String& titleString)
{
    NSString *title = nsStringNilIfEmpty(titleString);
    NSURL *cocoaURL = url;
    NSString *absoluteURLString = [cocoaURL absoluteString];

    NSString *domain = absoluteURLString;
#if HAVE(URL_FORMATTING)
    domain = [cocoaURL _lp_simplifiedDisplayString];
#else
    if (LinkPresentationLibrary())
        domain = [cocoaURL _lp_simplifiedDisplayString];
#endif

    if ([title isEqualToString:absoluteURLString])
        title = nil;

    NSFont *titleFont = [NSFont boldSystemFontOfSize:linkImageFontSize];
    NSFont *domainFont = [NSFont systemFontOfSize:linkImageFontSize];

    NSColor *titleColor = [NSColor labelColor];
    NSColor *domainColor = [NSColor secondaryLabelColor];

    CGFloat maximumAvailableWidth = linkImageMaximumWidth - linkImagePadding * 2;

    CGFloat currentY = linkImagePadding;
    CGFloat maximumUsedTextWidth = 0;

    auto buildLines = [this, maximumAvailableWidth, &maximumUsedTextWidth, &currentY] (NSString *text, NSColor *color, NSFont *font, CFIndex maximumLines, CTLineBreakMode lineBreakMode) {
        CTParagraphStyleSetting paragraphStyleSettings[1];
        paragraphStyleSettings[0].spec = kCTParagraphStyleSpecifierLineBreakMode;
        paragraphStyleSettings[0].valueSize = sizeof(CTLineBreakMode);
        paragraphStyleSettings[0].value = &lineBreakMode;
        RetainPtr<CTParagraphStyleRef> paragraphStyle = adoptCF(CTParagraphStyleCreate(paragraphStyleSettings, 1));

        NSDictionary *textAttributes = @{
            (id)kCTFontAttributeName: font,
            (id)kCTForegroundColorAttributeName: color,
            (id)kCTParagraphStyleAttributeName: (id)paragraphStyle.get()
        };
        NSDictionary *frameAttributes = @{
            (id)kCTFrameMaximumNumberOfLinesAttributeName: @(maximumLines)
        };

        RetainPtr<NSAttributedString> attributedText = adoptNS([[NSAttributedString alloc] initWithString:text attributes:textAttributes]);
        RetainPtr<CTFramesetterRef> textFramesetter = adoptCF(CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedText.get()));

        CFRange fitRange;
        CGSize textSize = CTFramesetterSuggestFrameSizeWithConstraints(textFramesetter.get(), CFRangeMake(0, 0), (CFDictionaryRef)frameAttributes, CGSizeMake(maximumAvailableWidth, CGFLOAT_MAX), &fitRange);

        RetainPtr<CGPathRef> textPath = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, textSize.width, textSize.height), nullptr));
        RetainPtr<CTFrameRef> textFrame = adoptCF(CTFramesetterCreateFrame(textFramesetter.get(), fitRange, textPath.get(), (CFDictionaryRef)frameAttributes));

        CFArrayRef ctLines = CTFrameGetLines(textFrame.get());
        CFIndex lineCount = CFArrayGetCount(ctLines);
        if (!lineCount)
            return;

        Vector<CGPoint> origins(lineCount);
        CGRect lineBounds;
        CGFloat height = 0;
        CTFrameGetLineOrigins(textFrame.get(), CFRangeMake(0, 0), origins.data());
        for (CFIndex lineIndex = 0; lineIndex < lineCount; ++lineIndex) {
            CTLineRef line = (CTLineRef)CFArrayGetValueAtIndex(ctLines, lineIndex);

            lineBounds = CTLineGetBoundsWithOptions(line, 0);
            CGFloat trailingWhitespaceWidth = CTLineGetTrailingWhitespaceWidth(line);
            CGFloat lineWidthIgnoringTrailingWhitespace = lineBounds.size.width - trailingWhitespaceWidth;
            maximumUsedTextWidth = std::max(maximumUsedTextWidth, lineWidthIgnoringTrailingWhitespace);

            if (lineIndex)
                height += origins[lineIndex - 1].y - origins[lineIndex].y;
        }

        LinkImageLayout::Label label;
        label.frame = textFrame;
        label.origin = FloatPoint(linkImagePadding, currentY + origins[0].y);
        labels.append(label);

        currentY += height + lineBounds.size.height;
    };

    if (title)
        buildLines(title, titleColor, titleFont, linkImageTitleMaximumLineCount, kCTLineBreakByTruncatingTail);

    if (title && domain)
        currentY += linkImageDomainBaselineToTitleBaseline - (domainFont.ascender - domainFont.descender);

    if (domain)
        buildLines(domain, domainColor, domainFont, 1, kCTLineBreakByTruncatingMiddle);

    currentY += linkImagePadding;

    boundingRect = FloatRect(0, 0, maximumUsedTextWidth + linkImagePadding * 2, currentY);

    // To work around blurry drag images on 1x displays, make the width and height a multiple of 2.
    // FIXME: remove this workaround when <rdar://problem/33059739> is fixed.
    boundingRect.setWidth((static_cast<int>(boundingRect.width()) / 2) * 2);
    boundingRect.setHeight((static_cast<int>(boundingRect.height() / 2) * 2));
}

DragImageRef createDragImageForLink(Element& element, URL& url, const String& title, TextIndicatorData&, FontRenderingMode, float deviceScaleFactor)
{
    LinkImageLayout layout(url, title);

    LocalDefaultSystemAppearance localAppearance(element.document().useDarkAppearance(element.computedStyle()));

    auto imageSize = layout.boundingRect.size();
    RetainPtr<NSImage> dragImage = adoptNS([[NSImage alloc] initWithSize:imageSize]);
    [dragImage _web_lockFocusWithDeviceScaleFactor:deviceScaleFactor];

    GraphicsContext context([NSGraphicsContext currentContext].CGContext);

    context.fillRoundedRect(FloatRoundedRect(layout.boundingRect, FloatRoundedRect::Radii(linkImageCornerRadius)), colorFromNSColor([NSColor controlBackgroundColor]));

    for (const auto& label : layout.labels) {
        GraphicsContextStateSaver saver(context);
        context.translate(label.origin.x(), layout.boundingRect.height() - label.origin.y() - linkImagePadding);
        CTFrameDraw(label.frame.get(), context.platformContext());
    }

    [dragImage unlockFocus];

    return dragImage;
}

DragImageRef createDragImageForColor(const Color& color, const FloatRect&, float, Path&)
{
    auto dragImage = adoptNS([[NSImage alloc] initWithSize:NSMakeSize(ColorSwatchWidth, ColorSwatchWidth)]);

    [dragImage lockFocus];

    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(0, 0, ColorSwatchWidth, ColorSwatchWidth) xRadius:ColorSwatchCornerRadius yRadius:ColorSwatchCornerRadius];
    [path setLineWidth:ColorSwatchStrokeSize];

    [nsColor(color) setFill];
    [path fill];

    [[NSColor quaternaryLabelColor] setStroke];
    [path stroke];

    [dragImage unlockFocus];

    return dragImage;
}

} // namespace WebCore

#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)
