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

struct lineCubic {
    SkDCubic cubic;
    SkDLine line;
};

static lineCubic failLineCubicTests[] = {
    {{{{37.5273438,-1.44140625}, {37.8736992,-1.69921875}, {38.1640625,-2.140625},
            {38.3984375,-2.765625}}},
            {{{40.625,-5.7890625}, {37.7109375,1.3515625}}}},
};

static const size_t failLineCubicTests_count = SK_ARRAY_COUNT(failLineCubicTests);

static void testFail(skiatest::Reporter* reporter, int iIndex) {
    const SkDCubic& cubic = failLineCubicTests[iIndex].cubic;
    SkASSERT(ValidCubic(cubic));
    const SkDLine& line = failLineCubicTests[iIndex].line;
    SkASSERT(ValidLine(line));
    SkReduceOrder reduce1;
    SkReduceOrder reduce2;
    int order1 = reduce1.reduce(cubic, SkReduceOrder::kNo_Quadratics);
    int order2 = reduce2.reduce(line);
    if (order1 < 4) {
        SkDebugf("[%d] cubic order=%d\n", iIndex, order1);
        REPORTER_ASSERT(reporter, 0);
    }
    if (order2 < 2) {
        SkDebugf("[%d] line order=%d\n", iIndex, order2);
        REPORTER_ASSERT(reporter, 0);
    }
    if (order1 == 4 && order2 == 2) {
        SkIntersections i;
        int roots = i.intersect(cubic, line);
        REPORTER_ASSERT(reporter, roots == 0);
    }
}

static lineCubic lineCubicTests[] = {
    {{{{0.468027353,4}, {1.06734705,1.33333337}, {1.36700678,0}, {3,0}}},
    {{{2,1}, {0,1}}}},

    {{{{-634.60540771484375, -481.262939453125}, {266.2696533203125, -752.70867919921875},
            {-751.8370361328125, -317.37921142578125}, {-969.7427978515625, 824.7255859375}}},
            {{{-287.9506133720805678, -557.1376476615772617},
            {-285.9506133720805678, -557.1376476615772617}}}},

    {{{{36.7184372,0.888650894}, {36.7184372,0.888650894}, {35.1233864,0.554015458},
            {34.5114098,-0.115255356}}}, {{{35.4531212,0}, {31.9375,0}}}},

    {{{{421, 378}, {421, 380.209137f}, {418.761414f, 382}, {416, 382}}},
            {{{320, 378}, {421, 378.000031f}}}},

    {{{{416, 383}, {418.761414f, 383}, {421, 380.761414f}, {421, 378}}},
            {{{320, 378}, {421, 378.000031f}}}},

    {{{{154,715}, {151.238571,715}, {149,712.761414}, {149,710}}},
            {{{149,675}, {149,710.001465}}}},

    {{{{0,1}, {1,6}, {4,1}, {4,3}}},
            {{{6,1}, {1,4}}}},

    {{{{0,1}, {2,6}, {4,1}, {5,4}}},
            {{{6,2}, {1,4}}}},

    {{{{0,4}, {3,4}, {6,2}, {5,2}}},
            {{{4,3}, {2,6}}}},
#if 0
    {{{{258, 122}, {260.761414, 122}, { 263, 124.238579}, {263, 127}}},
            {{{259.82843, 125.17157}, {261.535522, 123.46447}}}},
#endif
    {{{{1006.6951293945312,291}, {1023.263671875,291}, {1033.8402099609375,304.43145751953125},
            {1030.318359375,321}}},
            {{{979.30487060546875,561}, {1036.695068359375,291}}}},
    {{{{259.30487060546875,561}, {242.73631286621094,561}, {232.15980529785156,547.56854248046875},
            {235.68154907226562,531}}},
            {{{286.69512939453125,291}, {229.30485534667969,561}}}},
    {{{{1, 2}, {2, 6}, {2, 0}, {1, 0}}}, {{{1, 0}, {1, 2}}}},
    {{{{0, 0}, {0, 1}, {0, 1}, {1, 1}}}, {{{0, 1}, {1, 0}}}},
};

static const size_t lineCubicTests_count = SK_ARRAY_COUNT(lineCubicTests);

