/*
 * 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 "SkIntersections.h"
#include "SkOpAngle.h"
#include "SkOpSegment.h"
#include "SkPathOpsCurve.h"
#include "SkTSort.h"

#if DEBUG_ANGLE
#include "SkString.h"
#endif

/* Angles are sorted counterclockwise. The smallest angle has a positive x and the smallest
   positive y. The largest angle has a positive x and a zero y. */

#if DEBUG_ANGLE
    static bool CompareResult(SkString* bugOut, int append, bool compare) {
        SkDebugf("%s %c %d\n", bugOut->c_str(), compare ? 'T' : 'F', append);
        return compare;
    }

    #define COMPARE_RESULT(append, compare) CompareResult(&bugOut, append, compare)
#else
    #define COMPARE_RESULT(append, compare) compare
#endif

/*             quarter angle values for sector

31   x > 0, y == 0              horizontal line (to the right)
0    x > 0, y == epsilon        quad/cubic horizontal tangent eventually going +y
1    x > 0, y > 0, x > y        nearer horizontal angle
2                  x + e == y   quad/cubic 45 going horiz
3    x > 0, y > 0, x == y       45 angle
4                  x == y + e   quad/cubic 45 going vert
5    x > 0, y > 0, x < y        nearer vertical angle
6    x == epsilon, y > 0        quad/cubic vertical tangent eventually going +x
7    x == 0, y > 0              vertical line (to the top)

                                      8  7  6
                                 9       |       5
                              10         |          4
                            11           |            3
                          12  \          |           / 2
                         13              |              1
                        14               |               0
                        15 --------------+------------- 31
                        16               |              30
                         17              |             29
                          18  /          |          \ 28
                            19           |           27
                              20         |         26
                                 21      |      25
                                     22 23 24
*/

// return true if lh < this < rh
bool SkOpAngle::after(const SkOpAngle* test) const {
    const SkOpAngle& lh = *test;
    const SkOpAngle& rh = *lh.fNext;
    SkASSERT(&lh != &rh);
#if DEBUG_ANGLE
    SkString bugOut;
    bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                  " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                  " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
            lh.fSegment->debugID(), lh.debugID(), lh.fSectorStart, lh.fSectorEnd,
            lh.fSegment->t(lh.fStart), lh.fSegment->t(lh.fEnd),
            fSegment->debugID(), debugID(), fSectorStart, fSectorEnd, fSegment->t(fStart),
            fSegment->t(fEnd),
            rh.fSegment->debugID(), rh.debugID(), rh.fSectorStart, rh.fSectorEnd,
            rh.fSegment->t(rh.fStart), rh.fSegment->t(rh.fEnd));
#endif
    if (lh.fComputeSector && !const_cast<SkOpAngle&>(lh).computeSector()) {
        return COMPARE_RESULT(1, true);
    }
    if (fComputeSector && !const_cast<SkOpAngle*>(this)->computeSector()) {
        return COMPARE_RESULT(2, true);
    }
    if (rh.fComputeSector && !const_cast<SkOpAngle&>(rh).computeSector()) {
        return COMPARE_RESULT(3, true);
    }
#if DEBUG_ANGLE  // reset bugOut with computed sectors
    bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                  " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
                  " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
            lh.fSegment->debugID(), lh.debugID(), lh.fSectorStart, lh.fSectorEnd,
            lh.fSegment->t(lh.fStart), lh.fSegment->t(lh.fEnd),
            fSegment->debugID(), debugID(), fSectorStart, fSectorEnd, fSegment->t(fStart),
            fSegment->t(fEnd),
            rh.fSegment->debugID(), rh.debugID(), rh.fSectorStart, rh.fSectorEnd,
            rh.fSegment->t(rh.fStart), rh.fSegment->t(rh.fEnd));
#endif
    bool ltrOverlap = (lh.fSectorMask | rh.fSectorMask) & fSectorMask;
    bool lrOverlap = lh.fSectorMask & rh.fSectorMask;
    int lrOrder;  // set to -1 if either order works
    if (!lrOverlap) {  // no lh/rh sector overlap
        if (!ltrOverlap) {  // no lh/this/rh sector overlap
            return COMPARE_RESULT(4,  (lh.fSectorEnd > rh.fSectorStart)
                    ^ (fSectorStart > lh.fSectorEnd) ^ (fSectorStart > rh.fSectorStart));
        }
        int lrGap = (rh.fSectorStart - lh.fSectorStart + 32) & 0x1f;
        /* A tiny change can move the start +/- 4. The order can only be determined if
           lr gap is not 12 to 20 or -12 to -20.
               -31 ..-21      1
               -20 ..-12     -1
               -11 .. -1      0
                 0          shouldn't get here
                11 ..  1      1
                12 .. 20     -1
                21 .. 31      0
         */
        lrOrder = lrGap > 20 ? 0 : lrGap > 11 ? -1 : 1;
    } else {
        lrOrder = (int) lh.orderable(rh);
        if (!ltrOverlap) {
            return COMPARE_RESULT(5, !lrOrder);
        }
    }
    int ltOrder;
    SkASSERT((lh.fSectorMask & fSectorMask) || (rh.fSectorMask & fSectorMask));
    if (lh.fSectorMask & fSectorMask) {
        ltOrder = (int) lh.orderable(*this);
    } else {
        int ltGap = (fSectorStart - lh.fSectorStart + 32) & 0x1f;
        ltOrder = ltGap > 20 ? 0 : ltGap > 11 ? -1 : 1;
    }
    int trOrder;
    if (rh.fSectorMask & fSectorMask) {
        trOrder = (int) orderable(rh);
    } else {
        int trGap = (rh.fSectorStart - fSectorStart + 32) & 0x1f;
        trOrder = trGap > 20 ? 0 : trGap > 11 ? -1 : 1;
    }
    if (lrOrder >= 0 && ltOrder >= 0 && trOrder >= 0) {
        return COMPARE_RESULT(7, lrOrder ? (ltOrder & trOrder) : (ltOrder | trOrder));
    }
    SkASSERT(lrOrder >= 0 || ltOrder >= 0 || trOrder >= 0);
