/*
* Copyright 2013 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 "SkOpContour.h"
#include "SkPathWriter.h"
#include "SkTSort.h"

bool SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex,
        const SkIntersections& ts, bool swap) {
    SkPoint pt0 = ts.pt(0).asSkPoint();
    SkPoint pt1 = ts.pt(1).asSkPoint();
    if (pt0 == pt1) {
        // FIXME: one could imagine a case where it would be incorrect to ignore this
        // suppose two self-intersecting cubics overlap to be coincident --
        // this needs to check that by some measure the t values are far enough apart
        // or needs to check to see if the self-intersection bit was set on the cubic segment
        return false;
    }
    SkCoincidence& coincidence = fCoincidences.push_back();
    coincidence.fOther = other;
    coincidence.fSegments[0] = index;
    coincidence.fSegments[1] = otherIndex;
    coincidence.fTs[swap][0] = ts[0][0];
    coincidence.fTs[swap][1] = ts[0][1];
    coincidence.fTs[!swap][0] = ts[1][0];
    coincidence.fTs[!swap][1] = ts[1][1];
    coincidence.fPts[swap][0] = pt0;
    coincidence.fPts[swap][1] = pt1;
    bool nearStart = ts.nearlySame(0);
    bool nearEnd = ts.nearlySame(1);
    coincidence.fPts[!swap][0] = nearStart ? ts.pt2(0).asSkPoint() : pt0;
    coincidence.fPts[!swap][1] = nearEnd ? ts.pt2(1).asSkPoint() : pt1;
    coincidence.fNearly[0] = nearStart;
    coincidence.fNearly[1] = nearEnd;
    return true;
}

SkOpSegment* SkOpContour::nonVerticalSegment(int* start, int* end) {
    int segmentCount = fSortedSegments.count();
    SkASSERT(segmentCount > 0);
    for (int sortedIndex = fFirstSorted; sortedIndex < segmentCount; ++sortedIndex) {
        SkOpSegment* testSegment = fSortedSegments[sortedIndex];
        if (testSegment->done()) {
            continue;
        }
        *start = *end = 0;
        while (testSegment->nextCandidate(start, end)) {
            if (!testSegment->isVertical(*start, *end)) {
                return testSegment;
            }
        }
    }
    return NULL;
}

// if one is very large the smaller may have collapsed to nothing
static void bump_out_close_span(double* startTPtr, double* endTPtr) {
    double startT = *startTPtr;
    double endT = *endTPtr;
    if (approximately_negative(endT - startT)) {
        if (endT <= 1 - FLT_EPSILON) {
            *endTPtr += FLT_EPSILON;
            SkASSERT(*endTPtr <= 1);
        } else {
            *startTPtr -= FLT_EPSILON;
            SkASSERT(*startTPtr >= 0);
        }
    }
}

// first pass, add missing T values
// second pass, determine winding values of overlaps
void SkOpContour::addCoincidentPoints() {
    int count = fCoincidences.count();
    for (int index = 0; index < count; ++index) {
        SkCoincidence& coincidence = fCoincidences[index];
        int thisIndex = coincidence.fSegments[0];
        SkOpSegment& thisOne = fSegments[thisIndex];
        SkOpContour* otherContour = coincidence.fOther;
        int otherIndex = coincidence.fSegments[1];
        SkOpSegment& other = otherContour->fSegments[otherIndex];
        if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) {
            // OPTIMIZATION: remove from array
            continue;
        }
    #if DEBUG_CONCIDENT
        thisOne.debugShowTs("-");
        other.debugShowTs("o");
    #endif
        double startT = coincidence.fTs[0][0];
        double endT = coincidence.fTs[0][1];
        bool startSwapped, oStartSwapped, cancelers;
        if ((cancelers = startSwapped = startT > endT)) {
            SkTSwap(startT, endT);
        }
        bump_out_close_span(&startT, &endT);
        SkASSERT(!approximately_negative(endT - startT));
        double oStartT = coincidence.fTs[1][0];
        double oEndT = coincidence.fTs[1][1];
        if ((oStartSwapped = oStartT > oEndT)) {
            SkTSwap(oStartT, oEndT);
            cancelers ^= true;
        }
        bump_out_close_span(&oStartT, &oEndT);
        SkASSERT(!approximately_negative(oEndT - oStartT));
        const SkPoint& startPt = coincidence.fPts[0][startSwapped];
        if (cancelers) {
            // make sure startT and endT have t entries
            if (startT > 0 || oEndT < 1
                    || thisOne.isMissing(startT, startPt) || other.isMissing(oEndT, startPt)) {
                thisOne.addTPair(startT, &other, oEndT, true, startPt,
                        coincidence.fPts[1][startSwapped]);
            }
            const SkPoint& oStartPt = coincidence.fPts[1][oStartSwapped];
            if (oStartT > 0 || endT < 1
                    || thisOne.isMissing(endT, oStartPt) || other.isMissing(oStartT, oStartPt)) {
                other.addTPair(oStartT, &thisOne, endT, true, oStartPt,
                        coincidence.fPts[0][oStartSwapped]);
            }
        } else {
            if (startT > 0 || oStartT > 0
                    || thisOne.isMissing(startT, startPt) || other.isMissing(oStartT, startPt)) {
                thisOne.addTPair(startT, &other, oStartT, true, startPt,
                        coincidence.fPts[1][startSwapped]);
            }
            const SkPoint& oEndPt = coincidence.fPts[1][!oStartSwapped];
            if (endT < 1 || oEndT < 1
                    || thisOne.isMissing(endT, oEndPt) || other.isMissing(oEndT, oEndPt)) {
                other.addTPair(oEndT, &thisOne, endT, true, oEndPt,
                        coincidence.fPts[0][!oStartSwapped]);
            }
        }
    #if DEBUG_CONCIDENT
        thisOne.debugShowTs("+");
        other.debugShowTs("o");
    #endif
    }
    // if there are multiple pairs of coincidence that share an edge, see if the opposite
    // are also coincident
    for (int index = 0; index < count - 1; ++index) {
        const SkCoincidence& coincidence = fCoincidences[index];
        int thisIndex = coincidence.fSegments[0];
        SkOpContour* otherContour = coincidence.fOther;
        int otherIndex = coincidence.fSegments[1];
        for (int idx2 = 1; idx2 < count; ++idx2) {
            const SkCoincidence& innerCoin = fCoincidences[idx2];
            int innerThisIndex = innerCoin.fSegments[0];
            if (thisIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 1, innerCoin, 1, false);
            }
            if (this == otherContour && otherIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 0, innerCoin, 1, false);
            }
            SkOpContour* innerOtherContour = innerCoin.fOther;
            innerThisIndex = innerCoin.fSegments[1];
            if (this == innerOtherContour && thisIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 1, innerCoin, 0, false);
            }
            if (otherContour == innerOtherContour && otherIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 0, innerCoin, 0, false);
            }
        }
    }
}

bool SkOpContour::addPartialCoincident(int index, SkOpContour* other, int otherIndex,
        const SkIntersections& ts, int ptIndex, bool swap) {
    SkPoint pt0 = ts.pt(ptIndex).asSkPoint();
    SkPoint pt1 = ts.pt(ptIndex + 1).asSkPoint();
    if (SkDPoint::ApproximatelyEqual(pt0, pt1)) {
        // FIXME: one could imagine a case where it would be incorrect to ignore this
        // suppose two self-intersecting cubics overlap to form a partial coincidence --
        // although it isn't clear why the regular coincidence could wouldn't pick this up
        // this is exceptional enough to ignore for now
        return false;
    }
    SkCoincidence& coincidence = fPartialCoincidences.push_back();
    coincidence.fOther = other;
    coincidence.fSegments[0] = index;
    coincidence.fSegments[1] = otherIndex;
    coincidence.fTs[swap][0] = ts[0][ptIndex];
    coincidence.fTs[swap][1] = ts[0][ptIndex + 1];
    coincidence.fTs[!swap][0] = ts[1][ptIndex];
    coincidence.fTs[!swap][1] = ts[1][ptIndex + 1];
    coincidence.fPts[0][0] = coincidence.fPts[1][0] = pt0;
    coincidence.fPts[0][1] = coincidence.fPts[1][1] = pt1;
    coincidence.fNearly[0] = 0;
    coincidence.fNearly[1] = 0;
    return true;
}

void SkOpContour::align(const SkOpSegment::AlignedSpan& aligned, bool swap,
        SkCoincidence* coincidence) {
    for (int idx2 = 0; idx2 < 2; ++idx2) {
        if (coincidence->fPts[0][idx2] == aligned.fOldPt
                && coincidence->fTs[swap][idx2] == aligned.fOldT) {
            SkASSERT(SkDPoint::RoughlyEqual(coincidence->fPts[0][idx2], aligned.fPt));
            coincidence->fPts[0][idx2] = aligned.fPt;
            SkASSERT(way_roughly_equal(coincidence->fTs[swap][idx2], aligned.fT));
            coincidence->fTs[swap][idx2] = aligned.fT;
        }
    }
}

void SkOpContour::alignCoincidence(const SkOpSegment::AlignedSpan& aligned,
        SkTArray<SkCoincidence, true>* coincidences) {
    int count = coincidences->count();
    for (int index = 0; index < count; ++index) {
        SkCoincidence& coincidence = (*coincidences)[index];
        int thisIndex = coincidence.fSegments[0];
        const SkOpSegment* thisOne = &fSegments[thisIndex];
        const SkOpContour* otherContour = coincidence.fOther;
        int otherIndex = coincidence.fSegments[1];
        const SkOpSegment* other = &otherContour->fSegments[otherIndex];
        if (thisOne == aligned.fOther1 && other == aligned.fOther2) {
            align(aligned, false, &coincidence);
        } else if (thisOne == aligned.fOther2 && other == aligned.fOther1) {
            align(aligned, true, &coincidence);
        }
    }
}

void SkOpContour::alignTPt(int segmentIndex, const SkOpContour* other, int otherIndex, 
        bool swap, int tIndex, SkIntersections* ts, SkPoint* point) const {
    int zeroPt;
    if ((zeroPt = alignT(swap, tIndex, ts)) >= 0) {
        alignPt(segmentIndex, point, zeroPt);
    }
    if ((zeroPt = other->alignT(!swap, tIndex, ts)) >= 0) {
        other->alignPt(otherIndex, point, zeroPt);
    }
}

void SkOpContour::alignPt(int index, SkPoint* point, int zeroPt) const {
    const SkOpSegment& segment = fSegments[index];
    if (0 == zeroPt) {     
        *point = segment.pts()[0];
    } else {
        *point = segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
    }
}

int SkOpContour::alignT(bool swap, int tIndex, SkIntersections* ts) const {
    double tVal = (*ts)[swap][tIndex];
    if (tVal != 0 && precisely_zero(tVal)) {
        ts->set(swap, tIndex, 0);
        return 0;
    } 
     if (tVal != 1 && precisely_equal(tVal, 1)) {
        ts->set(swap, tIndex, 1);
        return 1;
    }
    return -1;
}

bool SkOpContour::calcAngles() {
    int segmentCount = fSegments.count();
    for (int test = 0; test < segmentCount; ++test) {
        if (!fSegments[test].calcAngles()) {
            return false;
        }
    }
    return true;
}

bool SkOpContour::calcCoincidentWinding() {
    int count = fCoincidences.count();
#if DEBUG_CONCIDENT
    if (count > 0) {
        SkDebugf("%s count=%d\n", __FUNCTION__, count);
    }
#endif
    for (int index = 0; index < count; ++index) {
        SkCoincidence& coincidence = fCoincidences[index];
        if (!calcCommonCoincidentWinding(coincidence)) {
            return false;
        }
    }
    return true;
}

void SkOpContour::calcPartialCoincidentWinding() {
    int count = fPartialCoincidences.count();
#if DEBUG_CONCIDENT
    if (count > 0) {
        SkDebugf("%s count=%d\n", __FUNCTION__, count);
    }
#endif
    for (int index = 0; index < count; ++index) {
        SkCoincidence& coincidence = fPartialCoincidences[index];
        calcCommonCoincidentWinding(coincidence);
    }
    // if there are multiple pairs of partial coincidence that share an edge, see if the opposite
    // are also coincident
    for (int index = 0; index < count - 1; ++index) {
        const SkCoincidence& coincidence = fPartialCoincidences[index];
        int thisIndex = coincidence.fSegments[0];
        SkOpContour* otherContour = coincidence.fOther;
        int otherIndex = coincidence.fSegments[1];
        for (int idx2 = 1; idx2 < count; ++idx2) {
            const SkCoincidence& innerCoin = fPartialCoincidences[idx2];
            int innerThisIndex = innerCoin.fSegments[0];
            if (thisIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 1, innerCoin, 1, true);
            }
            if (this == otherContour && otherIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 0, innerCoin, 1, true);
            }
            SkOpContour* innerOtherContour = innerCoin.fOther;
            innerThisIndex = innerCoin.fSegments[1];
            if (this == innerOtherContour && thisIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 1, innerCoin, 0, true);
            }
            if (otherContour == innerOtherContour && otherIndex == innerThisIndex) {
                checkCoincidentPair(coincidence, 0, innerCoin, 0, true);
            }
        }
    }
}

void SkOpContour::checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx,
        const SkCoincidence& twoCoin, int twoIdx, bool partial) {
    SkASSERT((oneIdx ? this : oneCoin.fOther) == (twoIdx ? this : twoCoin.fOther));
    SkASSERT(oneCoin.fSegments[!oneIdx] == twoCoin.fSegments[!twoIdx]);
    // look for common overlap
    double min = SK_ScalarMax;
    double max = SK_ScalarMin;
    double min1 = oneCoin.fTs[!oneIdx][0];
    double max1 = oneCoin.fTs[!oneIdx][1];
    double min2 = twoCoin.fTs[!twoIdx][0];
    double max2 = twoCoin.fTs[!twoIdx][1];
    bool cancelers = (min1 < max1) != (min2 < max2);
    if (min1 > max1) {
        SkTSwap(min1, max1);
    }
    if (min2 > max2) {
        SkTSwap(min2, max2);
    }
    if (between(min1, min2, max1)) {
        min = min2;
    }
    if (between(min1, max2, max1)) {
        max = max2;
    }
    if (between(min2, min1, max2)) {
        min = SkTMin(min, min1);
    }
    if (between(min2, max1, max2)) {
        max = SkTMax(max, max1);
    }
    if (min >= max) {
        return;  // no overlap
    }
    // look to see if opposite are different segments
    int seg1Index = oneCoin.fSegments[oneIdx];
    int seg2Index = twoCoin.fSegments[twoIdx];
    if (seg1Index == seg2Index) {
        return;
    }
    SkOpContour* contour1 = oneIdx ? oneCoin.fOther : this;
    SkOpContour* contour2 = twoIdx ? twoCoin.fOther : this;
    SkOpSegment* segment1 = &contour1->fSegments[seg1Index];
    SkOpSegment* segment2 = &contour2->fSegments[seg2Index];
    // find opposite t value ranges corresponding to reference min/max range
    const SkOpContour* refContour = oneIdx ? this : oneCoin.fOther;
    const int refSegIndex = oneCoin.fSegments[!oneIdx];
    const SkOpSegment* refSegment = &refContour->fSegments[refSegIndex];
    int seg1Start = segment1->findOtherT(min, refSegment);
    int seg1End = segment1->findOtherT(max, refSegment);
    int seg2Start = segment2->findOtherT(min, refSegment);
    int seg2End = segment2->findOtherT(max, refSegment);
    // if the opposite pairs already contain min/max, we're done
    if (seg1Start >= 0 && seg1End >= 0 && seg2Start >= 0 && seg2End >= 0) {
        return;
    }
    double loEnd = SkTMin(min1, min2);
    double hiEnd = SkTMax(max1, max2);
    // insert the missing coincident point(s)
    double missingT1 = -1;
    double otherT1 = -1;
    if (seg1Start < 0) {
        if (seg2Start < 0) {
            return;
        }
        missingT1 = segment1->calcMissingTStart(refSegment, loEnd, min, max, hiEnd,
                segment2, seg1End);
        if (missingT1 < 0) {
            return;
        }
        const SkOpSpan* missingSpan = &segment2->span(seg2Start);
        otherT1 = missingSpan->fT;
    } else if (seg2Start < 0) {
        SkASSERT(seg1Start >= 0);
        missingT1 = segment2->calcMissingTStart(refSegment, loEnd, min, max, hiEnd,
                segment1, seg2End);
        if (missingT1 < 0) {
            return;
        }
        const SkOpSpan* missingSpan = &segment1->span(seg1Start);
        otherT1 = missingSpan->fT;
    }
    SkPoint missingPt1;
    SkOpSegment* addTo1 = NULL;
    SkOpSegment* addOther1 = seg1Start < 0 ? segment2 : segment1;
    int minTIndex = refSegment->findExactT(min, addOther1);
    SkASSERT(minTIndex >= 0);
    if (missingT1 >= 0) {
        missingPt1 = refSegment->span(minTIndex).fPt;
        addTo1 = seg1Start < 0 ? segment1 : segment2;
    }
    double missingT2 = -1;
    double otherT2 = -1;
    if (seg1End < 0) {
        if (seg2End < 0) {
            return;
        }
        missingT2 = segment1->calcMissingTEnd(refSegment, loEnd, min, max, hiEnd,
                segment2, seg1Start);
        if (missingT2 < 0) {
            return;
        }
        const SkOpSpan* missingSpan = &segment2->span(seg2End);
        otherT2 = missingSpan->fT;
    } else if (seg2End < 0) {
        SkASSERT(seg1End >= 0);
        missingT2 = segment2->calcMissingTEnd(refSegment, loEnd, min, max, hiEnd,
                segment1, seg2Start);
        if (missingT2 < 0) {
            return;
        }
        const SkOpSpan* missingSpan = &segment1->span(seg1End);
        otherT2 = missingSpan->fT;
    }
    SkPoint missingPt2;
    SkOpSegment* addTo2 = NULL;
    SkOpSegment* addOther2 = seg1End < 0 ? segment2 : segment1;
    int maxTIndex = refSegment->findExactT(max, addOther2);
    SkASSERT(maxTIndex >= 0);
    if (missingT2 >= 0) {
        missingPt2 = refSegment->span(maxTIndex).fPt;
        addTo2 = seg1End < 0 ? segment1 : segment2;
    }
    if (missingT1 >= 0) {
        addTo1->pinT(missingPt1, &missingT1);
        addTo1->addTPair(missingT1, addOther1, otherT1, false, missingPt1);
    } else {
        SkASSERT(minTIndex >= 0);
        missingPt1 = refSegment->span(minTIndex).fPt;
    }
    if (missingT2 >= 0) {
        addTo2->pinT(missingPt2, &missingT2);
        addTo2->addTPair(missingT2, addOther2, otherT2, false, missingPt2);
    } else {
        SkASSERT(minTIndex >= 0);
        missingPt2 = refSegment->span(maxTIndex).fPt;
    }
    if (!partial) {
        return;
    }
    if (cancelers) {
        if (missingT1 >= 0) {
            if (addTo1->reversePoints(missingPt1, missingPt2)) {
                SkTSwap(missingPt1, missingPt2);
            }
            addTo1->addTCancel(missingPt1, missingPt2, addOther1);
        } else {
            if (addTo2->reversePoints(missingPt1, missingPt2)) {
                SkTSwap(missingPt1, missingPt2);
            }
            addTo2->addTCancel(missingPt1, missingPt2, addOther2);
        }
    } else if (missingT1 >= 0) {
        SkAssertResult(addTo1->addTCoincident(missingPt1, missingPt2,
                addTo1 == addTo2 ? missingT2 : otherT2, addOther1));
    } else {
        SkAssertResult(addTo2->addTCoincident(missingPt2, missingPt1,
                addTo2 == addTo1 ? missingT1 : otherT1, addOther2));
    }
}

void SkOpContour::joinCoincidence(const SkTArray<SkCoincidence, true>& coincidences, bool partial) {
    int count = coincidences.count();
#if DEBUG_CONCIDENT
    if (count > 0) {
        SkDebugf("%s count=%d\n", __FUNCTION__, count);
    }
#endif
    // look for a lineup where the partial implies another adjoining coincidence
    for (int index = 0; index < count; ++index) {
        const SkCoincidence& coincidence = coincidences[index];
        int thisIndex = coincidence.fSegments[0];
        SkOpSegment& thisOne = fSegments[thisIndex];
        if (thisOne.done()) {
            continue;
        }
        SkOpContour* otherContour = coincidence.fOther;
        int otherIndex = coincidence.fSegments[1];
        SkOpSegment& other = otherContour->fSegments[otherIndex];
        if (other.done()) {
            continue;
        }
        double startT = coincidence.fTs[0][0];
        double endT = coincidence.fTs[0][1];
        if (startT == endT) {  // this can happen in very large compares
            continue;
        }
        double oStartT = coincidence.fTs[1][0];
        double oEndT = coincidence.fTs[1][1];
        if (oStartT == oEndT) {
            continue;
        }
        bool swapStart = startT > endT;
        bool swapOther = oStartT > oEndT;
        const SkPoint* startPt = &coincidence.fPts[0][0];
        const SkPoint* endPt = &coincidence.fPts[0][1];
        if (swapStart) {
            SkTSwap(startT, endT);
            SkTSwap(oStartT, oEndT);
            SkTSwap(startPt, endPt);
        }
        bool cancel = swapOther != swapStart;
        int step = swapStart ? -1 : 1;
        int oStep = swapOther ? -1 : 1;
        double oMatchStart = cancel ? oEndT : oStartT;
        if (partial ? startT != 0 || oMatchStart != 0 : (startT == 0) != (oMatchStart == 0)) {
            bool added = false;
            if (oMatchStart != 0) {
                const SkPoint& oMatchStartPt = cancel ? *endPt : *startPt;
                added = thisOne.joinCoincidence(&other, oMatchStart, oMatchStartPt, oStep, cancel);
            }
            if (!cancel && startT != 0 && !added) {
                (void) other.joinCoincidence(&thisOne, startT, *startPt, step, cancel);
            }
        }
        double oMatchEnd = cancel ? oStartT : oEndT;
        if (partial ? endT != 1 || oMatchEnd != 1 : (endT == 1) != (oMatchEnd == 1)) {
            bool added = false;
            if (cancel && endT != 1 && !added) {
                (void) other.joinCoincidence(&thisOne, endT, *endPt, -step, cancel);
            }
        }
    }
}

bool SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
    if (coincidence.fNearly[0] && coincidence.fNearly[1]) {
        return true;
    }
    int thisIndex = coincidence.fSegments[0];
    SkOpSegment& thisOne = fSegments[thisIndex];
    if (thisOne.done()) {
        return true;
    }
    SkOpContour* otherContour = coincidence.fOther;
    int otherIndex = coincidence.fSegments[1];
    SkOpSegment& other = otherContour->fSegments[otherIndex];
    if (other.done()) {
        return true;
    }
    double startT = coincidence.fTs[0][0];
    double endT = coincidence.fTs[0][1];
    const SkPoint* startPt = &coincidence.fPts[0][0];
    const SkPoint* endPt = &coincidence.fPts[0][1];
    bool cancelers;
    if ((cancelers = startT > endT)) {
        SkTSwap<double>(startT, endT);
        SkTSwap<const SkPoint*>(startPt, endPt);
    }
    bump_out_close_span(&startT, &endT);
    SkASSERT(!approximately_negative(endT - startT));
    double oStartT = coincidence.fTs[1][0];
    double oEndT = coincidence.fTs[1][1];
    if (oStartT > oEndT) {
        SkTSwap<double>(oStartT, oEndT);
        cancelers ^= true;
    }
    bump_out_close_span(&oStartT, &oEndT);
    SkASSERT(!approximately_negative(oEndT - oStartT));
    bool success = true;
    if (cancelers) {
        thisOne.addTCancel(*startPt, *endPt, &other);
    } else {
        success = thisOne.addTCoincident(*startPt, *endPt, endT, &other);
    }
#if DEBUG_CONCIDENT
    thisOne.debugShowTs("p");
    other.debugShowTs("o");
#endif
    return success;
}

void SkOpContour::resolveNearCoincidence() {
    int count = fCoincidences.count();
    for (int index = 0; index < count; ++index) {
        SkCoincidence& coincidence = fCoincidences[index];
        if (!coincidence.fNearly[0] || !coincidence.fNearly[1]) {
            continue;
        }
        int thisIndex = coincidence.fSegments[0];
        SkOpSegment& thisOne = fSegments[thisIndex];
        SkOpContour* otherContour = coincidence.fOther;
        int otherIndex = coincidence.fSegments[1];
        SkOpSegment& other = otherContour->fSegments[otherIndex];
        if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) {
            // OPTIMIZATION: remove from coincidence array
            continue;
        }
    #if DEBUG_CONCIDENT
        thisOne.debugShowTs("-");
        other.debugShowTs("o");
    #endif
        double startT = coincidence.fTs[0][0];
        double endT = coincidence.fTs[0][1];
        bool cancelers;
        if ((cancelers = startT > endT)) {
            SkTSwap<double>(startT, endT);
        }
        if (startT == endT) { // if span is very large, the smaller may have collapsed to nothing
            if (endT <= 1 - FLT_EPSILON) {
                endT += FLT_EPSILON;
                SkASSERT(endT <= 1);
            } else {
                startT -= FLT_EPSILON;
                SkASSERT(startT >= 0);
            }
        }
        SkASSERT(!approximately_negative(endT - startT));
        double oStartT = coincidence.fTs[1][0];
        double oEndT = coincidence.fTs[1][1];
        if (oStartT > oEndT) {
            SkTSwap<double>(oStartT, oEndT);
            cancelers ^= true;
        }
        SkASSERT(!approximately_negative(oEndT - oStartT));
        if (cancelers) {
            thisOne.blindCancel(coincidence, &other);
        } else {
            thisOne.blindCoincident(coincidence, &other);
        }
    }
}

void SkOpContour::sortAngles() {
    int segmentCount = fSegments.count();
    for (int test = 0; test < segmentCount; ++test) {
        fSegments[test].sortAngles();
    }
}

void SkOpContour::sortSegments() {
    int segmentCount = fSegments.count();
    fSortedSegments.push_back_n(segmentCount);
    for (int test = 0; test < segmentCount; ++test) {
        fSortedSegments[test] = &fSegments[test];
    }
    SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1);
    fFirstSorted = 0;
}

void SkOpContour::toPath(SkPathWriter* path) const {
    int segmentCount = fSegments.count();
    const SkPoint& pt = fSegments.front().pts()[0];
    path->deferredMove(pt);
    for (int test = 0; test < segmentCount; ++test) {
        fSegments[test].addCurveTo(0, 1, path, true);
    }
    path->close();
}

void SkOpContour::topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY,
        SkOpSegment** topStart) {
    int segmentCount = fSortedSegments.count();
    SkASSERT(segmentCount > 0);
    int sortedIndex = fFirstSorted;
    fDone = true;  // may be cleared below
    for ( ; sortedIndex < segmentCount; ++sortedIndex) {
        SkOpSegment* testSegment = fSortedSegments[sortedIndex];
        if (testSegment->done()) {
            if (sortedIndex == fFirstSorted) {
                ++fFirstSorted;
            }
            continue;
        }
        fDone = false;
        SkPoint testXY = testSegment->activeLeftTop(NULL);
        if (*topStart) {
            if (testXY.fY < topLeft.fY) {
                continue;
            }
            if (testXY.fY == topLeft.fY && testXY.fX < topLeft.fX) {
                continue;
            }
            if (bestXY->fY < testXY.fY) {
                continue;
            }
            if (bestXY->fY == testXY.fY && bestXY->fX < testXY.fX) {
                continue;
            }
        }
        *topStart = testSegment;
        *bestXY = testXY;
    }
}

SkOpSegment* SkOpContour::undoneSegment(int* start, int* end) {
    int segmentCount = fSegments.count();
    for (int test = 0; test < segmentCount; ++test) {
        SkOpSegment* testSegment = &fSegments[test];
        if (testSegment->done()) {
            continue;
        }
        testSegment->undoneSpan(start, end);
        return testSegment;
    }
    return NULL;
}

#if DEBUG_SHOW_WINDING
int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) {
    int count = fSegments.count();
    int sum = 0;
    for (int index = 0; index < count; ++index) {
        sum += fSegments[index].debugShowWindingValues(totalSegments, ofInterest);
    }
//      SkDebugf("%s sum=%d\n", __FUNCTION__, sum);
    return sum;
}

void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList) {
//     int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13;
//    int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16;
    int ofInterest = 1 << 5 | 1 << 8;
    int total = 0;
    int index;
    for (index = 0; index < contourList.count(); ++index) {
        total += contourList[index]->segments().count();
    }
    int sum = 0;
    for (index = 0; index < contourList.count(); ++index) {
        sum += contourList[index]->debugShowWindingValues(total, ofInterest);
    }
//       SkDebugf("%s total=%d\n", __FUNCTION__, sum);
}
#endif

void SkOpContour::setBounds() {
    int count = fSegments.count();
    if (count == 0) {
        SkDebugf("%s empty contour\n", __FUNCTION__);
        SkASSERT(0);
        // FIXME: delete empty contour?
        return;
    }
    fBounds = fSegments.front().bounds();
    for (int index = 1; index < count; ++index) {
        fBounds.add(fSegments[index].bounds());
    }
}