static int doIntersect(SkIntersections& intersections, const SkDCubic& cubic, const SkDLine& line) {
    int result;
    bool flipped = false;
    if (line[0].fX == line[1].fX) {
        double top = line[0].fY;
        double bottom = line[1].fY;
        flipped = top > bottom;
        if (flipped) {
            SkTSwap<double>(top, bottom);
        }
        result = intersections.vertical(cubic, top, bottom, line[0].fX, flipped);
    } else if (line[0].fY == line[1].fY) {
        double left = line[0].fX;
        double right = line[1].fX;
        flipped = left > right;
        if (flipped) {
            SkTSwap<double>(left, right);
        }
        result = intersections.horizontal(cubic, left, right, line[0].fY, flipped);
    } else {
        intersections.intersect(cubic, line);
        result = intersections.used();
    }
    return result;
}

static void testOne(skiatest::Reporter* reporter, int iIndex) {
    const SkDCubic& cubic = lineCubicTests[iIndex].cubic;
    SkASSERT(ValidCubic(cubic));
    const SkDLine& line = lineCubicTests[iIndex].line;
    SkASSERT(ValidLine(line));
    SkReduceOrder reduce1;
    SkReduceOrder reduce2;
    int order1 = reduce1.reduce(cubic, SkReduceOrder::kNo_Quadratics);
    int order2 = reduce2.reduce(line);
    if (order1 < 4) {
        SkDebugf("[%d] cubic order=%d\n", iIndex, order1);
        REPORTER_ASSERT(reporter, 0);
    }
    if (order2 < 2) {
        SkDebugf("[%d] line order=%d\n", iIndex, order2);
        REPORTER_ASSERT(reporter, 0);
    }
    if (order1 == 4 && order2 == 2) {
        SkIntersections i;
        int roots = doIntersect(i, cubic, line);
        for (int pt = 0; pt < roots; ++pt) {
            double tt1 = i[0][pt];
            SkDPoint xy1 = cubic.ptAtT(tt1);
            double tt2 = i[1][pt];
            SkDPoint xy2 = line.ptAtT(tt2);
            if (!xy1.approximatelyEqual(xy2)) {
                SkDebugf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                    __FUNCTION__, iIndex, pt, tt1, xy1.fX, xy1.fY, tt2, xy2.fX, xy2.fY);
            }
            REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2));
        }
#if ONE_OFF_DEBUG
        double cubicT = i[0][0];
        SkDPoint prev = cubic.ptAtT(cubicT * 2 - 1);
        SkDPoint sect = cubic.ptAtT(cubicT);
        double left[3] = { line.isLeft(prev), line.isLeft(sect), line.isLeft(cubic[3]) };
        SkDebugf("cubic=(%1.9g, %1.9g, %1.9g)\n", left[0], left[1], left[2]);
        SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", prev.fX, prev.fY, sect.fX, sect.fY);
        SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", sect.fX, sect.fY, cubic[3].fX, cubic[3].fY);
        SkDPoint prevL = line.ptAtT(i[1][0] - 0.0000007);
        SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", prevL.fX, prevL.fY, i.pt(0).fX, i.pt(0).fY);
        SkDPoint nextL = line.ptAtT(i[1][0] + 0.0000007);
        SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", i.pt(0).fX, i.pt(0).fY, nextL.fX, nextL.fY);
        SkDebugf("prevD=%1.9g dist=%1.9g nextD=%1.9g\n", prev.distance(nextL),
                sect.distance(i.pt(0)), cubic[3].distance(prevL));
#endif
    }
}

DEF_TEST(PathOpsFailCubicLineIntersection, reporter) {
    for (size_t index = 0; index < failLineCubicTests_count; ++index) {
        int iIndex = static_cast<int>(index);
        testFail(reporter, iIndex);
        reporter->bumpTestCount();
    }
}

DEF_TEST(PathOpsCubicLineIntersection, reporter) {
    for (size_t index = 0; index < lineCubicTests_count; ++index) {
        int iIndex = static_cast<int>(index);
        testOne(reporter, iIndex);
        reporter->bumpTestCount();
    }
}

DEF_TEST(PathOpsCubicLineIntersectionOneOff, reporter) {
    int iIndex = 0;
    testOne(reporter, iIndex);
    const SkDCubic& cubic = lineCubicTests[iIndex].cubic;
    const SkDLine& line = lineCubicTests[iIndex].line;
    SkIntersections i;
    i.intersect(cubic, line);
    SkASSERT(i.used() == 1);
}