// There's not enough information to sort. Get the pairs of angles in opposite planes.
// If an order is < 0, the pair is already in an opposite plane. Check the remaining pairs.
    // FIXME : once all variants are understood, rewrite this more simply
    if (ltOrder == 0 && lrOrder == 0) {
        SkASSERT(trOrder < 0);
        // FIXME : once this is verified to work, remove one opposite angle call
        SkDEBUGCODE(bool lrOpposite = lh.oppositePlanes(rh));
        bool ltOpposite = lh.oppositePlanes(*this);
        SkASSERT(lrOpposite != ltOpposite);
        return COMPARE_RESULT(8, ltOpposite);
    } else if (ltOrder == 1 && trOrder == 0) {
        SkASSERT(lrOrder < 0);
        SkDEBUGCODE(bool ltOpposite = lh.oppositePlanes(*this));
        bool trOpposite = oppositePlanes(rh);
        SkASSERT(ltOpposite != trOpposite);
        return COMPARE_RESULT(9, trOpposite);
    } else if (lrOrder == 1 && trOrder == 1) {
        SkASSERT(ltOrder < 0);
        SkDEBUGCODE(bool trOpposite = oppositePlanes(rh));
        bool lrOpposite = lh.oppositePlanes(rh);
        SkASSERT(lrOpposite != trOpposite);
        return COMPARE_RESULT(10, lrOpposite);
    }
    if (lrOrder < 0) {
        if (ltOrder < 0) {
            return COMPARE_RESULT(11, trOrder);
        }
        return COMPARE_RESULT(12, ltOrder);
    }
    return COMPARE_RESULT(13, !lrOrder);
}

// given a line, see if the opposite curve's convex hull is all on one side
// returns -1=not on one side    0=this CW of test   1=this CCW of test
int SkOpAngle::allOnOneSide(const SkOpAngle& test) const {
    SkASSERT(!fIsCurve);
    SkASSERT(test.fIsCurve);
    const SkDPoint& origin = test.fCurvePart[0];
    SkVector line;
    if (fSegment->verb() == SkPath::kLine_Verb) {
        const SkPoint* linePts = fSegment->pts();
        int lineStart = fStart < fEnd ? 0 : 1;
        line = linePts[lineStart ^ 1] - linePts[lineStart];
    } else {
        SkPoint shortPts[2] = { fCurvePart[0].asSkPoint(), fCurvePart[1].asSkPoint() };
        line = shortPts[1] - shortPts[0];
    }
    float crosses[3];
    SkPath::Verb testVerb = test.fSegment->verb();
    int iMax = SkPathOpsVerbToPoints(testVerb);
//    SkASSERT(origin == test.fCurveHalf[0]);
    const SkDCubic& testCurve = test.fCurvePart;
//    do {
        for (int index = 1; index <= iMax; ++index) {
            float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY));
            float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX));
            crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2;
        }
        if (crosses[0] * crosses[1] < 0) {
            return -1;
        }
        if (SkPath::kCubic_Verb == testVerb) {
            if (crosses[0] * crosses[2] < 0 || crosses[1] * crosses[2] < 0) {
                return -1;
            }
        }
        if (crosses[0]) {
            return crosses[0] < 0;
        }
        if (crosses[1]) {
            return crosses[1] < 0;
        }
        if (SkPath::kCubic_Verb == testVerb && crosses[2]) {
            return crosses[2] < 0;
        }
    fUnorderable = true;
    return -1;
}

bool SkOpAngle::calcSlop(double x, double y, double rx, double ry, bool* result) const {
    double absX = fabs(x);
    double absY = fabs(y);
    double length = absX < absY ? absX / 2 + absY : absX + absY / 2;
    int exponent;
    (void) frexp(length, &exponent);
    double epsilon = ldexp(FLT_EPSILON, exponent);
    SkPath::Verb verb = fSegment->verb();
    SkASSERT(verb == SkPath::kQuad_Verb || verb == SkPath::kCubic_Verb);
    // FIXME: the quad and cubic factors are made up ; determine actual values
    double slop = verb == SkPath::kQuad_Verb ? 4 * epsilon : 512 * epsilon;
    double xSlop = slop;
    double ySlop = x * y < 0 ? -xSlop : xSlop; // OPTIMIZATION: use copysign / _copysign ?
    double x1 = x - xSlop;
    double y1 = y + ySlop;
    double x_ry1 = x1 * ry;
    double rx_y1 = rx * y1;
    *result = x_ry1 < rx_y1;
    double x2 = x + xSlop;
    double y2 = y - ySlop;
    double x_ry2 = x2 * ry;
    double rx_y2 = rx * y2;
    bool less2 = x_ry2 < rx_y2;
    return *result == less2;
}

bool SkOpAngle::checkCrossesZero() const {
    int start = SkTMin(fSectorStart, fSectorEnd);
    int end = SkTMax(fSectorStart, fSectorEnd);
    bool crossesZero = end - start > 16;
    return crossesZero;
}

