/*
 * Copyright (C) 2013 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDERS AND 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 THE
 * COPYRIGHT HOLDER 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.
 */

#include "sky/engine/config.h"

#include "sky/engine/platform/geometry/FloatRoundedRect.h"

#include <gtest/gtest.h>

using namespace blink;

namespace blink {

void PrintTo(const FloatSize& size, std::ostream* os)
{
    *os << "FloatSize("
        << size.width() << ", "
        << size.height() << ")";
}

void PrintTo(const FloatRect& rect, std::ostream* os)
{
    *os << "FloatRect("
        << rect.x() << ", "
        << rect.y() << ", "
        << rect.width() << ", "
        << rect.height() << ")";
}

void PrintTo(const FloatRoundedRect::Radii& radii, std::ostream* os)
{
    *os << "FloatRoundedRect::Radii("
        << ::testing::PrintToString(radii.topLeft()) << ", "
        << ::testing::PrintToString(radii.topRight()) << ", "
        << ::testing::PrintToString(radii.bottomRight()) << ", "
        << ::testing::PrintToString(radii.bottomLeft()) << ")";
}

void PrintTo(const FloatRoundedRect& roundedRect, std::ostream* os)
{
    *os << "FloatRoundedRect("
        << ::testing::PrintToString(roundedRect.rect()) << ", "
        << ::testing::PrintToString(roundedRect.radii()) << ")";
}

} // namespace blink

namespace {

#define TEST_INTERCEPTS(roundedRect, yCoordinate, expectedMinXIntercept, expectedMaxXIntercept) \
{                                                                                               \
    float minXIntercept;                                                                        \
    float maxXIntercept;                                                                        \
    EXPECT_TRUE(roundedRect.xInterceptsAtY(yCoordinate, minXIntercept, maxXIntercept));         \
    EXPECT_FLOAT_EQ(expectedMinXIntercept, minXIntercept);                                      \
    EXPECT_FLOAT_EQ(expectedMaxXIntercept, maxXIntercept);                                      \
}

TEST(FloatRoundedRectTest, zeroRadii)
{
    FloatRoundedRect r = FloatRoundedRect(1, 2, 3, 4);

    EXPECT_EQ(FloatRect(1, 2, 3, 4), r.rect());
    EXPECT_EQ(FloatSize(), r.radii().topLeft());
    EXPECT_EQ(FloatSize(), r.radii().topRight());
    EXPECT_EQ(FloatSize(), r.radii().bottomLeft());
    EXPECT_EQ(FloatSize(), r.radii().bottomRight());
    EXPECT_TRUE(r.radii().isZero());
    EXPECT_FALSE(r.isRounded());
    EXPECT_FALSE(r.isEmpty());

    EXPECT_EQ(FloatRect(1, 2, 0, 0), r.topLeftCorner());
    EXPECT_EQ(FloatRect(4, 2, 0, 0), r.topRightCorner());
    EXPECT_EQ(FloatRect(4, 6, 0, 0), r.bottomRightCorner());
    EXPECT_EQ(FloatRect(1, 6, 0, 0), r.bottomLeftCorner());

    TEST_INTERCEPTS(r, 2, r.rect().x(), r.rect().maxX());
    TEST_INTERCEPTS(r, 4, r.rect().x(), r.rect().maxX());
    TEST_INTERCEPTS(r, 6, r.rect().x(), r.rect().maxX());

    float minXIntercept;
    float maxXIntercept;

    EXPECT_FALSE(r.xInterceptsAtY(1, minXIntercept, maxXIntercept));
    EXPECT_FALSE(r.xInterceptsAtY(7, minXIntercept, maxXIntercept));

    // The FloatRoundedRect::expandRadii() function doesn't change radii FloatSizes that
    // are <= zero. Same as RoundedRect::expandRadii().
    r.expandRadii(20);
    r.shrinkRadii(10);
    EXPECT_TRUE(r.radii().isZero());
}

TEST(FloatRoundedRectTest, circle)
{
    FloatSize cornerRadii(50, 50);
    FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii, cornerRadii, cornerRadii, cornerRadii);

