/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "include/core/SkPoint.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "src/core/SkGeometry.h"
#include "src/pathops/SkIntersections.h"
#include "src/pathops/SkPathOpsConic.h"
#include "src/pathops/SkPathOpsPoint.h"
#include "src/pathops/SkPathOpsQuad.h"
#include "src/pathops/SkPathOpsTypes.h"
#include "tests/PathOpsTestCommon.h"
#include "tests/Test.h"

#include <array>

/*
manually compute the intersection of a pair of circles and see if the conic intersection matches
  given two circles
    construct a line connecting their centers

 */

static constexpr auto testSet = std::to_array<ConicPts>({
        ConicPts{{{{306.588013, -227.983994}, {212.464996, -262.242004}, {95.5512009, 58.9763985}}},
                 0.707107008f},
        ConicPts{{{{377.218994, -141.981003}, {40.578701, -201.339996}, {23.1854992, -102.697998}}},
                 0.707107008f},

        ConicPts{{{{5.1114602088928223, 628.77813720703125},
                   {10.834027290344238, 988.964111328125},
                   {163.40835571289062, 988.964111328125}}},
                 0.72944212f},
        ConicPts{{{{163.40835571289062, 988.964111328125},
                   {5, 988.964111328125},
                   {5, 614.7423095703125}}},
                 0.707106769f},

        ConicPts{{{{11.17222976684570312, -8.103978157043457031},
                   {22.91432571411132812, -10.37866020202636719},
                   {23.7764129638671875, -7.725424289703369141}}},
                 1.00862849f},
        ConicPts{{{{-1.545085430145263672, -4.755282402038574219},
                   {22.23132705688476562, -12.48070907592773438},
                   {23.7764129638671875, -7.725427150726318359}}},
                 0.707106769f},

        ConicPts{{{{-4, 1}, {-4, 5}, {0, 5}}}, 0.707106769f},
        ConicPts{{{{-3, 4}, {-3, 1}, {0, 1}}}, 0.707106769f},

        ConicPts{{{{0, 0}, {0, 1}, {1, 1}}}, 0.5f},
        ConicPts{{{{1, 0}, {0, 0}, {0, 1}}}, 0.5f},
});

const int testSetCount = (int) std::size(testSet);

static void chopCompare(const SkConic chopped[2], const SkDConic dChopped[2]) {
    SkASSERT(roughly_equal(chopped[0].fW, dChopped[0].fWeight));
    SkASSERT(roughly_equal(chopped[1].fW, dChopped[1].fWeight));
    for (int cIndex = 0; cIndex < 2; ++cIndex) {
        for (int pIndex = 0; pIndex < 3; ++pIndex) {
            SkDPoint up;
            up.set(chopped[cIndex].fPts[pIndex]);
            SkASSERT(dChopped[cIndex].fPts[pIndex].approximatelyEqual(up));
        }
    }
#if DEBUG_VISUALIZE_CONICS
    dChopped[0].dump();
    dChopped[1].dump();
#endif
}

#define DEBUG_VISUALIZE_CONICS 0

#if DEBUG_VISUALIZE_CONICS
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkString.h"
#include "src/pathops/SkPathOpsRect.h"

static void writePng(const SkConic& c, const SkConic ch[2], const char* name) {
    const int scale = 10;
    SkConic conic, chopped[2];
    for (int index = 0; index < 3; ++index) {
        conic.fPts[index].fX = c.fPts[index].fX * scale;
        conic.fPts[index].fY = c.fPts[index].fY * scale;
        for (int chIndex = 0; chIndex < 2; ++chIndex) {
            chopped[chIndex].fPts[index].fX = ch[chIndex].fPts[index].fX * scale;
            chopped[chIndex].fPts[index].fY = ch[chIndex].fPts[index].fY * scale;
        }
    }
    conic.fW = c.fW;
    chopped[0].fW = ch[0].fW;
    chopped[1].fW = ch[1].fW;
    SkBitmap bitmap;
    SkRect bounds;
    conic.computeTightBounds(&bounds);
    bounds.outset(10, 10);
    bitmap.tryAllocPixels(SkImageInfo::MakeN32Premul(
          SkScalarRoundToInt(bounds.width()), SkScalarRoundToInt(bounds.height())));
    SkCanvas canvas(bitmap);
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas.translate(-bounds.fLeft, -bounds.fTop);
    canvas.drawColor(SK_ColorWHITE);
    SkPathBuilder builder;
    builder.moveTo(conic.fPts[0]);
    builder.conicTo(conic.fPts[1], conic.fPts[2], conic.fW);
    paint.setARGB(0x80, 0xFF, 0, 0);
    canvas.drawPath(builder.detach(), paint);
    builder.moveTo(chopped[0].fPts[0]);
    builder.conicTo(chopped[0].fPts[1], chopped[0].fPts[2], chopped[0].fW);
    builder.moveTo(chopped[1].fPts[0]);
    builder.conicTo(chopped[1].fPts[1], chopped[1].fPts[2], chopped[1].fW);
    paint.setARGB(0x80, 0, 0, 0xFF);
    canvas.drawPath(builder.detach(), paint);
    SkString filename("c:\\Users\\caryclark\\Documents\\");
    filename.appendf("%s.png", name);
    ToolUtils::EncodeImageToPngFile(filename.c_str(), bitmap);
}