bool SkOpAngle::checkParallel(const SkOpAngle& rh) const {
    SkDVector scratch[2];
    const SkDVector* sweep, * tweep;
    if (!fUnorderedSweep) {
        sweep = fSweep;
    } else {
        scratch[0] = fCurvePart[1] - fCurvePart[0];
        sweep = &scratch[0];
    }
    if (!rh.fUnorderedSweep) {
        tweep = rh.fSweep;
    } else {
        scratch[1] = rh.fCurvePart[1] - rh.fCurvePart[0];
        tweep = &scratch[1];
    }
    double s0xt0 = sweep->crossCheck(*tweep);
    if (tangentsDiverge(rh, s0xt0)) {
        return s0xt0 < 0;
    }
    SkDVector m0 = fSegment->dPtAtT(midT()) - fCurvePart[0];
    SkDVector m1 = rh.fSegment->dPtAtT(rh.midT()) - rh.fCurvePart[0];
    double m0xm1 = m0.crossCheck(m1);
    if (m0xm1 == 0) {
        fUnorderable = true;
        rh.fUnorderable = true;
        return true;
    }
    return m0xm1 < 0;
}

// the original angle is too short to get meaningful sector information
// lengthen it until it is long enough to be meaningful or leave it unset if lengthening it
// would cause it to intersect one of the adjacent angles
bool SkOpAngle::computeSector() {
    if (fComputedSector) {
        // FIXME: logically, this should return !fUnorderable, but doing so breaks testQuadratic51
        // -- but in general, this code may not work so this may be the least of problems
        // adding the bang fixes testQuads46x in release, however
        return !fUnorderable;
    }
    SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small());
    fComputedSector = true;
    int step = fStart < fEnd ? 1 : -1;
    int limit = step > 0 ? fSegment->count() : -1;
    int checkEnd = fEnd;
    do {
// advance end
        const SkOpSpan& span = fSegment->span(checkEnd);
        const SkOpSegment* other = span.fOther;
        int oCount = other->count();
        for (int oIndex = 0; oIndex < oCount; ++oIndex) {
            const SkOpSpan& oSpan = other->span(oIndex);
            if (oSpan.fOther != fSegment) {
                continue;
            }
            if (oSpan.fOtherIndex == checkEnd) {
                continue;
            }
            if (!approximately_equal(oSpan.fOtherT, span.fT)) {
                continue;
            }
            goto recomputeSector;
        }
        checkEnd += step;
    } while (checkEnd != limit);
recomputeSector:
    if (checkEnd == fEnd || checkEnd - step == fEnd) {
        fUnorderable = true;
        return false;
    }
    int saveEnd = fEnd;
    fComputedEnd = fEnd = checkEnd - step;
    setSpans();
    setSector();
    fEnd = saveEnd;
    return !fUnorderable;
}

// returns -1 if overlaps   0 if no overlap cw    1 if no overlap ccw
int SkOpAngle::convexHullOverlaps(const SkOpAngle& rh) const {
    const SkDVector* sweep = fSweep;
    const SkDVector* tweep = rh.fSweep;
    double s0xs1 = sweep[0].crossCheck(sweep[1]);
    double s0xt0 = sweep[0].crossCheck(tweep[0]);
    double s1xt0 = sweep[1].crossCheck(tweep[0]);
    bool tBetweenS = s0xs1 > 0 ? s0xt0 > 0 && s1xt0 < 0 : s0xt0 < 0 && s1xt0 > 0;
    double s0xt1 = sweep[0].crossCheck(tweep[1]);
    double s1xt1 = sweep[1].crossCheck(tweep[1]);
    tBetweenS |= s0xs1 > 0 ? s0xt1 > 0 && s1xt1 < 0 : s0xt1 < 0 && s1xt1 > 0;
    double t0xt1 = tweep[0].crossCheck(tweep[1]);
    if (tBetweenS) {
        return -1;
    }
    if ((s0xt0 == 0 && s1xt1 == 0) || (s1xt0 == 0 && s0xt1 == 0)) {  // s0 to s1 equals t0 to t1
        return -1;
    }
    bool sBetweenT = t0xt1 > 0 ? s0xt0 < 0 && s0xt1 > 0 : s0xt0 > 0 && s0xt1 < 0;
    sBetweenT |= t0xt1 > 0 ? s1xt0 < 0 && s1xt1 > 0 : s1xt0 > 0 && s1xt1 < 0;
    if (sBetweenT) {
        return -1;
    }
    // if all of the sweeps are in the same half plane, then the order of any pair is enough
    if (s0xt0 >= 0 && s0xt1 >= 0 && s1xt0 >= 0 && s1xt1 >= 0) {
        return 0;
    }
    if (s0xt0 <= 0 && s0xt1 <= 0 && s1xt0 <= 0 && s1xt1 <= 0) {
        return 1;
    }
    // if the outside sweeps are greater than 180 degress:
        // first assume the inital tangents are the ordering
        // if the midpoint direction matches the inital order, that is enough
    SkDVector m0 = fSegment->dPtAtT(midT()) - fCurvePart[0];
    SkDVector m1 = rh.fSegment->dPtAtT(rh.midT()) - rh.fCurvePart[0];
    double m0xm1 = m0.crossCheck(m1);
    if (s0xt0 > 0 && m0xm1 > 0) {
        return 0;
    }
    if (s0xt0 < 0 && m0xm1 < 0) {
        return 1;
    }
    if (tangentsDiverge(rh, s0xt0)) {
        return s0xt0 < 0;
    }
    return m0xm1 < 0;
}

