/*
 * 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 const ConicPts testSet[] = {
    {{{{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},

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

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

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

    {{{{0, 0}, {0, 1}, {1, 1}}}, 0.5f},
    {{{{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);
    SkPath path;
    path.moveTo(conic.fPts[0]);
    path.conicTo(conic.fPts[1], conic.fPts[2], conic.fW);
    paint.setARGB(0x80, 0xFF, 0, 0);
    canvas.drawPath(path, paint);
    path.reset();
    path.moveTo(chopped[0].fPts[0]);
    path.conicTo(chopped[0].fPts[1], chopped[0].fPts[2], chopped[0].fW);
    path.moveTo(chopped[1].fPts[0]);
    path.conicTo(chopped[1].fPts[1], chopped[1].fPts[2], chopped[1].fW);
    paint.setARGB(0x80, 0, 0, 0xFF);
    canvas.drawPath(path, 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);
    SkPath path;
    path.moveTo(dConic.fPts[0].asSkPoint());
    path.conicTo(dConic.fPts[1].asSkPoint(), dConic.fPts[2].asSkPoint(), dConic.fWeight);
    paint.setARGB(0x80, 0xFF, 0, 0);
    canvas.drawPath(path, paint);
    path.reset();
    const int chops = 2;
    for (int tIndex = 0; tIndex < chops; ++tIndex) {
        SkDConic chopped = dConic.subDivide(tIndex / (double) chops,
                (tIndex + 1) / (double) chops);
        path.moveTo(chopped.fPts[0].asSkPoint());
        path.conicTo(chopped.fPts[1].asSkPoint(), chopped.fPts[2].asSkPoint(), chopped.fWeight);
    }
    paint.setARGB(0x80, 0, 0, 0xFF);
    canvas.drawPath(path, 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 };
            SkPath path;
            path.moveTo(dConic.fPts[0].asSkPoint());
            path.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(path, 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);
}
