/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
add unit test for quadratic horizontal intersection
add unit test for cubic horizontal intersection with left/right
add unit test for ActiveEdge::calcLeft (can currently loop forever)
does ActiveEdge::isCoincidentWith need to support quad, cubic?
figure out why variation in ActiveEdge::tooCloseToCall isn't better
why does 'lastPtr - 2' in addIntersectingTs break testSimplifyTriangle22?
add code to promote quad to cubic, or add quad/cubic intersection
figure out why testSimplifySkinnyTriangle13 fails

for quadratics and cubics, once various T values are added, see if consecutive
Ts have ys that go up instead of down. If so, the edge needs to be broken.

when splitting curves at inflection pts, should I retain the original curve
data and note that the first/last T are no longer 0/1 ?
I need to figure this out before I can proceed

would it make sense to leave the InEdge alone, and add multiple copies of
ActiveEdge, pointing to the same InEdge, where the copy has only the subset
of Ts that need to be walked in reverse order?


-- A Digression Which Shows Why Resolving Coincidence Does Not Make Sense --

Consider the following fine ASCII art:

  +------>-------+       +------>-------+
  |              |       |              |
  ^              V       ^              V
  |              |       |              |
  +------<-------+       +------<-------+
  +------>-------+       +------<-------+
  |              |       |              |
  ^              V       V              ^
  |              |       |              |
  +------<-------+       +------>-------+

(assume the bottom and top of the stacked rectangles are coincident)

Simplifying said rectangles, regardless of rectangle direction, and regardless
of winding or even/odd, eliminates the coincident edge, i.e., the result is
always:

  +------>-------+
  |              |
  |              |
  |              |
  ^              V
  |              |
  |              |
  |              |
  +------<-------+

But when the rectangles are enclosed in a larger rectangle:

+-------->---------+    +-------->---------+
| +------>-------+ |    | +------>-------+ |
| |              | |    | |              | |
| ^              V |    | ^              V |
| |              | |    | |              | |
| +------<-------+ |    | +------<-------+ |
| +------>-------+ |    | +------<-------+ |
| |              | |    | |              | |
| ^              V |    | V              ^ |
| |              | |    | |              | |
| +------<-------+ |    | +------>-------+ |
+--------<---------+    +--------<---------+

Simplifying them gives different results depending on the winding setting:

winding:
+-------->---------+    +-------->---------+
|                  |    |                  |
|                  |    |                  |
|                  |    |                  |
|                  |    |                  |
|                  |    | +------<-------+ |
|                  |    | |              | |
|                  |    | V              ^ |
|                  |    | |              | |
|                  |    | +------>-------+ |
+--------<---------+    +--------<---------+

even odd:
+-------->---------+    +-------->---------+
| +------<-------+ |    | +------<-------+ |
| |              | |    | |              | |
| |              | |    | |              | |
| |              | |    | |              | |
| |              | |    | |              | |
| V              ^ |    | V              ^ |
| |              | |    | |              | |
| |              | |    | |              | |
| |              | |    | |              | |
| +------>-------+ |    | +------>-------+ |
+--------<---------+    +--------<---------+

So, given the inner rectangles alone (e.g., given coincident pairs in some local
context), we can't know whether to keep the coincident edges or not.


-- Thoughts About Sortless Ops --

I can't come up with anything truly sortless. It seems that the crossings need
to be sorted to know which segment is next on the outside, although sometimes
we can use that it is not coincident just to follow the direction.

If it is coincident or if there's more than two crossing segments, sorting
seems inevitable.

Likewise, to resolve whether one contour is inside another, it seems that
sorting is required. Given a pair of segments on different contours, to know
if one is inside of the other, I need to know for each which side of the edge
is the inside/filled side. When the outer contour is walked, it seems like I
could record the inside info. I guess when the inner contour is found, its
inside sense is reversed (inside is above the top). But how do I know if the
next contour is inside another? Maybe shoot out a line and brute-force
intersect it with all the segments in all the other contours? If every contour
has an extra segment when the intersections are computed, this may not be as
crazy as it seems.

Suppose each contour has one extra segment shooting straight up from the top
(or straight up from any point on the segment). This ray is not intersected
with the home contour, but is intersected with all other contours as part of
the normal intersection engine. If it is possible to get from the T values to
the other segments to the other contours, it would be straightforward to
count the contour crossings and determine if the home contour is in another
contour or not (if the count is even, not, if odd, is inside). By itself that
doesn't tell us about winding, but it's a start.