static void writeDPng(const SkDConic& dC, const char* name) {
    const int scale = 5;
    SkDConic dConic = {{{ {dC.fPts[0].fX * scale, dC.fPts[0].fY * scale },
        {dC.fPts[1].fX * scale, dC.fPts[1].fY * scale },
        {dC.fPts[2].fX * scale, dC.fPts[2].fY * scale }}}, dC.fWeight };
    SkBitmap bitmap;
    SkDRect bounds;
    bounds.setBounds(dConic);
    bounds.fLeft -= 10;
    bounds.fTop -= 10;
    bounds.fRight += 10;
    bounds.fBottom += 10;
    bitmap.tryAllocPixels(SkImageInfo::MakeN32Premul(
          SkScalarRoundToInt(SkDoubleToScalar(bounds.width())),
          SkScalarRoundToInt(SkDoubleToScalar(bounds.height()))));
    SkCanvas canvas(bitmap);
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas.translate(SkDoubleToScalar(-bounds.fLeft), SkDoubleToScalar(-bounds.fTop));
    canvas.drawColor(SK_ColorWHITE);
    SkPathBuilder builder;
    builder.moveTo(dConic.fPts[0].asSkPoint());
    builder.conicTo(dConic.fPts[1].asSkPoint(), dConic.fPts[2].asSkPoint(), dConic.fWeight);
    paint.setARGB(0x80, 0xFF, 0, 0);
    canvas.drawPath(builder.detach(), paint);

    const int chops = 2;
    for (int tIndex = 0; tIndex < chops; ++tIndex) {
        SkDConic chopped = dConic.subDivide(tIndex / (double) chops,
                (tIndex + 1) / (double) chops);
        builder.moveTo(chopped.fPts[0].asSkPoint());
        builder.conicTo(chopped.fPts[1].asSkPoint(), chopped.fPts[2].asSkPoint(), chopped.fWeight);
    }
    paint.setARGB(0x80, 0, 0, 0xFF);
    canvas.drawPath(builder.detach(), paint);
    SkString filename("c:\\Users\\caryclark\\Documents\\");
    filename.appendf("%s.png", name);
    ToolUtils::EncodeImageToPngFile(filename.c_str(), bitmap);
}
#endif

static void chopBothWays(const SkDConic& dConic, double t, const char* name) {
    SkConic conic;
    for (int index = 0; index < 3; ++index) {
        conic.fPts[index] = dConic.fPts[index].asSkPoint();
    }
    conic.fW = dConic.fWeight;
    SkConic chopped[2];
    SkDConic dChopped[2];
    if (!conic.chopAt(SkDoubleToScalar(t), chopped)) {
        return;
    }
    dChopped[0] = dConic.subDivide(0, t);
    dChopped[1] = dConic.subDivide(t, 1);
#if DEBUG_VISUALIZE_CONICS
    dConic.dump();
#endif
    chopCompare(chopped, dChopped);
#if DEBUG_VISUALIZE_CONICS
    writePng(conic, chopped, name);
#endif
}

#if DEBUG_VISUALIZE_CONICS
const SkDConic frame0[] = {
{{{{306.588013,-227.983994}, {212.464996,-262.242004}, {95.5512009,58.9763985}}}, 0.707107008f},
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
};