// OPTIMIZATION: longest can all be either lazily computed here or precomputed in setup
double SkOpAngle::distEndRatio(double dist) const {
    double longest = 0;
    const SkOpSegment& segment = *this->segment();
    int ptCount = SkPathOpsVerbToPoints(segment.verb());
    const SkPoint* pts = segment.pts();
    for (int idx1 = 0; idx1 <= ptCount - 1; ++idx1) {
        for (int idx2 = idx1 + 1; idx2 <= ptCount; ++idx2) {
            if (idx1 == idx2) {
                continue;
            }
            SkDVector v;
            v.set(pts[idx2] - pts[idx1]);
            double lenSq = v.lengthSquared();
            longest = SkTMax(longest, lenSq);
        }
    }
    return sqrt(longest) / dist;
}

bool SkOpAngle::endsIntersect(const SkOpAngle& rh) const {
    SkPath::Verb lVerb = fSegment->verb();
    SkPath::Verb rVerb = rh.fSegment->verb();
    int lPts = SkPathOpsVerbToPoints(lVerb);
    int rPts = SkPathOpsVerbToPoints(rVerb);
    SkDLine rays[] = {{{fCurvePart[0], rh.fCurvePart[rPts]}},
            {{fCurvePart[0], fCurvePart[lPts]}}};
    if (rays[0][1] == rays[1][1]) {
        return checkParallel(rh);
    }
    double smallTs[2] = {-1, -1};
    bool limited[2] = {false, false};
    for (int index = 0; index < 2; ++index) {
        const SkOpSegment& segment = index ? *rh.fSegment : *fSegment;
        SkIntersections i;
        (*CurveIntersectRay[index ? rPts : lPts])(segment.pts(), rays[index], &i);
//      SkASSERT(i.used() >= 1);
//        if (i.used() <= 1) {
//            continue;
//        }
        double tStart = segment.t(index ? rh.fStart : fStart);
        double tEnd = segment.t(index ? rh.fComputedEnd : fComputedEnd);
        bool testAscends = index ? rh.fStart < rh.fComputedEnd : fStart < fComputedEnd;
        double t = testAscends ? 0 : 1;
        for (int idx2 = 0; idx2 < i.used(); ++idx2) {
            double testT = i[0][idx2];
            if (!approximately_between_orderable(tStart, testT, tEnd)) {
                continue;
            }
            if (approximately_equal_orderable(tStart, testT)) {
                continue;
            }
            smallTs[index] = t = testAscends ? SkTMax(t, testT) : SkTMin(t, testT);
            limited[index] = approximately_equal_orderable(t, tEnd);
        }
    }
#if 0
    if (smallTs[0] < 0 && smallTs[1] < 0) {  // if neither ray intersects, do endpoint sort
        double m0xm1 = 0;
        if (lVerb == SkPath::kLine_Verb) {
            SkASSERT(rVerb != SkPath::kLine_Verb);
            SkDVector m0 = rays[1][1] - fCurvePart[0];
            SkDPoint endPt;
            endPt.set(rh.fSegment->pts()[rh.fStart < rh.fEnd ? rPts : 0]);
            SkDVector m1 = endPt - fCurvePart[0];
            m0xm1 = m0.crossCheck(m1);
        }
        if (rVerb == SkPath::kLine_Verb) {
            SkDPoint endPt;
            endPt.set(fSegment->pts()[fStart < fEnd ? lPts : 0]);
            SkDVector m0 = endPt - fCurvePart[0];
            SkDVector m1 = rays[0][1] - fCurvePart[0];
            m0xm1 = m0.crossCheck(m1);
        }
        if (m0xm1 != 0) {
            return m0xm1 < 0;
        }
    }
#endif
    bool sRayLonger = false;
    SkDVector sCept = {0, 0};
    double sCeptT = -1;
    int sIndex = -1;
    bool useIntersect = false;
    for (int index = 0; index < 2; ++index) {
        if (smallTs[index] < 0) {
            continue;
        }
        const SkOpSegment& segment = index ? *rh.fSegment : *fSegment;
        const SkDPoint& dPt = segment.dPtAtT(smallTs[index]);
        SkDVector cept = dPt - rays[index][0];
        // If this point is on the curve, it should have been detected earlier by ordinary
        // curve intersection. This may be hard to determine in general, but for lines,
        // the point could be close to or equal to its end, but shouldn't be near the start.
        if ((index ? lPts : rPts) == 1) {
            SkDVector total = rays[index][1] - rays[index][0];
            if (cept.lengthSquared() * 2 < total.lengthSquared()) {
                continue;
            }
        }
        SkDVector end = rays[index][1] - rays[index][0];
        if (cept.fX * end.fX < 0 || cept.fY * end.fY < 0) {
            continue;
        }
        double rayDist = cept.length();
        double endDist = end.length();
        bool rayLonger = rayDist > endDist;
        if (limited[0] && limited[1] && rayLonger) {
            useIntersect = true;
            sRayLonger = rayLonger;
            sCept = cept;
            sCeptT = smallTs[index];
            sIndex = index;
            break;
        }
        double delta = fabs(rayDist - endDist);
        double minX, minY, maxX, maxY;
        minX = minY = SK_ScalarInfinity;
        maxX = maxY = -SK_ScalarInfinity;
        const SkDCubic& curve = index ? rh.fCurvePart : fCurvePart;
        int ptCount = index ? rPts : lPts;
        for (int idx2 = 0; idx2 <= ptCount; ++idx2) {
            minX = SkTMin(minX, curve[idx2].fX);
            minY = SkTMin(minY, curve[idx2].fY);
            maxX = SkTMax(maxX, curve[idx2].fX);
            maxY = SkTMax(maxY, curve[idx2].fY);
        }
        double maxWidth = SkTMax(maxX - minX, maxY - minY);
        delta /= maxWidth;
        if (delta > 1e-4 && (useIntersect ^= true)) {  // FIXME: move this magic number
            sRayLonger = rayLonger;
            sCept = cept;
            sCeptT = smallTs[index];
            sIndex = index;
        }
    }
    if (useIntersect) {
        const SkDCubic& curve = sIndex ? rh.fCurvePart : fCurvePart;
        const SkOpSegment& segment = sIndex ? *rh.fSegment : *fSegment;
        double tStart = segment.t(sIndex ? rh.fStart : fStart);
        SkDVector mid = segment.dPtAtT(tStart + (sCeptT - tStart) / 2) - curve[0];
        double septDir = mid.crossCheck(sCept);
        if (!septDir) {
            return checkParallel(rh);
        }
        return sRayLonger ^ (sIndex == 0) ^ (septDir < 0);
    } else {
        return checkParallel(rh);
    }
}