Since intersecting these rays is unrelated to computing other intersections,
it can be lazily done once the contour is found.

So
repeat the following
find the top segment of all contours
trace the outside, marking touching first and last segments as inside
continue tracing the touched segments with reversed outside/inside sense
once the edges are exhausted, remaining must be disjoint contours
send a ray from a disjoint point through all other contours
count the crossings, determine if disjoint is inside or outside, then continue

===

On Quadratic (and Cubic) Intersections

Currently, if only the end points touch, QuadracticIntersections does a lot of
work to figure that out. Can I test for that up front, then short circuit the
recursive search for the end points?

Or, is there something defective in the current approach that makes the end
point recursion go so deep? I'm seeing 56 stack frames (about 28 divides, but
thankfully, no splits) to find one matching endpoint.


Bezier curve focus may allow more quickly determining that end points with
identical tangents are practically coicident for some range of T, but I don't
understand the math yet to know.

Another approach is to determine how flat the curve is to make good guesses
about how far to move away in T before doing the intersection for the remainder
and/or to determine whether one curve is to the inside or outside of another.
According to Mike/Rob, the flatness for quadratics increases by 4 for each
subdivision, and a crude guess of the curvature can be had by comparing P1 to
(P0+P2)/2. By looking at the ULPS of the numbers, I can guess what value of
T may be far enough that the curves diverge but don't cross.

====

