/*
 * 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 "CurveIntersection.h"
#include "Intersections.h"
#include "IntersectionUtilities.h"
#include "LineIntersection.h"
#include "LineUtilities.h"
#include "QuadraticLineSegments.h"
#include "QuadraticUtilities.h"
#include <algorithm> // for swap

static const double tClipLimit = 0.8; // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf see Multiple intersections

class QuadraticIntersections {
public:

QuadraticIntersections(const Quadratic& q1, const Quadratic& q2, Intersections& i)
    : quad1(q1)
    , quad2(q2)
    , intersections(i)
    , depth(0)
    , splits(0)
    , coinMinT1(-1) {
}

bool intersect() {
    double minT1, minT2, maxT1, maxT2;
    if (!bezier_clip(quad2, quad1, minT1, maxT1)) {
        return false;
    }
    if (!bezier_clip(quad1, quad2, minT2, maxT2)) {
        return false;
    }
    quad1Divisions = 1 / subDivisions(quad1);
    quad2Divisions = 1 / subDivisions(quad2);
    int split;
    if (maxT1 - minT1 < maxT2 - minT2) {
        intersections.swap();
        minT2 = 0;
        maxT2 = 1;
        split = maxT1 - minT1 > tClipLimit;
    } else {
        minT1 = 0;
        maxT1 = 1;
        split = (maxT2 - minT2 > tClipLimit) << 1;
    }
    return chop(minT1, maxT1, minT2, maxT2, split);
}

protected:

bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
    bool t1IsLine = maxT1 - minT1 <= quad1Divisions;
    bool t2IsLine = maxT2 - minT2 <= quad2Divisions;
    if (t1IsLine | t2IsLine) {
        return intersectAsLine(minT1, maxT1, minT2, maxT2, t1IsLine, t2IsLine);
    }
    Quadratic smaller, larger;
    // FIXME: carry last subdivide and reduceOrder result with quad
    sub_divide(quad1, minT1, maxT1, intersections.swapped() ? larger : smaller);
    sub_divide(quad2, minT2, maxT2, intersections.swapped() ? smaller : larger);
    double minT, maxT;
    if (!bezier_clip(smaller, larger, minT, maxT)) {
        if (approximately_equal(minT, maxT)) {
            double smallT, largeT;
            _Point q2pt, q1pt;
            if (intersections.swapped()) {
                largeT = interp(minT2, maxT2, minT);
                xy_at_t(quad2, largeT, q2pt.x, q2pt.y);
                xy_at_t(quad1, minT1, q1pt.x, q1pt.y);
                if (AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y)) {
                    smallT = minT1;
                } else {
                    xy_at_t(quad1, maxT1, q1pt.x, q1pt.y); // FIXME: debug code
                    SkASSERT(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
                    smallT = maxT1;
                }
            } else {
                smallT = interp(minT1, maxT1, minT);
                xy_at_t(quad1, smallT, q1pt.x, q1pt.y);
                xy_at_t(quad2, minT2, q2pt.x, q2pt.y);
                if (AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y)) {
                    largeT = minT2;
                } else {
                    xy_at_t(quad2, maxT2, q2pt.x, q2pt.y); // FIXME: debug code
                    SkASSERT(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
                    largeT = maxT2;
                }
            }
            intersections.add(smallT, largeT);
            return true;
        }
        return false;
    }
    int split;
    if (intersections.swapped()) {
        double newMinT1 = interp(minT1, maxT1, minT);
        double newMaxT1 = interp(minT1, maxT1, maxT);
        split = (newMaxT1 - newMinT1 > (maxT1 - minT1) * tClipLimit) << 1;
#define VERBOSE 0
#if VERBOSE
        printf("%s d=%d s=%d new1=(%g,%g) old1=(%g,%g) split=%d\n", __FUNCTION__, depth,
            splits, newMinT1, newMaxT1, minT1, maxT1, split);
#endif
        minT1 = newMinT1;
        maxT1 = newMaxT1;
    } else {
        double newMinT2 = interp(minT2, maxT2, minT);
        double newMaxT2 = interp(minT2, maxT2, maxT);
        split = newMaxT2 - newMinT2 > (maxT2 - minT2) * tClipLimit;
#if VERBOSE
        printf("%s d=%d s=%d new2=(%g,%g) old2=(%g,%g) split=%d\n", __FUNCTION__, depth,
            splits, newMinT2, newMaxT2, minT2, maxT2, split);
#endif
        minT2 = newMinT2;
        maxT2 = newMaxT2;
    }
    return chop(minT1, maxT1, minT2, maxT2, split);
}

bool intersectAsLine(double minT1, double maxT1, double minT2, double maxT2,
       bool treat1AsLine, bool treat2AsLine)
{
    _Line line1, line2;
    if (intersections.swapped()) {
        SkTSwap(treat1AsLine, treat2AsLine);
        SkTSwap(minT1, minT2);
        SkTSwap(maxT1, maxT2);
    }
    if (coinMinT1 >= 0) {
        bool earlyExit;
        if ((earlyExit = coinMaxT1 == minT1)) {
            coinMaxT1 = maxT1;
        }
        if (coinMaxT2 == minT2) {
            coinMaxT2 = maxT2;
            return true;
        }
        if (earlyExit) {
            return true;
        }
        coinMinT1 = -1;
    }
    // do line/quadratic or even line/line intersection instead
    if (treat1AsLine) {
        xy_at_t(quad1, minT1, line1[0].x, line1[0].y);
        xy_at_t(quad1, maxT1, line1[1].x, line1[1].y);
    }
    if (treat2AsLine) {
        xy_at_t(quad2, minT2, line2[0].x, line2[0].y);
        xy_at_t(quad2, maxT2, line2[1].x, line2[1].y);
    }
    int pts;
    double smallT1, largeT1, smallT2, largeT2;
    if (treat1AsLine & treat2AsLine) {
        double t1[2], t2[2];
        pts = ::intersect(line1, line2, t1, t2);
        if (pts == 2) {
            smallT1 = interp(minT1, maxT1, t1[0]);
            largeT1 = interp(minT2, maxT2, t2[0]);
            smallT2 = interp(minT1, maxT1, t1[1]);
            largeT2 = interp(minT2, maxT2, t2[1]);
            intersections.addCoincident(smallT1, smallT2, largeT1, largeT2);
        } else {
            smallT1 = interp(minT1, maxT1, t1[0]);
            largeT1 = interp(minT2, maxT2, t2[0]);
            intersections.add(smallT1, largeT1);
        }
    } else {
        Intersections lq;
        pts = ::intersect(treat1AsLine ? quad2 : quad1,
                treat1AsLine ? line1 : line2, lq);
        if (pts == 2) { // if the line and edge are coincident treat differently
            _Point midQuad, midLine;
            double midQuadT = (lq.fT[0][0] + lq.fT[0][1]) / 2;
            xy_at_t(treat1AsLine ? quad2 : quad1, midQuadT, midQuad.x, midQuad.y);
            double lineT = t_at(treat1AsLine ? line1 : line2, midQuad);
            xy_at_t(treat1AsLine ? line1 : line2, lineT, midLine.x, midLine.y);
            if (AlmostEqualUlps(midQuad.x, midLine.x)
                    && AlmostEqualUlps(midQuad.y, midLine.y)) {
                smallT1 = lq.fT[0][0];
                largeT1 = lq.fT[1][0];
                smallT2 = lq.fT[0][1];
                largeT2 = lq.fT[1][1];
                if (treat2AsLine) {
                    smallT1 = interp(minT1, maxT1, smallT1);
                    smallT2 = interp(minT1, maxT1, smallT2);
                } else {
                    largeT1 = interp(minT2, maxT2, largeT1);
                    largeT2 = interp(minT2, maxT2, largeT2);
                }
                intersections.addCoincident(smallT1, smallT2, largeT1, largeT2);
                goto setCoinMinMax;
            }
        }
        for (int index = 0; index < pts; ++index) {
            smallT1 = lq.fT[0][index];
            largeT1 = lq.fT[1][index];
            if (treat2AsLine) {
                smallT1 = interp(minT1, maxT1, smallT1);
            } else {
                largeT1 = interp(minT2, maxT2, largeT1);
            }
            intersections.add(smallT1, largeT1);
        }
    }
    if (pts > 0) {
setCoinMinMax:
        coinMinT1 = minT1;
        coinMaxT1 = maxT1;
        coinMinT2 = minT2;
        coinMaxT2 = maxT2;
    }
    return pts > 0;
}

bool chop(double minT1, double maxT1, double minT2, double maxT2, int split) {
    ++depth;
    intersections.swap();
    if (split) {
        ++splits;
        if (split & 2) {
            double middle1 = (maxT1 + minT1) / 2;
            intersect(minT1, middle1, minT2, maxT2);
            intersect(middle1, maxT1, minT2, maxT2);
        } else {
            double middle2 = (maxT2 + minT2) / 2;
            intersect(minT1, maxT1, minT2, middle2);
            intersect(minT1, maxT1, middle2, maxT2);
        }
        --splits;
        intersections.swap();
        --depth;
        return intersections.intersected();
    }
    bool result = intersect(minT1, maxT1, minT2, maxT2);
    intersections.swap();
    --depth;
    return result;
}

private:

const Quadratic& quad1;
const Quadratic& quad2;
Intersections& intersections;
int depth;
int splits;
double quad1Divisions; // line segments to approximate original within error
double quad2Divisions;
double coinMinT1; // range of Ts where approximate line intersected curve
double coinMaxT1;
double coinMinT2;
double coinMaxT2;
};

#include "LineParameters.h"

static void hackToFixPartialCoincidence(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
    // look to see if non-coincident data basically has unsortable tangents

    // look to see if a point between non-coincident data is on the curve
    int cIndex;
    for (int uIndex = 0; uIndex < i.fUsed; ) {
        double bestDist1 = 1;
        double bestDist2 = 1;
        int closest1 = -1;
        int closest2 = -1;
        for (cIndex = 0; cIndex < i.fCoincidentUsed; ++cIndex) {
            double dist = fabs(i.fT[0][uIndex] - i.fCoincidentT[0][cIndex]);
            if (bestDist1 > dist) {
                bestDist1 = dist;
                closest1 = cIndex;
            }
            dist = fabs(i.fT[1][uIndex] - i.fCoincidentT[1][cIndex]);
            if (bestDist2 > dist) {
                bestDist2 = dist;
                closest2 = cIndex;
            }
        }
        _Line ends;
        _Point mid;
        double t1 = i.fT[0][uIndex];
        xy_at_t(q1, t1, ends[0].x, ends[0].y);
        xy_at_t(q1, i.fCoincidentT[0][closest1], ends[1].x, ends[1].y);
        double midT = (t1 + i.fCoincidentT[0][closest1]) / 2;
        xy_at_t(q1, midT, mid.x, mid.y);
        LineParameters params;
        params.lineEndPoints(ends);
        double midDist = params.pointDistance(mid);
        // Note that we prefer to always measure t error, which does not scale,
        // instead of point error, which is scale dependent. FIXME
        if (!approximately_zero(midDist)) {
            ++uIndex;
            continue;
        }
        double t2 = i.fT[1][uIndex];
        xy_at_t(q2, t2, ends[0].x, ends[0].y);
        xy_at_t(q2, i.fCoincidentT[1][closest2], ends[1].x, ends[1].y);
        midT = (t2 + i.fCoincidentT[1][closest2]) / 2;
        xy_at_t(q2, midT, mid.x, mid.y);
        params.lineEndPoints(ends);
        midDist = params.pointDistance(mid);
        if (!approximately_zero(midDist)) {
            ++uIndex;
            continue;
        }
        // if both midpoints are close to the line, lengthen coincident span
        int cEnd = closest1 ^ 1; // assume coincidence always travels in pairs
        if (!between(i.fCoincidentT[0][cEnd], t1, i.fCoincidentT[0][closest1])) {
            i.fCoincidentT[0][closest1] = t1;
        }
        cEnd = closest2 ^ 1;
        if (!between(i.fCoincidentT[0][cEnd], t2, i.fCoincidentT[0][closest2])) {
            i.fCoincidentT[0][closest2] = t2;
        }
        int remaining = --i.fUsed - uIndex;
        if (remaining > 0) {
            memmove(&i.fT[0][uIndex], &i.fT[0][uIndex + 1], sizeof(i.fT[0][0]) * remaining);
            memmove(&i.fT[1][uIndex], &i.fT[1][uIndex + 1], sizeof(i.fT[1][0]) * remaining);
        }
    }
    // if coincident data is subjectively a tiny span, replace it with a single point
    for (cIndex = 0; cIndex < i.fCoincidentUsed; ) {
        double start1 = i.fCoincidentT[0][cIndex];
        double end1 = i.fCoincidentT[0][cIndex + 1];
        _Line ends1;
        xy_at_t(q1, start1, ends1[0].x, ends1[0].y);
        xy_at_t(q1, end1, ends1[1].x, ends1[1].y);
        if (!AlmostEqualUlps(ends1[0].x, ends1[1].x) || AlmostEqualUlps(ends1[0].y, ends1[1].y)) {
            cIndex += 2;
            continue;
        }
        double start2 = i.fCoincidentT[1][cIndex];
        double end2 = i.fCoincidentT[1][cIndex + 1];
        _Line ends2;
        xy_at_t(q2, start2, ends2[0].x, ends2[0].y);
        xy_at_t(q2, end2, ends2[1].x, ends2[1].y);
        // again, approximately should be used with T values, not points FIXME
        if (!AlmostEqualUlps(ends2[0].x, ends2[1].x) || AlmostEqualUlps(ends2[0].y, ends2[1].y)) {
            cIndex += 2;
            continue;
        }
        if (approximately_less_than_zero(start1) || approximately_less_than_zero(end1)) {
            start1 = 0;
        } else if (approximately_greater_than_one(start1) || approximately_greater_than_one(end1)) {
            start1 = 1;
        } else {
            start1 = (start1 + end1) / 2;
        }
        if (approximately_less_than_zero(start2) || approximately_less_than_zero(end2)) {
            start2 = 0;
        } else if (approximately_greater_than_one(start2) || approximately_greater_than_one(end2)) {
            start2 = 1;
        } else {
            start2 = (start2 + end2) / 2;
        }
        i.insert(start1, start2);
        i.fCoincidentUsed -= 2;
        int remaining = i.fCoincidentUsed - cIndex;
        if (remaining > 0) {
            memmove(&i.fCoincidentT[0][cIndex], &i.fCoincidentT[0][cIndex + 2], sizeof(i.fCoincidentT[0][0]) * remaining);
            memmove(&i.fCoincidentT[1][cIndex], &i.fCoincidentT[1][cIndex + 2], sizeof(i.fCoincidentT[1][0]) * remaining);
        }
    }
}

bool intersect(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
    if (implicit_matches(q1, q2)) {
        // FIXME: compute T values
        // compute the intersections of the ends to find the coincident span
        bool useVertical = fabs(q1[0].x - q1[2].x) < fabs(q1[0].y - q1[2].y);
        double t;
        if ((t = axialIntersect(q1, q2[0], useVertical)) >= 0) {
            i.addCoincident(t, 0);
        }
        if ((t = axialIntersect(q1, q2[2], useVertical)) >= 0) {
            i.addCoincident(t, 1);
        }
        useVertical = fabs(q2[0].x - q2[2].x) < fabs(q2[0].y - q2[2].y);
        if ((t = axialIntersect(q2, q1[0], useVertical)) >= 0) {
            i.addCoincident(0, t);
        }
        if ((t = axialIntersect(q2, q1[2], useVertical)) >= 0) {
            i.addCoincident(1, t);
        }
        SkASSERT(i.fCoincidentUsed <= 2);
        return i.fCoincidentUsed > 0;
    }
    QuadraticIntersections q(q1, q2, i);
    bool result = q.intersect();
    // FIXME: partial coincidence detection is currently poor. For now, try
    // to fix up the data after the fact. In the future, revisit the error
    // term to try to avoid this kind of result in the first place.
    if (i.fUsed && i.fCoincidentUsed) {
        hackToFixPartialCoincidence(q1, q2, i);
    }
    return result;
}