// Most of the time, the first one can be found trivially by detecting the smallest sector value.
// If all angles have the same sector value, actual sorting is required.
const SkOpAngle* SkOpAngle::findFirst() const {
    const SkOpAngle* best = this;
    int bestStart = SkTMin(fSectorStart, fSectorEnd);
    const SkOpAngle* angle = this;
    while ((angle = angle->fNext) != this) {
        int angleEnd = SkTMax(angle->fSectorStart, angle->fSectorEnd);
        if (angleEnd < bestStart) {
            return angle;    // we wrapped around
        }
        int angleStart = SkTMin(angle->fSectorStart, angle->fSectorEnd);
        if (bestStart > angleStart) {
            best = angle;
            bestStart = angleStart;
        }
    }
    // back up to the first possible angle
    const SkOpAngle* firstBest = best;
    angle = best;
    int bestEnd = SkTMax(best->fSectorStart, best->fSectorEnd);
    while ((angle = angle->previous()) != firstBest) {
        if (angle->fStop) {
            break;
        }
        int angleStart = SkTMin(angle->fSectorStart, angle->fSectorEnd);
        // angles that are smaller by one aren't necessary better, since the larger may be a line
        // and the smaller may be a curve that curls to the other side of the line.
        if (bestEnd + 1 < angleStart) {
            return best;
        }
        best = angle;
        bestEnd = SkTMax(angle->fSectorStart, angle->fSectorEnd);
    }
    // in the case where all angles are nearly in the same sector, check the order to find the best
    firstBest = best;
    angle = best;
    do {
        angle = angle->fNext;
        if (angle->fStop) {
            return firstBest;
        }
        bool orderable = best->orderable(*angle);  // note: may return an unorderable angle
        if (orderable == 0) {
            return angle;
        }
        best = angle;
    } while (angle != firstBest);
    // if the angles are equally ordered, fall back on the initial tangent
    bool foundBelow = false;
    while ((angle = angle->fNext)) {
        SkDVector scratch[2];
        const SkDVector* sweep;
        if (!angle->fUnorderedSweep) {
            sweep = angle->fSweep;
        } else {
            scratch[0] = angle->fCurvePart[1] - angle->fCurvePart[0];
            sweep = &scratch[0];
        }
        bool isAbove = sweep->fY <= 0;
        if (isAbove && foundBelow) {
            return angle;
        }
        foundBelow |= !isAbove;
        if (angle == firstBest) {
            return NULL; // should not loop around
        }
    }
    SkASSERT(0);  // should never get here
    return NULL;
}

/*      y<0 y==0 y>0  x<0 x==0 x>0 xy<0 xy==0 xy>0
    0    x                      x               x
    1    x                      x          x
    2    x                      x    x
    3    x                  x        x
    4    x             x             x
    5    x             x                   x
    6    x             x                        x
    7         x        x                        x
    8             x    x                        x
    9             x    x                   x
    10            x    x             x
    11            x         x        x
    12            x             x    x
    13            x             x          x
    14            x             x               x
    15        x                 x               x
*/
int SkOpAngle::findSector(SkPath::Verb verb, double x, double y) const {
    double absX = fabs(x);
    double absY = fabs(y);
    double xy = SkPath::kLine_Verb == verb || !AlmostEqualUlps(absX, absY) ? absX - absY : 0;
    // If there are four quadrants and eight octants, and since the Latin for sixteen is sedecim,
    // one could coin the term sedecimant for a space divided into 16 sections.
   // http://english.stackexchange.com/questions/133688/word-for-something-partitioned-into-16-parts
    static const int sedecimant[3][3][3] = {
    //       y<0           y==0           y>0
    //   x<0 x==0 x>0  x<0 x==0 x>0  x<0 x==0 x>0
        {{ 4,  3,  2}, { 7, -1, 15}, {10, 11, 12}},  // abs(x) <  abs(y)
        {{ 5, -1,  1}, {-1, -1, -1}, { 9, -1, 13}},  // abs(x) == abs(y)
        {{ 6,  3,  0}, { 7, -1, 15}, { 8, 11, 14}},  // abs(x) >  abs(y)
    };
    int sector = sedecimant[(xy >= 0) + (xy > 0)][(y >= 0) + (y > 0)][(x >= 0) + (x > 0)] * 2 + 1;
    SkASSERT(SkPath::kLine_Verb == verb || sector >= 0);
    return sector;
}