Code I May Not Need Any More

    static bool CoincidentCandidate(const Angle* current) {
        const Segment* segment = current->segment();
        int min = SkMin32(current->start(), current->end());
        do {
            const Span& span = segment->fTs[min];
            if (span.fCoincident == Span::kStart_Coincidence) {
                return true;
            }
        } while (--min >= 0);
        return false;
    }

    static bool CoincidentHalf(const Angle* current, const Angle* next) {
        const Segment* other = next->segment();
        const Segment* segment = current->segment();
        int min = SkMin32(current->start(), current->end());
        const Span& minSpan = segment->fTs[min];
        if (minSpan.fOther == other) {
            return minSpan.fCoincident == Span::kStart_Coincidence;
        }
        int index = min;
        int spanCount = segment->fTs.count();
        while (++index < spanCount) {
            const Span& span = segment->fTs[index];
            if (minSpan.fT != span.fT) {
                break;
            }
            if (span.fOther != other) {
                continue;
            }
            return span.fCoincident == Span::kStart_Coincidence;
        }
        index = min;
        while (--index >= 0) {
            const Span& span = segment->fTs[index];
            if (span.fOther != other) {
                continue;
            }
            return span.fCoincident == Span::kStart_Coincidence;
        }
        return false;
    }
    
    static bool Coincident(const Angle* current, const Angle* next) {
        return CoincidentHalf(current, next) &&
                CoincidentHalf(next, current);
    }

    // If three lines cancel in a - b - c order, a - b may or may not
    // eliminate the edge that describes the b - c cancellation. Check done to
    // determine this.
    static bool CoincidentCancels(const Angle* current, const Angle* next) {
        int curMin = SkMin32(current->start(), current->end());
        if (current->segment()->fTs[curMin].fDone) {
            return false;
        }
        int nextMin = SkMin32(next->start(), next->end());
        if (next->segment()->fTs[nextMin].fDone) {
            return false;
        }
        return SkSign32(current->start() - current->end())
                != SkSign32(next->start() - next->end());
    }

    // FIXME: at this point, just have two functions for the different steps
    int coincidentEnd(int from, int step) const {
        double fromT = fTs[from].fT;
        int count = fTs.count();
        int to = from;
        while (step > 0 ? ++to < count : --to >= 0) {
            const Span& span = fTs[to];
            if ((step > 0 ? span.fT - fromT : fromT - span.fT) >= FLT_EPSILON ) {
                // FIXME: we assume that if the T changes, we don't care about 
                // coincident -- but in nextSpan, we require that both the T
                // and actual loc change to represent a span. This asymettry may
                // be OK or may be trouble -- if trouble, probably will need to
                // detect coincidence earlier or sort differently 
                break;
            }
#if 01
            if (span.fCoincident == (step < 0 ? Span::kStart_Coincidence :
                    Span::kEnd_Coincidence)) {
                from = to;
            }
#else
            from = to;
#endif
        }
        return from;
    }

    // once past current span, if step>0, look for coicident==1
    // if step<0, look for coincident==-1
    int nextSpanEnd(int from, int step) const {
        int result = nextSpan(from, step);
        if (result < 0) {
            return result;
        }
        return coincidentEnd(result, step);
    }

    
    void adjustFirst(const SkTDArray<Angle*>& sorted, int& first, int& winding,
            bool outside) {
        int firstIndex = first;
        int angleCount = sorted.count();
        if (true || outside) {
            const Angle* angle = sorted[firstIndex];
            int prior = firstIndex;
            do {
                if (--prior < 0) {
                    prior = angleCount - 1;
                }
                if (prior == firstIndex) { // all are coincident with each other
                    return;
                }
                if (!Coincident(sorted[prior], sorted[first])) {
                    return;
                }
                winding += angle->sign();
                first = prior;
                angle = sorted[prior];
                winding -= angle->sign();
            } while (true);
        }
        do {
            int next = first + 1;
            if (next == angleCount) {
                next = 0;
            }
            if (next == firstIndex) { // all are coincident with each other
                return;
            }
            if (!Coincident(sorted[first], sorted[next])) {
                return;
            }
            first = next;
        } while (true);
    }

            bool nextIsCoincident = CoincidentCandidate(nextAngle);
            bool finalOrNoCoincident = true;
            bool pairCoincides = false;
            bool pairCancels = false;
            if (nextIsCoincident) {
                int followIndex = nextIndex + 1;
                if (followIndex == angleCount) {
                    followIndex = 0;
                }
                const Angle* followAngle = sorted[followIndex];
                finalOrNoCoincident = !Coincident(nextAngle, followAngle);
                if ((pairCoincides = Coincident(angle, nextAngle))) {
                    pairCancels = CoincidentCancels(angle, nextAngle);
                }
            }
            if (pairCancels && !foundAngle && !nextSegment->done()) {
                Segment* aSeg = angle->segment();
      //          alreadyMarked |= aSeg == sorted[firstIndex]->segment();
                aSeg->markAndChaseCoincident(angle->start(), angle->end(),
                        nextSegment);
                if (firstEdge) {
                    return NULL;
                }
            }
            if (pairCoincides) {
                if (pairCancels) {
                    goto doNext;
                }
                int minT = SkMin32(nextAngle->start(), nextAngle->end());
                bool markNext = abs(maxWinding) < abs(winding);
                if (markNext) {
                    nextSegment->markDone(minT, winding);
                } 
                int oldMinT = SkMin32(angle->start(), angle->end());
                if (true || !foundAngle) {
                 //   SkASSERT(0); // do we ever get here?
                    Segment* aSeg = angle->segment();
        //            alreadyMarked |= aSeg == sorted[firstIndex]->segment();
                    aSeg->markDone(oldMinT, maxWinding);
                }
            }

    // OPTIMIZATION: uses tail recursion. Unwise?
    void innerCoincidentChase(int step, Segment* other) {
        // find other at index
   //     SkASSERT(!done());
        const Span* start = NULL;
        const Span* end = NULL;
        int index, startIndex, endIndex;
        int count = fTs.count();
        for (index = 0; index < count; ++index) {
            const Span& span = fTs[index];
            if (!span.fCoincident || span.fOther != other) {
                continue;
            }
            if (!start) {
                startIndex = index;
                start = &span;
            } else {
                SkASSERT(!end);
                endIndex = index;
                end = &span;
            }
        }
        if (!end) {
            return;
        }
        bool thisDone = fTs[SkMin32(startIndex, endIndex)].fDone;
        bool otherDone = other->fTs[SkMin32(start->fOtherIndex,
                end->fOtherIndex)].fDone;
        if (thisDone && otherDone) {
            return;
        }
        Segment* next;
        Segment* nextOther;
        if (step < 0) {
            next = start->fT == 0 ? NULL : this;
            nextOther = other->fTs[start->fOtherIndex].fT > 1 - FLT_EPSILON ? NULL : other;
        } else {
            next = end->fT == 1 ? NULL : this;
            nextOther = other->fTs[end->fOtherIndex].fT < FLT_EPSILON ? NULL : other;
        }
        SkASSERT(!next || !nextOther);
        for (index = 0; index < count; ++index) {
            const Span& span = fTs[index];
            if (span.fCoincident || span.fOther == other) {
                continue;
            }
            bool checkNext = !next && (step < 0 ? span.fT < FLT_EPSILON
                && span.fOtherT > 1 - FLT_EPSILON : span.fT > 1 - FLT_EPSILON
                && span.fOtherT < FLT_EPSILON);
            bool checkOther = !nextOther && (step < 0 ? fabs(span.fT - start->fT) < FLT_EPSILON
                && span.fOtherT < FLT_EPSILON : fabs(span.fT - end->fT) < FLT_EPSILON
                && span.fOtherT > 1 - FLT_EPSILON);
            if (!checkNext && !checkOther) {
                continue;
            }
            Segment* oSegment = span.fOther;
            if (oSegment->done()) {
                continue;
            }
            int oCount = oSegment->fTs.count();
            for (int oIndex = 0; oIndex < oCount; ++oIndex) {
                const Span& oSpan = oSegment->fTs[oIndex];
                if (oSpan.fT >= FLT_EPSILON && oSpan.fT <= 1 - FLT_EPSILON) {
                    continue;
                }
                if (!oSpan.fCoincident) {
                    continue;
                }
                if (checkNext && (oSpan.fT < FLT_EPSILON ^ step < 0)) { 
                    next = oSegment;
                    checkNext = false;
                }
                if (checkOther && (oSpan.fT > 1 - FLT_EPSILON ^ step < 0)) {
                    nextOther = oSegment;
                    checkOther = false;
                }
            }
        }
        // this needs to walk both spans in lock step, skipping edges that
        // are already marked done on one or the other
        markCanceled(startIndex, endIndex);
        if (next && nextOther) {
            next->innerCoincidentChase(step, nextOther);
        }
    }

    // cancel coincident edges in lock step
    void markCanceled(int start, int end) {
        if (done()) {
            return;
        }
        Segment* other = fTs[start].fOther;
        if (other->done()) {
            return;
        }
        if (start > end) {
            SkTSwap<int>(start, end);
        }
        double maxT = fTs[end].fT - FLT_EPSILON;
        int spanCount = fTs.count();
        // since these cancel, this walks up and other walks down
        int oStart = fTs[start].fOtherIndex;
        double oStartT = other->fTs[oStart].fT;
        while (oStartT - other->fTs[--oStart].fT < FLT_EPSILON)
            ;
        double startT = fTs[start].fT;
        while (start > 0 && startT - fTs[start - 1].fT < FLT_EPSILON) {
            --start;
        }
        do {
            Span* span = &fTs[start];
            Span* oSpan = &other->fTs[oStart];
            // find start of each, and see if both are not done
            bool markDone = !span->fDone && !oSpan->fDone;
            double spanT = span->fT;
            do {
                if (markDone) {
                    span->fCanceled = true;
                #if DEBUG_MARK_DONE
                    const SkPoint& pt = xyAtT(span);
                    SkDebugf("%s segment=%d index=%d t=%1.9g pt=(%1.9g,%1.9g)\n",
                            __FUNCTION__, fID, start, span->fT, pt.fX, pt.fY);
                #endif
                    SkASSERT(!span->fDone);
                    span->fDone = true;
                    span->fWinding = 0;
                    fDoneSpans++;
                }
                if (++start == spanCount) {
                    break;
                }
                span = &fTs[start];
            } while (span->fT - spanT < FLT_EPSILON);
            double oSpanT = oSpan->fT;
            do {
                if (markDone) {
                    oSpan->fCanceled = true;
                #if DEBUG_MARK_DONE
                    const SkPoint& oPt = xyAtT(oSpan);
                    SkDebugf("%s segment=%d index=%d t=%1.9g pt=(%1.9g,%1.9g)\n",
                            __FUNCTION__, other->fID, oStart, oSpan->fT,
                            oPt.fX, oPt.fY);
                #endif
                    SkASSERT(!oSpan->fDone);
                    oSpan->fDone = true;
                    oSpan->fWinding = 0;
                    other->fDoneSpans++;
                }
                if (--oStart < 0) {
                    break;
                }
                oSpan = &other->fTs[oStart];
            } while (oSpanT - oSpan->fT < FLT_EPSILON);
        } while (fTs[start].fT <= maxT);
    }

    bool canceled(int start, int end) const {
        int min = SkMin32(start, end);
        return fTs[min].fCanceled;
    }

    void markAndChaseCoincident(int index, int endIndex, Segment* other) {
        int step = SkSign32(endIndex - index);
        innerCoincidentChase(step, other);
    }