const SkDConic frame1[] = {
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
{{{{306.58801299999999, -227.983994}, {212.46499600000001, -262.24200400000001}, {95.551200899999998, 58.976398500000002}}}, 0.707107008f},
{{{{377.21899400000001, -141.98100299999999}, {237.77799285476553, -166.56830755921084}, {134.08399674208422, -155.06258330544892}}}, 0.788580656f},
{{{{134.08399674208422, -155.06258330544892}, {30.390000629402859, -143.55685905168704}, {23.185499199999999, -102.697998}}}, 0.923879623f},
};

const SkDConic frame2[] = {
{{{{306.588013,-227.983994}, {212.464996,-262.242004}, {95.5512009,58.9763985}}}, 0.707107008f},
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
{{{{205.78973252799028, -158.12538713371103}, {143.97848953841861, -74.076645245042371}, {95.551200899999998, 58.976398500000002}}}, 0.923879623f},
{{{{377.21899400000001, -141.98100299999999}, {237.77799285476553, -166.56830755921084}, {134.08399674208422, -155.06258330544892}}}, 0.788580656f},
};

const SkDConic frame3[] = {
{{{{306.588013,-227.983994}, {212.464996,-262.242004}, {95.5512009,58.9763985}}}, 0.707107008f},
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
{{{{205.78973252799028, -158.12538713371103}, {143.97848953841861, -74.076645245042371}, {95.551200899999998, 58.976398500000002}}}, 0.923879623f},
{{{{252.08225670812539, -156.90491625851064}, {185.93099479842493, -160.81544543232982}, {134.08399674208422, -155.06258330544892}}}, 0.835816324f},
};

const SkDConic frame4[] = {
{{{{306.588013,-227.983994}, {212.464996,-262.242004}, {95.5512009,58.9763985}}}, 0.707107008f},
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
{{{{205.78973252799028, -158.12538713371103}, {174.88411103320448, -116.10101618937664}, {145.19509369736275, -56.857102571363754}}}, 0.871667147f},
{{{{252.08225670812539, -156.90491625851064}, {185.93099479842493, -160.81544543232982}, {134.08399674208422, -155.06258330544892}}}, 0.835816324f},
};

const SkDConic frame5[] = {
{{{{306.588013,-227.983994}, {212.464996,-262.242004}, {95.5512009,58.9763985}}}, 0.707107008f},
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
{{{{205.78973252799028, -158.12538713371103}, {174.88411103320448, -116.10101618937664}, {145.19509369736275, -56.857102571363754}}}, 0.871667147f},
{{{{252.08225670812539, -156.90491625851064}, {219.70109133058406, -158.81912754088933}, {190.17095392508796, -158.38373974664466}}}, 0.858306944f},
};

const SkDConic frame6[] = {
{{{{306.588013,-227.983994}, {212.464996,-262.242004}, {95.5512009,58.9763985}}}, 0.707107008f},
{{{{377.218994,-141.981003}, {40.578701,-201.339996}, {23.1854992,-102.697998}}}, 0.707107008f},
{{{{205.78973252799028, -158.12538713371103}, {190.33692178059735, -137.11320166154385}, {174.87004877564593, -111.2132534799228}}}, 0.858117759f},
{{{{252.08225670812539, -156.90491625851064}, {219.70109133058406, -158.81912754088933}, {190.17095392508796, -158.38373974664466}}}, 0.858306944f},
};

const SkDConic* frames[] = {
    frame0, frame1, frame2, frame3, frame4, frame5, frame6
};

const int frameSizes[] = { (int) std::size(frame0), (int) std::size(frame1),
        (int) std::size(frame2), (int) std::size(frame3),
        (int) std::size(frame4), (int) std::size(frame5),
        (int) std::size(frame6),
};