// OPTIMIZE: if this loops to only one other angle, after first compare fails, insert on other side
// OPTIMIZE: return where insertion succeeded. Then, start next insertion on opposite side
void SkOpAngle::insert(SkOpAngle* angle) {
    if (angle->fNext) {
        if (loopCount() >= angle->loopCount()) {
            if (!merge(angle)) {
                return;
            }
        } else if (fNext) {
            if (!angle->merge(this)) {
                return;
            }
        } else {
            angle->insert(this);
        }
        return;
    }
    bool singleton = NULL == fNext;
    if (singleton) {
        fNext = this;
    }
    SkOpAngle* next = fNext;
    if (next->fNext == this) {
        if (angle->overlap(*this)) {
            return;
        }
        if (singleton || angle->after(this)) {
            this->fNext = angle;
            angle->fNext = next;
        } else {
            next->fNext = angle;
            angle->fNext = this;
        }
        debugValidateNext();
        return;
    }
    SkOpAngle* last = this;
    do {
        SkASSERT(last->fNext == next);
        if (angle->overlap(*last) || angle->overlap(*next)) {
            return;
        }
        if (angle->after(last)) {
            last->fNext = angle;
            angle->fNext = next;
            debugValidateNext();
            return;
        }
        last = next;
        next = next->fNext;
        if (last == this && next->fUnorderable) {
            fUnorderable = true;
            return;
        }
        SkASSERT(last != this);
    } while (true);
}

bool SkOpAngle::isHorizontal() const {
    return !fIsCurve && fSweep[0].fY == 0;
}

SkOpSpan* SkOpAngle::lastMarked() const {
    if (fLastMarked) {
        if (fLastMarked->fChased) {
            return NULL;
        }
        fLastMarked->fChased = true;
    }
    return fLastMarked;
}

bool SkOpAngle::loopContains(const SkOpAngle& test) const {
    if (!fNext) {
        return false;
    }
    const SkOpAngle* first = this;
    const SkOpAngle* loop = this;
    const SkOpSegment* tSegment = test.fSegment;
    double tStart = tSegment->span(test.fStart).fT;
    double tEnd = tSegment->span(test.fEnd).fT;
    do {
        const SkOpSegment* lSegment = loop->fSegment;
        // FIXME : use precisely_equal ? or compare points exactly ?
        if (lSegment != tSegment) {
            continue;
        }
        double lStart = lSegment->span(loop->fStart).fT;
        if (lStart != tEnd) {
            continue;
        }
        double lEnd = lSegment->span(loop->fEnd).fT;
        if (lEnd == tStart) {
            return true;
        }
    } while ((loop = loop->fNext) != first);
    return false;
}

int SkOpAngle::loopCount() const {
    int count = 0;
    const SkOpAngle* first = this;
    const SkOpAngle* next = this;
    do {
        next = next->fNext;
        ++count;
    } while (next && next != first);
    return count;
}

// OPTIMIZATION: can this be done better in after when angles are sorted?
void SkOpAngle::markStops() {
    SkOpAngle* angle = this;
    int lastEnd = SkTMax(fSectorStart, fSectorEnd);
    do {
        angle = angle->fNext;
        int angleStart = SkTMin(angle->fSectorStart, angle->fSectorEnd);
        // angles that are smaller by one aren't necessary better, since the larger may be a line
        // and the smaller may be a curve that curls to the other side of the line.
        if (lastEnd + 1 < angleStart) {
            angle->fStop = true;
        }
        lastEnd = SkTMax(angle->fSectorStart, angle->fSectorEnd);
    } while (angle != this);
}

bool SkOpAngle::merge(SkOpAngle* angle) {
    SkASSERT(fNext);
    SkASSERT(angle->fNext);
    SkOpAngle* working = angle;
    do {
        if (this == working) {
            return false;
        }
        working = working->fNext;
    } while (working != angle);
    do {
        SkOpAngle* next = working->fNext;
        working->fNext = NULL;
        insert(working);
        working = next;
    } while (working != angle);
    // it's likely that a pair of the angles are unorderable
#if DEBUG_ANGLE
    SkOpAngle* last = angle;
    working = angle->fNext;
    do {
        SkASSERT(last->fNext == working);
        last->fNext = working->fNext;
        SkASSERT(working->after(last));
        last->fNext = working;
        last = working;
        working = working->fNext;
    } while (last != angle);
#endif
    debugValidateNext();
    return true;
}

double SkOpAngle::midT() const {
    return (fSegment->t(fStart) + fSegment->t(fEnd)) / 2;
}

bool SkOpAngle::oppositePlanes(const SkOpAngle& rh) const {
    int startSpan = abs(rh.fSectorStart - fSectorStart);
    return startSpan >= 8;
}

bool SkOpAngle::orderable(const SkOpAngle& rh) const {
    int result;
    if (!fIsCurve) {
        if (!rh.fIsCurve) {
            double leftX = fTangentHalf.dx();
            double leftY = fTangentHalf.dy();
            double rightX = rh.fTangentHalf.dx();
            double rightY = rh.fTangentHalf.dy();
            double x_ry = leftX * rightY;
            double rx_y = rightX * leftY;
            if (x_ry == rx_y) {
                if (leftX * rightX < 0 || leftY * rightY < 0) {
                    return true;  // exactly 180 degrees apart
                }
                goto unorderable;
            }
            SkASSERT(x_ry != rx_y); // indicates an undetected coincidence -- worth finding earlier
            return x_ry < rx_y;
        }
        if ((result = allOnOneSide(rh)) >= 0) {
            return result;
        }
        if (fUnorderable || approximately_zero(rh.fSide)) {
            goto unorderable;
        }
    } else if (!rh.fIsCurve) {
        if ((result = rh.allOnOneSide(*this)) >= 0) {
            return !result;
        }
        if (rh.fUnorderable || approximately_zero(fSide)) {
            goto unorderable;
        }
    }
    if ((result = convexHullOverlaps(rh)) >= 0) {
        return result;
    }
    return endsIntersect(rh);
unorderable:
    fUnorderable = true;
    rh.fUnorderable = true;
    return true;
}