    EXPECT_EQ(FloatRect(0, 0, 100, 100), r.rect());
    EXPECT_EQ(cornerRadii, r.radii().topLeft());
    EXPECT_EQ(cornerRadii, r.radii().topRight());
    EXPECT_EQ(cornerRadii, r.radii().bottomLeft());
    EXPECT_EQ(cornerRadii, r.radii().bottomRight());
    EXPECT_FALSE(r.radii().isZero());
    EXPECT_TRUE(r.isRounded());
    EXPECT_FALSE(r.isEmpty());

    EXPECT_EQ(FloatRect(0, 0, 50, 50), r.topLeftCorner());
    EXPECT_EQ(FloatRect(50, 0, 50, 50), r.topRightCorner());
    EXPECT_EQ(FloatRect(0, 50, 50, 50), r.bottomLeftCorner());
    EXPECT_EQ(FloatRect(50, 50, 50, 50), r.bottomRightCorner());

    TEST_INTERCEPTS(r, 0, 50, 50);
    TEST_INTERCEPTS(r, 25, 6.69873, 93.3013);
    TEST_INTERCEPTS(r, 50, 0, 100);
    TEST_INTERCEPTS(r, 75, 6.69873, 93.3013);
    TEST_INTERCEPTS(r, 100, 50, 50);

    float minXIntercept;
    float maxXIntercept;

    EXPECT_FALSE(r.xInterceptsAtY(-1, minXIntercept, maxXIntercept));
    EXPECT_FALSE(r.xInterceptsAtY(101, minXIntercept, maxXIntercept));
}

/*
 * FloatRoundedRect geometry for this test. Corner radii are in parens, x and y intercepts
 * for the elliptical corners are noted. The rectangle itself is at 0,0 with width and height 100.
 *
 *         (10, 15)  x=10      x=90 (10, 20)
 *                (--+---------+--)
 *           y=15 +--|         |-+ y=20
 *                |               |
 *                |               |
 *           y=85 + -|         |- + y=70
 *                (--+---------+--)
 *       (25, 15)  x=25      x=80  (20, 30)
 */
TEST(FloatRoundedRectTest, ellipticalCorners)
{
    FloatSize cornerSize(10, 20);
    FloatRoundedRect::Radii cornerRadii;
    cornerRadii.setTopLeft(FloatSize(10, 15));
    cornerRadii.setTopRight(FloatSize(10, 20));
    cornerRadii.setBottomLeft(FloatSize(25, 15));
    cornerRadii.setBottomRight(FloatSize(20, 30));

    FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii);

    EXPECT_EQ(r.radii(), FloatRoundedRect::Radii(FloatSize(10, 15), FloatSize(10, 20), FloatSize(25, 15), FloatSize(20, 30)));
    EXPECT_EQ(r, FloatRoundedRect(FloatRect(0, 0, 100, 100), cornerRadii));

    EXPECT_EQ(FloatRect(0, 0, 10, 15), r.topLeftCorner());
    EXPECT_EQ(FloatRect(90, 0, 10, 20), r.topRightCorner());
    EXPECT_EQ(FloatRect(0, 85, 25, 15), r.bottomLeftCorner());
    EXPECT_EQ(FloatRect(80, 70, 20, 30), r.bottomRightCorner());

    TEST_INTERCEPTS(r, 5, 2.5464401, 96.61438);
    TEST_INTERCEPTS(r, 15, 0, 99.682457);
    TEST_INTERCEPTS(r, 20, 0, 100);
    TEST_INTERCEPTS(r, 50, 0, 100);
    TEST_INTERCEPTS(r, 70, 0, 100);
    TEST_INTERCEPTS(r, 85, 0, 97.320511);
    TEST_INTERCEPTS(r, 95, 6.3661003, 91.05542);

    float minXIntercept;
    float maxXIntercept;

    EXPECT_FALSE(r.xInterceptsAtY(-1, minXIntercept, maxXIntercept));
    EXPECT_FALSE(r.xInterceptsAtY(101, minXIntercept, maxXIntercept));
}

} // namespace

