/*
 * Copyright (C) 2006, 2008 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE 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 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 "WebNodeHighlightView.h"
#import "WebNodeHighlight.h"

#import <WebCore/GraphicsContextCG.h>
#import <WebCore/InspectorController.h>
#import <wtf/Assertions.h>

#if PLATFORM(IOS_FAMILY)
#import <CoreGraphics/CoreGraphics.h>
#import <WebCore/FloatQuad.h>
#import <WebCore/GeometryUtilities.h>
#import <WebCore/InspectorOverlay.h>
#import <WebCore/WebCoreThread.h>
#endif

using namespace WebCore;

@implementation WebNodeHighlightView

#if PLATFORM(IOS_FAMILY)
- (void)_removeAllLayers
{
    for (CAShapeLayer *layer in _layers)
        [layer removeFromSuperlayer];
    [_layers removeAllObjects];
}
#endif

- (id)initWithWebNodeHighlight:(WebNodeHighlight *)webNodeHighlight
{
    self = [self initWithFrame:NSZeroRect];
    if (!self)
        return nil;

    _webNodeHighlight = [webNodeHighlight retain];

#if PLATFORM(IOS_FAMILY)
    _layers = [[NSMutableArray alloc] init];
#endif

    return self;
}

- (void)dealloc
{
    [self detachFromWebNodeHighlight];
#if PLATFORM(IOS_FAMILY)
    [self _removeAllLayers];
    [_layers release];
#endif
    [super dealloc];
}

- (void)detachFromWebNodeHighlight
{
    [_webNodeHighlight release];
    _webNodeHighlight = nil;
}

- (BOOL)isFlipped
{
    return YES;
}

#if !PLATFORM(IOS_FAMILY)
- (void)drawRect:(NSRect)rect 
{
    if (_webNodeHighlight) {
        [NSGraphicsContext saveGraphicsState];

        ASSERT([[NSGraphicsContext currentContext] isFlipped]);

        GraphicsContextCG context([[NSGraphicsContext currentContext] CGContext]);
        [_webNodeHighlight inspectorController]->drawHighlight(context);
        [NSGraphicsContext restoreGraphicsState];
    }
}
#else
- (void)_attach:(CALayer *)parent numLayers:(NSUInteger)numLayers
{
    ASSERT(numLayers);

    // We have the right layers and they are all parented correctly.
    if ([_layers count] == numLayers && [[_layers objectAtIndex:0] superlayer] == parent)
        return;

    // Remove and create new layers.
    [self _removeAllLayers];
    for (NSUInteger i = 0; i < numLayers; ++i) {
        auto layer = adoptNS([[CAShapeLayer alloc] init]);
        [_layers addObject:layer.get()];
        [parent addSublayer:layer.get()];
    }
}

static bool findIntersectionOnLineBetweenPoints(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& d1, const FloatPoint& d2, FloatPoint& intersection) 
{
    // Do the lines intersect?
    FloatPoint temporaryIntersectionPoint;
    if (!findIntersection(p1, p2, d1, d2, temporaryIntersectionPoint))
        return false;

    // Is the intersection between the two points on the line?
    if (p1.x() >= p2.x()) {
        if (temporaryIntersectionPoint.x() > p1.x() || temporaryIntersectionPoint.x() < p2.x())
            return false;
    } else {
        if (temporaryIntersectionPoint.x() > p2.x() || temporaryIntersectionPoint.x() < p1.x())
            return false;
    }
    if (p1.y() >= p2.y()) {
        if (temporaryIntersectionPoint.y() > p1.y() || temporaryIntersectionPoint.y() < p2.y())
            return false;
    } else {
        if (temporaryIntersectionPoint.y() > p2.y() || temporaryIntersectionPoint.y() < p1.y())
            return false;
    }

    intersection = temporaryIntersectionPoint;
    return true;
}

// This quad intersection works because the two quads are known to be at the same
// rotation and clockwise-ness.
static FloatQuad quadIntersection(FloatQuad bounds, FloatQuad toClamp)
{
    // Resulting points.
    FloatPoint p1, p2, p3, p4;
    bool containsPoint1 = false;
    bool containsPoint2 = false;
    bool containsPoint3 = false;
    bool containsPoint4 = false;
    bool intersectForPoint1 = false;
    bool intersectForPoint2 = false;
    bool intersectForPoint3 = false;
    bool intersectForPoint4 = false;

    // Top / bottom vertical clamping.
    if (bounds.containsPoint(toClamp.p1())) {
        containsPoint1 = true;
        p1 = toClamp.p1();
    } else if (!(intersectForPoint1 = findIntersectionOnLineBetweenPoints(bounds.p1(), bounds.p2(), toClamp.p1(), toClamp.p4(), p1)))
        p1 = toClamp.p1();

    if (bounds.containsPoint(toClamp.p2())) {
        containsPoint2 = true;
        p2 = toClamp.p2();
    } else if (!(intersectForPoint2 = findIntersectionOnLineBetweenPoints(bounds.p1(), bounds.p2(), toClamp.p2(), toClamp.p3(), p2)))
        p2 = toClamp.p2();

    if (bounds.containsPoint(toClamp.p3())) {
        containsPoint3 = true;
        p3 = toClamp.p3();
    } else if (!(intersectForPoint3 = findIntersectionOnLineBetweenPoints(bounds.p4(), bounds.p3(), toClamp.p2(), toClamp.p3(), p3)))
        p3 = toClamp.p3();

    if (bounds.containsPoint(toClamp.p4())) {
        containsPoint4 = true;
        p4 = toClamp.p4();
    } else if (!(intersectForPoint4 = findIntersectionOnLineBetweenPoints(bounds.p4(), bounds.p3(), toClamp.p1(), toClamp.p4(), p4)))
        p4 = toClamp.p4();

    // If only one of the points intersected on either the top or bottom line then we
    // can clamp the other point on that line to the corner of the bounds.
    if (!containsPoint1 && intersectForPoint2 && !intersectForPoint1) {
        containsPoint1 = true;
        p1 = bounds.p1();
    } else if (!containsPoint2 && intersectForPoint1 && !intersectForPoint2) {
        containsPoint2 = true;
        p2 = bounds.p2();
    }
    if (!containsPoint4 && intersectForPoint3 && !intersectForPoint4) {
        containsPoint4 = true;
        p4 = bounds.p4();
    } else if (!containsPoint3 && intersectForPoint4 && !intersectForPoint3) {
        containsPoint3 = true;
        p3 = bounds.p3();
    }

    // Now we only need to perform horizontal clamping for unadjusted points.
    if (!containsPoint2 && !intersectForPoint2)
        findIntersectionOnLineBetweenPoints(bounds.p2(), bounds.p3(), p1, p2, p2);
    if (!containsPoint3 && !intersectForPoint3)
        findIntersectionOnLineBetweenPoints(bounds.p2(), bounds.p3(), p4, p3, p3);
    if (!containsPoint1 && !intersectForPoint1)
        findIntersectionOnLineBetweenPoints(bounds.p1(), bounds.p4(), p1, p2, p1);
    if (!containsPoint4 && !intersectForPoint4)
        findIntersectionOnLineBetweenPoints(bounds.p1(), bounds.p4(), p4, p3, p4);

    return FloatQuad(p1, p2, p3, p4);
}

static void layerPathWithHole(CAShapeLayer *layer, const FloatQuad& outerQuad, const FloatQuad& holeQuad)
{
    // Nothing to show.
    if (outerQuad == holeQuad || holeQuad.containsQuad(outerQuad)) {
        layer.path = NULL;
        return;
    }

    // If there is a negative margin / padding then the outer box might not
    // fully contain the hole box. In such cases we recalculate the hole to
    // be the intersection of the two quads.
    FloatQuad innerHole;
    if (outerQuad.containsQuad(holeQuad))
        innerHole = holeQuad;
    else
        innerHole = quadIntersection(outerQuad, holeQuad);

    // Clockwise inside rect (hole), Counter-Clockwise outside rect (fill).
    auto path = adoptCF(CGPathCreateMutable());
    CGPathMoveToPoint(path.get(), 0, innerHole.p1().x(), innerHole.p1().y());
    CGPathAddLineToPoint(path.get(), 0, innerHole.p2().x(), innerHole.p2().y());
    CGPathAddLineToPoint(path.get(), 0, innerHole.p3().x(), innerHole.p3().y());
    CGPathAddLineToPoint(path.get(), 0, innerHole.p4().x(), innerHole.p4().y());
    CGPathMoveToPoint(path.get(), 0, outerQuad.p1().x(), outerQuad.p1().y());
    CGPathAddLineToPoint(path.get(), 0, outerQuad.p4().x(), outerQuad.p4().y());
    CGPathAddLineToPoint(path.get(), 0, outerQuad.p3().x(), outerQuad.p3().y());
    CGPathAddLineToPoint(path.get(), 0, outerQuad.p2().x(), outerQuad.p2().y());
    layer.path = path.get();
}

static void layerPath(CAShapeLayer *layer, const FloatQuad& outerQuad)
{
    auto path = adoptCF(CGPathCreateMutable());
    CGPathMoveToPoint(path.get(), 0, outerQuad.p1().x(), outerQuad.p1().y());
    CGPathAddLineToPoint(path.get(), 0, outerQuad.p4().x(), outerQuad.p4().y());
    CGPathAddLineToPoint(path.get(), 0, outerQuad.p3().x(), outerQuad.p3().y());
    CGPathAddLineToPoint(path.get(), 0, outerQuad.p2().x(), outerQuad.p2().y());
    layer.path = path.get();
}

- (void)_layoutForNodeHighlight:(InspectorOverlay::Highlight*)highlight parent:(CALayer *)parentLayer
{
    if (!highlight->quads.size()) {
        [self _removeAllLayers];
        return;
    }

    [self _attach:parentLayer numLayers:4];

    CAShapeLayer *marginLayer = [_layers objectAtIndex:0];
    CAShapeLayer *borderLayer = [_layers objectAtIndex:1];
    CAShapeLayer *paddingLayer = [_layers objectAtIndex:2];
    CAShapeLayer *contentLayer = [_layers objectAtIndex:3];

    FloatQuad marginQuad = highlight->quads[0];
    FloatQuad borderQuad = highlight->quads[1];
    FloatQuad paddingQuad = highlight->quads[2];
    FloatQuad contentQuad = highlight->quads[3];

    marginLayer.fillColor = cachedCGColor(highlight->marginColor);
    borderLayer.fillColor = cachedCGColor(highlight->borderColor);
    paddingLayer.fillColor = cachedCGColor(highlight->paddingColor);
    contentLayer.fillColor = cachedCGColor(highlight->contentColor);

    layerPathWithHole(marginLayer, marginQuad, borderQuad);
    layerPathWithHole(borderLayer, borderQuad, paddingQuad);
    layerPathWithHole(paddingLayer, paddingQuad, contentQuad);
    layerPath(contentLayer, contentQuad);
}

- (void)_layoutForRectsHighlight:(InspectorOverlay::Highlight*)highlight parent:(CALayer *)parentLayer
{
    NSUInteger numLayers = highlight->quads.size();
    if (!numLayers) {
        [self _removeAllLayers];
        return;
    }

    [self _attach:parentLayer numLayers:numLayers];

    CGColorRef contentColor = cachedCGColor(highlight->contentColor);
    for (NSUInteger i = 0; i < numLayers; ++i) {
        CAShapeLayer *layer = [_layers objectAtIndex:i];
        layer.fillColor = contentColor;
        layerPath(layer, highlight->quads[i]);
    }
}

- (void)layoutSublayers:(CALayer *)parentLayer
{
    if (!_webNodeHighlight)
        return;

    WebThreadLock();

    if (![_webNodeHighlight inspectorController])
        return;

    InspectorOverlay::Highlight h;
    [_webNodeHighlight inspectorController]->getHighlight(h, InspectorOverlay::CoordinateSystem::View);

    if (h.type == InspectorOverlay::Highlight::Type::Node)
        [self _layoutForNodeHighlight:&h parent:parentLayer];
    else if (h.type == InspectorOverlay::Highlight::Type::Rects)
        [self _layoutForRectsHighlight:&h parent:parentLayer];
}
#endif

- (WebNodeHighlight *)webNodeHighlight
{
    return _webNodeHighlight;
}

@end