bool SkOpAngle::overlap(const SkOpAngle& other) const {
    int min = SkTMin(fStart, fEnd);
    const SkOpSpan& span = fSegment->span(min);
    const SkOpSegment* oSeg = other.fSegment;
    int oMin = SkTMin(other.fStart, other.fEnd);
    const SkOpSpan& oSpan = oSeg->span(oMin);
    if (!span.fSmall && !oSpan.fSmall) {
        return false;
    }
    if (fSegment->span(fStart).fPt != oSeg->span(other.fStart).fPt) {
        return false;
    }
    // see if small span is contained by opposite span
    return span.fSmall ? oSeg->containsPt(fSegment->span(fEnd).fPt, other.fEnd, other.fStart)
            : fSegment->containsPt(oSeg->span(other.fEnd).fPt, fEnd, fStart);
}

// OPTIMIZE: if this shows up in a profile, add a previous pointer
// as is, this should be rarely called
SkOpAngle* SkOpAngle::previous() const {
    SkOpAngle* last = fNext;
    do {
        SkOpAngle* next = last->fNext;
        if (next == this) {
            return last;
        }
        last = next;
    } while (true);
}

void SkOpAngle::set(const SkOpSegment* segment, int start, int end) {
    fSegment = segment;
    fStart = start;
    fComputedEnd = fEnd = end;
    fNext = NULL;
    fComputeSector = fComputedSector = false;
    fStop = false;
    setSpans();
    setSector();
}

void SkOpAngle::setCurveHullSweep() {
    fUnorderedSweep = false;
    fSweep[0] = fCurvePart[1] - fCurvePart[0];
    if (SkPath::kLine_Verb == fSegment->verb()) {
        fSweep[1] = fSweep[0];
        return;
    }
    fSweep[1] = fCurvePart[2] - fCurvePart[0];
    if (SkPath::kCubic_Verb != fSegment->verb()) {
        if (!fSweep[0].fX && !fSweep[0].fY) {
            fSweep[0] = fSweep[1];
        }
        return;
    }
    SkDVector thirdSweep = fCurvePart[3] - fCurvePart[0];
    if (fSweep[0].fX == 0 && fSweep[0].fY == 0) {
        fSweep[0] = fSweep[1];
        fSweep[1] = thirdSweep;
        if (fSweep[0].fX == 0 && fSweep[0].fY == 0) {
            fSweep[0] = fSweep[1];
            fCurvePart[1] = fCurvePart[3];
            fIsCurve = false;
        }
        return;
    }
    double s1x3 = fSweep[0].crossCheck(thirdSweep);
    double s3x2 = thirdSweep.crossCheck(fSweep[1]);
    if (s1x3 * s3x2 >= 0) {  // if third vector is on or between first two vectors
        return;
    }
    double s2x1 = fSweep[1].crossCheck(fSweep[0]);
    // FIXME: If the sweep of the cubic is greater than 180 degrees, we're in trouble
    // probably such wide sweeps should be artificially subdivided earlier so that never happens
    SkASSERT(s1x3 * s2x1 < 0 || s1x3 * s3x2 < 0);
    if (s3x2 * s2x1 < 0) {
        SkASSERT(s2x1 * s1x3 > 0);
        fSweep[0] = fSweep[1];
        fUnorderedSweep = true;
    }
    fSweep[1] = thirdSweep;
}

void SkOpAngle::setSector() {
    SkPath::Verb verb = fSegment->verb();
    if (SkPath::kLine_Verb != verb && small()) {
        fSectorStart = fSectorEnd = -1;
        fSectorMask = 0;
        fComputeSector = true;  // can't determine sector until segment length can be found
        return;
    }
    fSectorStart = findSector(verb, fSweep[0].fX, fSweep[0].fY);
    if (!fIsCurve) {  // if it's a line or line-like, note that both sectors are the same
        SkASSERT(fSectorStart >= 0);
        fSectorEnd = fSectorStart;
        fSectorMask = 1 << fSectorStart;
        return;
    }
    SkASSERT(SkPath::kLine_Verb != verb);
    fSectorEnd = findSector(verb, fSweep[1].fX, fSweep[1].fY);
    if (fSectorEnd == fSectorStart) {
        SkASSERT((fSectorStart & 3) != 3);  // if the sector has no span, it can't be an exact angle
        fSectorMask = 1 << fSectorStart;
        return;
    }
    bool crossesZero = checkCrossesZero();
    int start = SkTMin(fSectorStart, fSectorEnd);
    bool curveBendsCCW = (fSectorStart == start) ^ crossesZero;
    // bump the start and end of the sector span if they are on exact compass points
    if ((fSectorStart & 3) == 3) {
        fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f;
    }
    if ((fSectorEnd & 3) == 3) {
        fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f;
    }
    crossesZero = checkCrossesZero();
    start = SkTMin(fSectorStart, fSectorEnd);
    int end = SkTMax(fSectorStart, fSectorEnd);
    if (!crossesZero) {
        fSectorMask = (unsigned) -1 >> (31 - end + start) << start;
    } else {
        fSectorMask = (unsigned) -1 >> (31 - start) | (-1 << end);
    }
}

