/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkPathOpsBounds.h"
#include "Test.h"

static const SkRect sectTests[][2] = {
    {{2, 0, 4, 1}, {4, 0, 6, 1}},
    {{2, 0, 4, 1}, {3, 0, 5, 1}},
    {{2, 0, 4, 1}, {3, 0, 5, 0}},
    {{2, 0, 4, 1}, {3, 1, 5, 2}},
    {{2, 1, 4, 2}, {1, 0, 5, 3}},
    {{2, 1, 5, 3}, {3, 1, 4, 2}},
    {{2, 0, 4, 1}, {3, 0, 3, 0}},  // intersecting an empty bounds is OK
    {{2, 0, 4, 1}, {4, 1, 5, 2}},  // touching just on a corner is OK
};

static const size_t sectTestsCount = SK_ARRAY_COUNT(sectTests);

static const SkRect noSectTests[][2] = {
    {{2, 0, 4, 1}, {5, 0, 6, 1}},
    {{2, 0, 4, 1}, {3, 2, 5, 2}},
};

static const size_t noSectTestsCount = SK_ARRAY_COUNT(noSectTests);

static const SkRect reallyEmpty[] = {
    {0, 0, 0, 0},
    {1, 1, 1, 0},
    {1, 1, 0, 1},
    {1, 1, 0, 0},
    {1, 2, 3, SK_ScalarNaN},
};

static const size_t emptyTestsCount = SK_ARRAY_COUNT(reallyEmpty);

static const SkRect notReallyEmpty[] = {
    {0, 0, 1, 0},
    {0, 0, 0, 1},
    {0, 0, 1, 1},
};

static const size_t notEmptyTestsCount = SK_ARRAY_COUNT(notReallyEmpty);

static void PathOpsBoundsTest(skiatest::Reporter* reporter) {
    for (size_t index = 0; index < sectTestsCount; ++index) {
        const SkPathOpsBounds& bounds1 = static_cast<const SkPathOpsBounds&>(sectTests[index][0]);
        const SkPathOpsBounds& bounds2 = static_cast<const SkPathOpsBounds&>(sectTests[index][1]);
        bool touches = SkPathOpsBounds::Intersects(bounds1, bounds2);
        REPORTER_ASSERT(reporter, touches);
    }
    for (size_t index = 0; index < noSectTestsCount; ++index) {
        const SkPathOpsBounds& bounds1 = static_cast<const SkPathOpsBounds&>(noSectTests[index][0]);
        const SkPathOpsBounds& bounds2 = static_cast<const SkPathOpsBounds&>(noSectTests[index][1]);
        bool touches = SkPathOpsBounds::Intersects(bounds1, bounds2);
        REPORTER_ASSERT(reporter, !touches);
    }
    SkPathOpsBounds bounds;
    bounds.setEmpty();
    bounds.add(1, 2, 3, 4);
    SkPathOpsBounds expected;
    expected.set(0, 0, 3, 4);
    REPORTER_ASSERT(reporter, bounds == expected);
    bounds.setEmpty();
    SkPathOpsBounds ordinal;
    ordinal.set(1, 2, 3, 4);
    bounds.add(ordinal);
    REPORTER_ASSERT(reporter, bounds == expected);
    SkPoint topLeft = {0, 0};
    bounds.setPointBounds(topLeft);
    SkPoint botRight = {3, 4};
    bounds.add(botRight);
    REPORTER_ASSERT(reporter, bounds == expected);
    for (size_t index = 0; index < emptyTestsCount; ++index) {
        const SkPathOpsBounds& bounds = static_cast<const SkPathOpsBounds&>(reallyEmpty[index]);
        bool empty = bounds.isReallyEmpty();
        REPORTER_ASSERT(reporter, empty);
    }
    for (size_t index = 0; index < notEmptyTestsCount; ++index) {
        const SkPathOpsBounds& bounds = static_cast<const SkPathOpsBounds&>(notReallyEmpty[index]);
        bool empty = bounds.isReallyEmpty();
        REPORTER_ASSERT(reporter, !empty);
    }
    const SkPoint curvePts[] = {{0, 0}, {1, 2}, {3, 4}, {5, 6}};
    bounds.setLineBounds(curvePts);
    expected.set(0, 0, 1, 2);
    REPORTER_ASSERT(reporter, bounds == expected);
    (bounds.*SetCurveBounds[1])(curvePts);
    REPORTER_ASSERT(reporter, bounds == expected);
    bounds.setQuadBounds(curvePts);
    expected.set(0, 0, 3, 4);
    REPORTER_ASSERT(reporter, bounds == expected);
    (bounds.*SetCurveBounds[2])(curvePts);
    REPORTER_ASSERT(reporter, bounds == expected);
    bounds.setCubicBounds(curvePts);
    expected.set(0, 0, 5, 6);
    REPORTER_ASSERT(reporter, bounds == expected);
    (bounds.*SetCurveBounds[3])(curvePts);
    REPORTER_ASSERT(reporter, bounds == expected);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS_SHORT(PathOpsBoundsTest)