static void writeFrames() {
    const int scale = 5;

    for (int index = 0; index < (int) std::size(frameSizes); ++index) {
        SkDRect bounds;
        bool boundsSet = false;
        int frameSize = frameSizes[index];
        for (int fIndex = 0; fIndex < frameSize; ++fIndex) {
            const SkDConic& dC = frames[index][fIndex];
            SkDConic dConic = {{{ {dC.fPts[0].fX * scale, dC.fPts[0].fY * scale },
                {dC.fPts[1].fX * scale, dC.fPts[1].fY * scale },
                {dC.fPts[2].fX * scale, dC.fPts[2].fY * scale }}}, dC.fWeight };
            SkDRect dBounds;
            dBounds.setBounds(dConic);
            if (!boundsSet) {
                bounds = dBounds;
                boundsSet = true;
            } else {
                bounds.add((SkDPoint&) dBounds.fLeft);
                bounds.add((SkDPoint&) dBounds.fRight);
            }
        }
        bounds.fLeft -= 10;
        bounds.fTop -= 10;
        bounds.fRight += 10;
        bounds.fBottom += 10;
        SkBitmap bitmap;
        bitmap.tryAllocPixels(SkImageInfo::MakeN32Premul(
              SkScalarRoundToInt(SkDoubleToScalar(bounds.width())),
              SkScalarRoundToInt(SkDoubleToScalar(bounds.height()))));
        SkCanvas canvas(bitmap);
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        canvas.translate(SkDoubleToScalar(-bounds.fLeft), SkDoubleToScalar(-bounds.fTop));
        canvas.drawColor(SK_ColorWHITE);
        for (int fIndex = 0; fIndex < frameSize; ++fIndex) {
            const SkDConic& dC = frames[index][fIndex];
            SkDConic dConic = {{{ {dC.fPts[0].fX * scale, dC.fPts[0].fY * scale },
                {dC.fPts[1].fX * scale, dC.fPts[1].fY * scale },
                {dC.fPts[2].fX * scale, dC.fPts[2].fY * scale }}}, dC.fWeight };
            SkPathBuilder builder;
            builder.moveTo(dConic.fPts[0].asSkPoint());
            builder.conicTo(dConic.fPts[1].asSkPoint(), dConic.fPts[2].asSkPoint(), dConic.fWeight);
            if (fIndex < 2) {
                paint.setARGB(0x80, 0xFF, 0, 0);
            } else {
                paint.setARGB(0x80, 0, 0, 0xFF);
            }
            canvas.drawPath(builder.detach(), paint);
        }
        SkString filename("c:\\Users\\caryclark\\Documents\\");
        filename.appendf("f%d.png", index);
        ToolUtils::EncodeImageToPngFile(filename.c_str(), bitmap);
    }
}
#endif

static void oneOff(skiatest::Reporter* reporter, const ConicPts& conic1, const ConicPts& conic2,
        bool coin) {
#if DEBUG_VISUALIZE_CONICS
    writeFrames();
#endif
    SkDConic c1, c2;
    c1.debugSet(conic1.fPts.fPts, conic1.fWeight);
    c2.debugSet(conic2.fPts.fPts, conic2.fWeight);
    chopBothWays(c1, 0.5, "c1");
    chopBothWays(c2, 0.5, "c2");
#if DEBUG_VISUALIZE_CONICS
    writeDPng(c1, "d1");
    writeDPng(c2, "d2");
#endif
    SkASSERT(ValidConic(c1));
    SkASSERT(ValidConic(c2));
    SkIntersections intersections;
    intersections.intersect(c1, c2);
    REPORTER_ASSERT(reporter, !coin || intersections.used() == 2);
    double tt1, tt2;
    SkDPoint xy1, xy2;
    for (int pt3 = 0; pt3 < intersections.used(); ++pt3) {
        tt1 = intersections[0][pt3];
        xy1 = c1.ptAtT(tt1);
        tt2 = intersections[1][pt3];
        xy2 = c2.ptAtT(tt2);
        const SkDPoint& iPt = intersections.pt(pt3);
        REPORTER_ASSERT(reporter, xy1.approximatelyEqual(iPt));
        REPORTER_ASSERT(reporter, xy2.approximatelyEqual(iPt));
        REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2));
    }
    reporter->bumpTestCount();
}

static void oneOff(skiatest::Reporter* reporter, int outer, int inner) {
    const ConicPts& c1 = testSet[outer];
    const ConicPts& c2 = testSet[inner];
    oneOff(reporter, c1, c2, false);
}

static void oneOffTests(skiatest::Reporter* reporter) {
    for (int outer = 0; outer < testSetCount - 1; ++outer) {
        for (int inner = outer + 1; inner < testSetCount; ++inner) {
            oneOff(reporter, outer, inner);
        }
    }
}

DEF_TEST(PathOpsConicIntersectionOneOff, reporter) {
    oneOff(reporter, 0, 1);
}

DEF_TEST(PathOpsConicIntersection, reporter) {
    oneOffTests(reporter);
}