void SkOpAngle::setSpans() {
    fUnorderable = fSegment->isTiny(this);
    fLastMarked = NULL;
    const SkPoint* pts = fSegment->pts();
    SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurvePart[3].fY
            = SK_ScalarNaN);
    fSegment->subDivide(fStart, fEnd, &fCurvePart);
    setCurveHullSweep();
    const SkPath::Verb verb = fSegment->verb();
    if (verb != SkPath::kLine_Verb
            && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) {
        SkDLine lineHalf;
        lineHalf[0].set(fCurvePart[0].asSkPoint());
        lineHalf[1].set(fCurvePart[SkPathOpsVerbToPoints(verb)].asSkPoint());
        fTangentHalf.lineEndPoints(lineHalf);
        fSide = 0;
    }
    switch (verb) {
    case SkPath::kLine_Verb: {
        SkASSERT(fStart != fEnd);
        const SkPoint& cP1 = pts[fStart < fEnd];
        SkDLine lineHalf;
        lineHalf[0].set(fSegment->span(fStart).fPt);
        lineHalf[1].set(cP1);
        fTangentHalf.lineEndPoints(lineHalf);
        fSide = 0;
        fIsCurve = false;
        } return;
    case SkPath::kQuad_Verb: {
        SkLineParameters tangentPart;
        SkDQuad& quad2 = *SkTCast<SkDQuad*>(&fCurvePart);
        (void) tangentPart.quadEndPoints(quad2);
        fSide = -tangentPart.pointDistance(fCurvePart[2]);  // not normalized -- compare sign only
        } break;
    case SkPath::kCubic_Verb: {
        SkLineParameters tangentPart;
        (void) tangentPart.cubicPart(fCurvePart);
        fSide = -tangentPart.pointDistance(fCurvePart[3]);
        double testTs[4];
        // OPTIMIZATION: keep inflections precomputed with cubic segment?
        int testCount = SkDCubic::FindInflections(pts, testTs);
        double startT = fSegment->t(fStart);
        double endT = fSegment->t(fEnd);
        double limitT = endT;
        int index;
        for (index = 0; index < testCount; ++index) {
            if (!::between(startT, testTs[index], limitT)) {
                testTs[index] = -1;
            }
        }
        testTs[testCount++] = startT;
        testTs[testCount++] = endT;
        SkTQSort<double>(testTs, &testTs[testCount - 1]);
        double bestSide = 0;
        int testCases = (testCount << 1) - 1;
        index = 0;
        while (testTs[index] < 0) {
            ++index;
        }
        index <<= 1;
        for (; index < testCases; ++index) {
            int testIndex = index >> 1;
            double testT = testTs[testIndex];
            if (index & 1) {
                testT = (testT + testTs[testIndex + 1]) / 2;
            }
            // OPTIMIZE: could avoid call for t == startT, endT
            SkDPoint pt = dcubic_xy_at_t(pts, testT);
            SkLineParameters tangentPart;
            tangentPart.cubicEndPoints(fCurvePart);
            double testSide = tangentPart.pointDistance(pt);
            if (fabs(bestSide) < fabs(testSide)) {
                bestSide = testSide;
            }
        }
        fSide = -bestSide;  // compare sign only
        } break;
    default:
        SkASSERT(0);
    }
}

bool SkOpAngle::small() const {
    int min = SkMin32(fStart, fEnd);
    int max = SkMax32(fStart, fEnd);
    for (int index = min; index < max; ++index) {
        const SkOpSpan& mSpan = fSegment->span(index);
        if (!mSpan.fSmall) {
            return false;
        }
    }
    return true;
}

bool SkOpAngle::tangentsDiverge(const SkOpAngle& rh, double s0xt0) const {
    if (s0xt0 == 0) {
        return false;
    }
    // if the ctrl tangents are not nearly parallel, use them
    // solve for opposite direction displacement scale factor == m
    // initial dir = v1.cross(v2) == v2.x * v1.y - v2.y * v1.x
    // displacement of q1[1] : dq1 = { -m * v1.y, m * v1.x } + q1[1]
    // straight angle when : v2.x * (dq1.y - q1[0].y) == v2.y * (dq1.x - q1[0].x)
    //                       v2.x * (m * v1.x + v1.y) == v2.y * (-m * v1.y + v1.x)
    // - m * (v2.x * v1.x + v2.y * v1.y) == v2.x * v1.y - v2.y * v1.x
    // m = (v2.y * v1.x - v2.x * v1.y) / (v2.x * v1.x + v2.y * v1.y)
    // m = v1.cross(v2) / v1.dot(v2)
    const SkDVector* sweep = fSweep;
    const SkDVector* tweep = rh.fSweep;
    double s0dt0 = sweep[0].dot(tweep[0]);
    if (!s0dt0) {
        return true;
    }
    SkASSERT(s0dt0 != 0);
    double m = s0xt0 / s0dt0;
    double sDist = sweep[0].length() * m;
    double tDist = tweep[0].length() * m;
    bool useS = fabs(sDist) < fabs(tDist);
    double mFactor = fabs(useS ? distEndRatio(sDist) : rh.distEndRatio(tDist));
    return mFactor < 5000;  // empirically found limit
}

SkOpAngleSet::SkOpAngleSet() 
    : fAngles(NULL)
#if DEBUG_ANGLE
    , fCount(0)
#endif
{
}

SkOpAngleSet::~SkOpAngleSet() {
    SkDELETE(fAngles);
}

SkOpAngle& SkOpAngleSet::push_back() {
    if (!fAngles) {
        fAngles = SkNEW_ARGS(SkChunkAlloc, (2));
    }
    void* ptr = fAngles->allocThrow(sizeof(SkOpAngle));
    SkOpAngle* angle = (SkOpAngle*) ptr;
#if DEBUG_ANGLE
    angle->setID(++fCount);
#endif
    return *angle;
}

void SkOpAngleSet::reset() {
    if (fAngles) {
        fAngles->reset();
    }
}
