
/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */



////////////////////////////////////////////////////////////////////////////////
// This is an implementation of the triangulation algorithm described by Alain
// Fournier and Delfin Montuno, in "Triangulating Simple Polygons and Equivalent
// Problems", in the ACM Transactions on Graphics, vol. 3, no. 2, April 1984,
// pp. 153-174.
//
// No new vertices are created in the triangulation: triangles are constructed
// only from the points in the original polygon, so there is no possibility for
// cracks to develop from finite precision arithmetic.
////////////////////////////////////////////////////////////////////////////////

// TODO:
// - RemoveDegenerateTrapezoids() was added to make the code robust, but it
//   unfortunately introduces T-vertices. Make it robust without T-vertices.
// - It should be easy enough to detect whether the outer contour is right- or
//   left-handed by looking at the top vertex, which is available in the
//   pre-sort during trapezoidization. Use this information in angleIsConvex()
//   to allowed either handedness outer contour. In either case, though, holes
//   need to have the opposite orientation.
// - SkTHeapSort was broken, so I wrote a bubble sort so that I could make other
//   things work. Use SkQSort() instead.
// - The ActiveTrapezoid array does a linear search which is O(n) inefficient.
//   Use SkSearch to implement O(log n) binary search and insertion sort.
// - There is no need to use SkTDArray for everything. Use SkAutoTMalloc for
//   everything else.

#include "SkTDArray.h"
#include "SkGeometry.h"
#include "SkTSort.h"

// This is used to prevent runaway code bugs, and can probably be removed after
// the code has been proven robust.
#define kMaxCount 1000

#define DEBUG
#ifdef DEBUG
//------------------------------------------------------------------------------
// Debugging support
//------------------------------------------------------------------------------

#include <cstdio>
#include <stdarg.h>

static int gDebugLevel = 0;   // This enables debug reporting.

static void DebugPrintf(const char *format, ...) {
    if (gDebugLevel > 0) {
        va_list ap;
        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);
    }
}

static void FailureMessage(const char *format, ...) {
    if (1) {
        printf("FAILURE: ");
        va_list ap;
        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);
    }
}
#else  // !DEBUG
inline void DebugPrintf(const char *format, ...) {}
inline void FailureMessage(const char *format, ...) {}
#endif  // DEBUG


// Forward declaration.
class Vertex;


//------------------------------------------------------------------------------
// The Trapezoid (actually, up to two of them) is embedded into a Vertex, whose
// point() provides the top of the Trapezoid, whereas the bottom, and the left
// and right edges, are stored in the Trapezoid. The edges are represented by
// their tail point; the head is the successive point modulo the number of
// points in the polygon. Only the Y coordinate of the top and bottom are
// relevant.
//------------------------------------------------------------------------------
class Trapezoid {
public:
    const Vertex* left()   const    { return fLeft;   }
    const Vertex* right()  const    { return fRight;  }
    const Vertex* bottom() const    { return fBottom; }
    Vertex* left()                  { return fLeft;   }
    Vertex* right()                 { return fRight;  }
    Vertex* bottom()                { return fBottom; }
    void   setLeft(Vertex *left)    { fLeft   = left;   }
    void  setRight(Vertex *right)   { fRight  = right;  }
    void setBottom(Vertex *bottom)  { fBottom = bottom; }
    void nullify()                  { setBottom(NULL); }

    bool operator<(Trapezoid &t1)   { return compare(t1) < 0; }
    bool operator>(Trapezoid &t1)   { return compare(t1) > 0; }

private:
    Vertex *fLeft, *fRight, *fBottom;

    // These return a number that is less than, equal to, or greater than zero
    // depending on whether the trapezoid or point is to the left, on, or to the
    // right.
    SkScalar compare(const Trapezoid &t1) const;
    SkScalar compare(const SkPoint &p) const;
};


//------------------------------------------------------------------------------
// The ActiveTrapezoids are a sorted list containing the currently active
// trapezoids, i.e. those that have the top, left, and right, but still need the
// bottom. This could use some optimization, to reduce search time from O(n) to
// O(log n).
//------------------------------------------------------------------------------
class ActiveTrapezoids {
public:
    ActiveTrapezoids() { fTrapezoids.setCount(0); }

    size_t count() const { return fTrapezoids.count(); }

    // Select an unused trapezoid from the Vertex vt, initialize it with the
    // left and right edges, and insert it into the sorted list.
    bool insertNewTrapezoid(Vertex *vt, Vertex *left, Vertex *right);

    // Remove the specified Trapezoids from the active list.
    void remove(Trapezoid *t);

    // Determine whether the given point lies within any active trapezoid, and
    // return a pointer to that Trapezoid.
    bool withinActiveTrapezoid(const SkPoint &pt, Trapezoid **tp);

    // Find an active trapezoid that contains the given edge.
    Trapezoid* getTrapezoidWithEdge(const Vertex *edge);

private:
    // Insert the specified Trapezoid into the sorted list.
    void insert(Trapezoid *t);

    // The sorted list of active trapezoids. This is O(n), and would benefit
    // a 2-3 tree o achieve O(log n).
    SkTDArray<Trapezoid*> fTrapezoids;  // Fournier suggests a 2-3 tree instead.
};


//------------------------------------------------------------------------------
// The Vertex is used to communicate information between the various phases of
// triangulation.
//------------------------------------------------------------------------------
class Vertex {
public:
    enum VertexType { MONOTONE, CONVEX, CONCAVE };

    Trapezoid fTrap0;
    Trapezoid fTrap1;

    const SkPoint &point() const        { return fPoint; }
    void setPoint(const SkPoint &point) { fPoint = point; }

    // The next and previous vertices around the polygon.
    Vertex *next()                      { return fNext; }
    Vertex *prev()                      { return fPrev; }
    const Vertex *next() const          { return fNext; }
    const Vertex *prev() const          { return fPrev; }
    void setNext(Vertex *next)          { fNext = next; }
    void setPrev(Vertex *prev)          { fPrev = prev; }

    void setDone(bool done)             { fDone = done; }
    bool done() const                   { return fDone; }

    // Trapezoid accessors return non-null for any complete trapezoids.
    void trapezoids(Trapezoid **trap0, Trapezoid **trap1) {
        *trap0 = (fTrap0.bottom() != NULL) ? &fTrap0 : NULL;
        *trap1 = (fTrap1.bottom() != NULL) ? &fTrap1 : NULL;
    }

    // Eliminate a trapezoid.
    void nullifyTrapezoid() {
        if (fTrap1.bottom() != NULL) {
            DebugPrintf("Unexpected non-null second trapezoid.\n");
            fTrap1.nullify();
            return;
        }
        fTrap0.nullify();
    }

    // Determine whether the edge specified by this Vertex shares the given top
    // and bottom.
    bool shareEdge(Vertex *top, Vertex *bottom);

    // Determines whether the angle specified by { prev, this, next } is convex.
    // Note that collinear is considered to be convex.
    bool angleIsConvex();

    // Remove this Vertex from the { prev, next } linked list.
    void delink() {
        Vertex *p = prev(),
               *n = next();
        p->setNext(n);
        n->setPrev(p);
    }

    // Return a number that is less than, equal to, or greater than zero
    // depending on whether the point is to the left, on, or to the right of the
    // edge that has this Vertex as a base.
    SkScalar compare(const SkPoint &pt) const;

    // Classify the vertex, and return its sorted edges.
    VertexType classify(Vertex **e0, Vertex **e1);

    // This helps determine unimonotonicity.
    Vertex *diagonal();

private:
    SkPoint fPoint;
    Vertex *fNext;
    Vertex *fPrev;
    bool fDone;
};


bool Vertex::angleIsConvex() {
    SkPoint vPrev = prev()->point() - point(),
            vNext = next()->point() - point();
    // TODO(turk): There might be overflow in fixed-point.
    return SkPoint::CrossProduct(vNext, vPrev) >= 0;
}


bool Vertex::shareEdge(Vertex *top, Vertex *bottom) {
    return (((this == top)    && (this->next() == bottom)) ||
            ((this == bottom) && (this->next() == top)));
}


SkScalar Vertex::compare(const SkPoint &pt) const  {
    SkPoint ve = next()->point() - point(),
            vp = pt              - point();
    SkScalar d;
    if (ve.fY == 0) {
        // Return twice the distance to the center of the horizontal edge.
        d = ve.fX + pt.fX - next()->point().fX;
    } else {
        // Return the distance to the edge, scaled by the edge length.
        d = SkPoint::CrossProduct(ve, vp);
        if (ve.fY > 0) d = -d;
    }
    return d;
}


SkScalar Trapezoid::compare(const SkPoint &pt) const {
    SkScalar d = left()->compare(pt);
    if (d <= 0)
        return d;   // Left of the left edge.
    d = right()->compare(pt);
    if (d >= 0)
        return d;   // Right of the right edge.
    return 0;       // Somewhere between the left and the right edges.
}



SkScalar Trapezoid::compare(const Trapezoid &t1) const {
#if 1
    SkScalar d = left()->compare(t1.left()->point());
    if (d == 0)
        d = right()->compare(t1.right()->point());
    return d;
#else
    SkScalar dl =  left()->compare( t1.left()->point()),
             dr = right()->compare(t1.right()->point());
    if (dl < 0 && dr < 0)
        return dr;
    if (dl > 0 && dr > 0)
        return dl;
    return 0;
#endif
}


Trapezoid* ActiveTrapezoids::getTrapezoidWithEdge(const Vertex *edge) {
    DebugPrintf("Entering getTrapezoidWithEdge(): looking through %d\n",
           fTrapezoids.count());
    DebugPrintf("trying to find %p: ", edge);
    Trapezoid **tp;
    for (tp = fTrapezoids.begin(); tp < fTrapezoids.end(); ++tp) {
        SkASSERT(tp != NULL);
        SkASSERT(*tp != NULL);
        DebugPrintf("%p and %p, ", (**tp).left(), (**tp).right());
        if ((**tp).left() == edge || (**tp).right() == edge) {
            DebugPrintf("\ngetTrapezoidWithEdge found the trapezoid\n");
            return *tp;
        }
    }
    DebugPrintf("getTrapezoidWithEdge found no trapezoid\n");
    return NULL;
}


bool ActiveTrapezoids::insertNewTrapezoid(Vertex *vt,
                                          Vertex *left,
                                          Vertex *right) {
    DebugPrintf("Inserting a trapezoid...");
    if (vt->fTrap0.left() == NULL && vt->fTrap0.right() == NULL) {
        vt->fTrap0.setLeft(left);
        vt->fTrap0.setRight(right);
        insert(&vt->fTrap0);
    } else if (vt->fTrap1.left() == NULL && vt->fTrap1.right() == NULL) {
        DebugPrintf("a second one...");
        vt->fTrap1.setLeft(left);
        vt->fTrap1.setRight(right);
        if (vt->fTrap1 < vt->fTrap0) {  // Keep trapezoids sorted.
            remove(&vt->fTrap0);
            Trapezoid t = vt->fTrap0;
            vt->fTrap0 = vt->fTrap1;
            vt->fTrap1 = t;
            insert(&vt->fTrap0);
        }
        insert(&vt->fTrap1);
    } else {
        FailureMessage("More than 2 trapezoids requested for a vertex\n");
        return false;
    }
    DebugPrintf(" done. %d incomplete trapezoids\n", fTrapezoids.count());
    return true;
}


void ActiveTrapezoids::insert(Trapezoid *t) {
    Trapezoid **tp;
    for (tp = fTrapezoids.begin(); tp < fTrapezoids.end(); ++tp)
        if (**tp > *t)
            break;
    fTrapezoids.insert(tp - fTrapezoids.begin(), 1, &t);
    // SHOULD VERIFY THAT ALL TRAPEZOIDS ARE PROPERLY SORTED
}


void ActiveTrapezoids::remove(Trapezoid *t) {
    DebugPrintf("Removing a trapezoid...");
    for (Trapezoid **tp = fTrapezoids.begin(); tp < fTrapezoids.end(); ++tp) {
        if (*tp == t) {
            fTrapezoids.remove(tp - fTrapezoids.begin());
            DebugPrintf(" done.\n");
            return;
        }
    }
    DebugPrintf(" Arghh! Panic!\n");
    SkASSERT(t == 0);   // Cannot find t in active trapezoid list.
}


bool ActiveTrapezoids::withinActiveTrapezoid(const SkPoint &pt,
                                             Trapezoid **trap) {
    DebugPrintf("Entering withinActiveTrapezoid()\n");
    // This is where a good search data structure would be helpful.
    Trapezoid **t;
    for (t = fTrapezoids.begin(); t < fTrapezoids.end(); ++t) {
        if ((**t).left()->compare(pt) <= 0) {
            // The point is to the left of the left edge of this trapezoid.
            DebugPrintf("withinActiveTrapezoid: Before a trapezoid\n");
            *trap = *t;     // Return the place where a new trapezoid would go.
// We have a bug with the sorting -- look through everything.
            continue;
//             return false;   // Outside all trapezoids, since they are sorted.
        }
        // The point is to the right of the left edge of this trapezoid.

        if ((**t).right()->compare(pt) < 0) {
            // The point is to the left of the right edge.
            DebugPrintf("withinActiveTrapezoid: Within an Active Trapezoid\n");
            *trap = *t;
            return true;
        }
    }

    // The point is to the right of all trapezoids.
    DebugPrintf("withinActiveTrapezoid: After all trapezoids\n");
    *trap = NULL;
    return false;
}


Vertex* Vertex::diagonal() {
    Vertex *diag = NULL;
    if (fTrap0.bottom() != NULL) {
        if (!fTrap0.left() ->shareEdge(this, fTrap0.bottom()) &&
            !fTrap0.right()->shareEdge(this, fTrap0.bottom())
        ) {
            diag = fTrap0.bottom();
            fTrap0 = fTrap1;
            fTrap1.nullify();
        } else if (fTrap1.bottom() != NULL &&
                  !fTrap1.left() ->shareEdge(this, fTrap1.bottom()) &&
                  !fTrap1.right()->shareEdge(this, fTrap1.bottom())
        ) {
            diag = fTrap1.bottom();
            fTrap1.nullify();
        }
    }
    return diag;
}


// We use this to sort the edges vertically for a scan-conversion type of
// operation.
class VertexPtr {
public:
    Vertex *vt;
};


bool operator<(VertexPtr &v0, VertexPtr &v1) {
    // DebugPrintf("< %p %p\n", &v0, &v1);
    if (v0.vt->point().fY < v1.vt->point().fY)  return true;
    if (v0.vt->point().fY > v1.vt->point().fY)  return false;
    if (v0.vt->point().fX < v1.vt->point().fX)  return true;
    else                                        return false;
}


bool operator>(VertexPtr &v0, VertexPtr &v1) {
    // DebugPrintf("> %p %p\n", &v0, &v1);
    if (v0.vt->point().fY > v1.vt->point().fY)  return true;
    if (v0.vt->point().fY < v1.vt->point().fY)  return false;
    if (v0.vt->point().fX > v1.vt->point().fX)  return true;
    else                                        return false;
}


static void SetVertexPoints(size_t numPts, const SkPoint *pt, Vertex *vt) {
    for (; numPts-- != 0; ++pt, ++vt)
        vt->setPoint(*pt);
}


static void InitializeVertexTopology(size_t numPts, Vertex *v1) {
    Vertex *v0 = v1 + numPts - 1, *v_1 = v0 - 1;
    for (; numPts-- != 0; v_1 = v0, v0 = v1++) {
        v0->setPrev(v_1);
        v0->setNext(v1);
    }
}

Vertex::VertexType Vertex::classify(Vertex **e0, Vertex **e1) {
    VertexType type;
    SkPoint vPrev, vNext;
    vPrev.fX = prev()->point().fX - point().fX;
    vPrev.fY = prev()->point().fY - point().fY;
    vNext.fX = next()->point().fX - point().fX;
    vNext.fY = next()->point().fY - point().fY;

    // This can probably be simplified, but there are enough potential bugs,
    // we will leave it expanded until all cases are tested appropriately.
    if (vPrev.fY < 0) {
        if (vNext.fY > 0) {
            // Prev comes from above, Next goes below.
            type = MONOTONE;
            *e0 = prev();
            *e1 = this;
        } else if (vNext.fY < 0) {
            // The are both above: sort so that e0 is on the left.
            type = CONCAVE;
            if (SkPoint::CrossProduct(vPrev, vNext) <= 0) {
                *e0 = this;
                *e1 = prev();
            } else {
                *e0 = prev();
                *e1 = this;
            }
        } else {
            DebugPrintf("### py < 0, ny = 0\n");
            if (vNext.fX < 0) {
                type = CONCAVE;
                *e0 = this;     // flat to the left
                *e1 = prev();   // concave on the right
            } else {
                type = CONCAVE;
                *e0 = prev();   // concave to the left
                *e1 = this;     // flat to the right
            }
        }
    } else if (vPrev.fY > 0) {
        if (vNext.fY < 0) {
            // Next comes from above, Prev goes below.
            type = MONOTONE;
            *e0 = this;
            *e1 = prev();
        } else if (vNext.fY > 0) {
            // They are both below: sort so that e0 is on the left.
            type = CONVEX;
            if (SkPoint::CrossProduct(vPrev, vNext) <= 0) {
                *e0 = prev();
                *e1 = this;
            } else {
                *e0 = this;
                *e1 = prev();
            }
        } else {
            DebugPrintf("### py > 0, ny = 0\n");
            if (vNext.fX < 0) {
                type = MONOTONE;
                *e0 = this;     // flat to the left
                *e1 = prev();   // convex on the right - try monotone first
            } else {
                type = MONOTONE;
                *e0 = prev();   // convex to the left - try monotone first
                *e1 = this;     // flat to the right
            }
        }
    } else {  // vPrev.fY == 0
        if (vNext.fY < 0) {
            DebugPrintf("### py = 0, ny < 0\n");
            if (vPrev.fX < 0) {
                type = CONCAVE;
                *e0 = prev();   // flat to the left
                *e1 = this;     // concave on the right
            } else {
                type = CONCAVE;
                *e0 = this;     // concave on the left - defer
                *e1 = prev();   // flat to the right
            }
        } else if (vNext.fY > 0) {
            DebugPrintf("### py = 0, ny > 0\n");
            if (vPrev.fX < 0) {
                type = MONOTONE;
                *e0 = prev();   // flat to the left
                *e1 = this;     // convex on the right - try monotone first
            } else {
                type = MONOTONE;
                *e0 = this;     // convex to the left - try monotone first
                *e1 = prev();   // flat to the right
            }
        } else {
            DebugPrintf("### py = 0, ny = 0\n");
            // First we try concave, then monotone, then convex.
            if (vPrev.fX <= vNext.fX) {
                type = CONCAVE;
                *e0 = prev();   // flat to the left
                *e1 = this;     // flat to the right
            } else {
                type = CONCAVE;
                *e0 = this;     // flat to the left
                *e1 = prev();   // flat to the right
            }
        }
    }
    return type;
}


#ifdef DEBUG
static const char* GetVertexTypeString(Vertex::VertexType type) {
    const char *typeStr = NULL;
    switch (type) {
        case Vertex::MONOTONE:
            typeStr = "MONOTONE";
            break;
        case Vertex::CONCAVE:
            typeStr = "CONCAVE";
            break;
        case Vertex::CONVEX:
            typeStr = "CONVEX";
            break;
    }
    return typeStr;
}


static void PrintVertices(size_t numPts, Vertex *vt) {
    DebugPrintf("\nVertices:\n");
    for (size_t i = 0; i < numPts; i++) {
        Vertex *e0, *e1;
        Vertex::VertexType type = vt[i].classify(&e0, &e1);
        DebugPrintf("%2d: (%.7g, %.7g), prev(%d), next(%d), "
                    "type(%s), left(%d), right(%d)",
                    i, vt[i].point().fX, vt[i].point().fY,
                    vt[i].prev() - vt, vt[i].next() - vt,
                    GetVertexTypeString(type), e0 - vt, e1 - vt);
        Trapezoid *trap[2];
        vt[i].trapezoids(trap, trap+1);
        for (int j = 0; j < 2; ++j) {
            if (trap[j] != NULL) {
                DebugPrintf(", trap(L=%d, R=%d, B=%d)",
                            trap[j]->left()   - vt,
                            trap[j]->right()  - vt,
                            trap[j]->bottom() - vt);
            }
        }
        DebugPrintf("\n");
    }
}


static void PrintVertexPtrs(size_t numPts, VertexPtr *vp, Vertex *vtBase) {
    DebugPrintf("\nSorted Vertices:\n");
    for (size_t i = 0; i < numPts; i++) {
        Vertex *e0, *e1;
        Vertex *vt = vp[i].vt;
        Vertex::VertexType type = vt->classify(&e0, &e1);
        DebugPrintf("%2d: %2d: (%.7g, %.7g), prev(%d), next(%d), "
                    "type(%s), left(%d), right(%d)",
                    i, vt - vtBase, vt->point().fX, vt->point().fY,
                    vt->prev() - vtBase, vt->next() - vtBase,
                    GetVertexTypeString(type), e0 - vtBase, e1 - vtBase);
        Trapezoid *trap[2];
        vt->trapezoids(trap, trap+1);
        for (int j = 0; j < 2; ++j) {
            if (trap[j] != NULL) {
                DebugPrintf(", trap(L=%d, R=%d, B=%d)",
                            trap[j]->left()   - vtBase,
                            trap[j]->right()  - vtBase,
                            trap[j]->bottom() - vtBase);
            }
        }
        DebugPrintf("\n");
    }
}
#else  // !DEBUG
inline void PrintVertices(size_t numPts, Vertex *vt) {}
inline void PrintVertexPtrs(size_t numPts, VertexPtr *vp, Vertex *vtBase) {}
#endif  // !DEBUG


// SkTHeapSort is broken, so we use a bubble sort in the meantime.
template <typename T>
void BubbleSort(T *array, size_t count) {
    bool sorted;
    size_t count_1 = count - 1;
    do {
        sorted = true;
        for (size_t i = 0; i < count_1; ++i) {
            if (array[i + 1] < array[i]) {
                T t = array[i];
                array[i] = array[i + 1];
                array[i + 1] = t;
                sorted = false;
            }
        }
    } while (!sorted);
}


// Remove zero-height trapezoids.
static void RemoveDegenerateTrapezoids(size_t numVt, Vertex *vt) {
    for (; numVt-- != 0; vt++) {
        Trapezoid *traps[2];
        vt->trapezoids(traps, traps+1);
        if (traps[1] != NULL &&
                vt->point().fY >= traps[1]->bottom()->point().fY) {
            traps[1]->nullify();
            traps[1] = NULL;
        }
        if (traps[0] != NULL &&
                vt->point().fY >= traps[0]->bottom()->point().fY) {
            if (traps[1] != NULL) {
                *traps[0] = *traps[1];
                traps[1]->nullify();
            } else {
                traps[0]->nullify();
            }
        }
    }
}


// Enhance the polygon with trapezoids.
bool ConvertPointsToVertices(size_t numPts, const SkPoint *pts, Vertex *vta) {
    DebugPrintf("ConvertPointsToVertices()\n");

    // Clear everything.
    DebugPrintf("Zeroing vertices\n");
    sk_bzero(vta, numPts * sizeof(*vta));

    // Initialize vertices.
    DebugPrintf("Initializing vertices\n");
    SetVertexPoints(numPts, pts, vta);
    InitializeVertexTopology(numPts, vta);

    PrintVertices(numPts, vta);

    SkTDArray<VertexPtr> vtptr;
    vtptr.setCount(numPts);
    for (int i = numPts; i-- != 0;)
        vtptr[i].vt = vta + i;
    PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);
    DebugPrintf("Sorting vertrap ptr array [%d] %p %p\n", vtptr.count(),
        &vtptr[0], &vtptr[vtptr.count() - 1]
    );
//  SkTHeapSort(vtptr.begin(), vtptr.count());
    BubbleSort(vtptr.begin(), vtptr.count());
    DebugPrintf("Done sorting\n");
    PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);

    DebugPrintf("Traversing sorted vertrap ptrs\n");
    ActiveTrapezoids incompleteTrapezoids;
    for (VertexPtr *vtpp = vtptr.begin(); vtpp < vtptr.end(); ++vtpp) {
        DebugPrintf("%d: sorted vertrap %d\n",
                    vtpp - vtptr.begin(), vtpp->vt - vta);
        Vertex *vt = vtpp->vt;
        Vertex *e0, *e1;
        Trapezoid *t;
        switch (vt->classify(&e0, &e1)) {
            case Vertex::MONOTONE:
            monotone:
                DebugPrintf("MONOTONE %d %d\n", e0 - vta, e1 - vta);
                // We should find one edge.
                t = incompleteTrapezoids.getTrapezoidWithEdge(e0);
                if (t == NULL) {      // One of the edges is flat.
                    DebugPrintf("Monotone: cannot find a trapezoid with e0: "
                                "trying convex\n");
                    goto convex;
                }
                t->setBottom(vt);     // This trapezoid is now complete.
                incompleteTrapezoids.remove(t);

                if (e0 == t->left())  // Replace the left edge.
                    incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right());
                else                  // Replace the right edge.
                    incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e1);
                break;

            case Vertex::CONVEX:      // Start of a new trapezoid.
            convex:
                // We don't expect to find any edges.
                DebugPrintf("CONVEX %d %d\n", e0 - vta, e1 - vta);
                if (incompleteTrapezoids.withinActiveTrapezoid(
                        vt->point(), &t)) {
                    // Complete trapezoid.
                    SkASSERT(t != NULL);
                    t->setBottom(vt);
                    incompleteTrapezoids.remove(t);
                    // Introduce two new trapezoids.
                    incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e0);
                    incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right());
                } else {
                    // Insert a new trapezoid.
                    incompleteTrapezoids.insertNewTrapezoid(vt, e0, e1);
                }
                break;

            case Vertex::CONCAVE:   // End of a trapezoid.
                DebugPrintf("CONCAVE %d %d\n", e0 - vta, e1 - vta);
                // We should find two edges.
                t = incompleteTrapezoids.getTrapezoidWithEdge(e0);
                if (t == NULL) {
                    DebugPrintf("Concave: cannot find a trapezoid with e0: "
                                " trying monotone\n");
                    goto monotone;
                }
                SkASSERT(t != NULL);
                if (e0 == t->left() && e1 == t->right()) {
                    DebugPrintf(
                            "Concave edges belong to the same trapezoid.\n");
                    // Edges belong to the same trapezoid.
                    // Complete trapezoid & transfer it from the active list.
                    t->setBottom(vt);
                    incompleteTrapezoids.remove(t);
                } else {  // Edges belong to different trapezoids
                    DebugPrintf(
                            "Concave edges belong to different trapezoids.\n");
                    // Complete left and right trapezoids.
                    Trapezoid *s = incompleteTrapezoids.getTrapezoidWithEdge(
                                                                            e1);
                    if (s == NULL) {
                        DebugPrintf(
                                "Concave: cannot find a trapezoid with e1: "
                                " trying monotone\n");
                        goto monotone;
                    }
                    t->setBottom(vt);
                    s->setBottom(vt);
                    incompleteTrapezoids.remove(t);
                    incompleteTrapezoids.remove(s);

                    // Merge the two trapezoids into one below this vertex.
                    incompleteTrapezoids.insertNewTrapezoid(vt, t->left(),
                                                                s->right());
                }
                break;
        }
    }

    RemoveDegenerateTrapezoids(numPts, vta);

    DebugPrintf("Done making trapezoids\n");
    PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);

    size_t k = incompleteTrapezoids.count();
    if (k > 0) {
        FailureMessage("%d incomplete trapezoids\n", k);
        return false;
    }
    return true;
}


inline void appendTriangleAtVertex(const Vertex *v,
                                   SkTDArray<SkPoint> *triangles) {
    SkPoint *p = triangles->append(3);
    p[0] = v->prev()->point();
    p[1] = v->point();
    p[2] = v->next()->point();
    DebugPrintf(
          "Appending triangle: { (%.7g, %.7g), (%.7g, %.7g), (%.7g, %.7g) }\n",
          p[0].fX, p[0].fY,
          p[1].fX, p[1].fY,
          p[2].fX, p[2].fY
    );
}


static size_t CountVertices(const Vertex *first, const Vertex *last) {
    DebugPrintf("Counting vertices: ");
    size_t count = 1;
    for (; first != last; first = first->next()) {
        ++count;
        SkASSERT(count <= kMaxCount);
        if (count >= kMaxCount) {
            FailureMessage("Vertices do not seem to be in a linked chain\n");
            break;
        }
    }
    return count;
}


bool operator<(const SkPoint &p0, const SkPoint &p1) {
    if (p0.fY < p1.fY)  return true;
    if (p0.fY > p1.fY)  return false;
    if (p0.fX < p1.fX)  return true;
    else                return false;
}


static void PrintLinkedVertices(size_t n, Vertex *vertices) {
    DebugPrintf("%d vertices:\n", n);
    Vertex *v;
    for (v = vertices; n-- != 0; v = v->next())
        DebugPrintf("   (%.7g, %.7g)\n", v->point().fX, v->point().fY);
    if (v != vertices)
        FailureMessage("Vertices are not in a linked chain\n");
}


// Triangulate an unimonotone chain.
bool TriangulateMonotone(Vertex *first, Vertex *last,
                         SkTDArray<SkPoint> *triangles) {
    DebugPrintf("TriangulateMonotone()\n");

    size_t numVertices = CountVertices(first, last);
    if (numVertices == kMaxCount) {
        FailureMessage("Way too many vertices: %d:\n", numVertices);
        PrintLinkedVertices(numVertices, first);
        return false;
    }

    Vertex *start = first;
    // First find the point with the smallest Y.
    DebugPrintf("TriangulateMonotone: finding bottom\n");
    int count = kMaxCount;    // Maximum number of vertices.
    for (Vertex *v = first->next(); v != first && count-- > 0; v = v->next())
        if (v->point() < start->point())
            start = v;
    if (count <= 0) {
        FailureMessage("TriangulateMonotone() was given disjoint chain\n");
        return false;   // Something went wrong.
    }

    // Start at the far end of the long edge.
    if (start->prev()->point() < start->next()->point())
        start = start->next();

    Vertex *current = start->next();
    while (numVertices >= 3) {
        if (current->angleIsConvex()) {
            DebugPrintf("Angle %p is convex\n", current);
            // Print the vertices
            PrintLinkedVertices(numVertices, start);

            appendTriangleAtVertex(current, triangles);
            if (triangles->count() > kMaxCount * 3) {
                FailureMessage("An extraordinarily large number of triangles "
                               "were generated\n");
                return false;
            }
            Vertex *save = current->prev();
            current->delink();
            current = (save == start || save == start->prev()) ? start->next()
                                                               : save;
            --numVertices;
        } else {
            if (numVertices == 3) {
                FailureMessage("Convexity error in TriangulateMonotone()\n");
                appendTriangleAtVertex(current, triangles);
                return false;
            }
            DebugPrintf("Angle %p is concave\n", current);
            current = current->next();
        }
    }
    return true;
}


// Split the polygon into sets of unimonotone chains, and eventually call
// TriangulateMonotone() to convert them into triangles.
bool Triangulate(Vertex *first, Vertex *last, SkTDArray<SkPoint> *triangles) {
    DebugPrintf("Triangulate()\n");
    Vertex *currentVertex = first;
    while (!currentVertex->done()) {
        currentVertex->setDone(true);
        Vertex *bottomVertex = currentVertex->diagonal();
        if (bottomVertex != NULL) {
            Vertex *saveNext = currentVertex->next();
            Vertex *savePrev = bottomVertex->prev();
            currentVertex->setNext(bottomVertex);
            bottomVertex->setPrev(currentVertex);
            currentVertex->nullifyTrapezoid();
            bool success = Triangulate(bottomVertex, currentVertex, triangles);
            currentVertex->setDone(false);
            bottomVertex->setDone(false);
            currentVertex->setNext(saveNext);
            bottomVertex->setPrev(savePrev);
            bottomVertex->setNext(currentVertex);
            currentVertex->setPrev(bottomVertex);
            return Triangulate(currentVertex, bottomVertex, triangles)
                   && success;
        } else {
            currentVertex = currentVertex->next();
        }
    }
    return TriangulateMonotone(first, last, triangles);
}


bool SkConcaveToTriangles(size_t numPts,
                          const SkPoint pts[],
                          SkTDArray<SkPoint> *triangles) {
    DebugPrintf("SkConcaveToTriangles()\n");

    SkTDArray<Vertex> vertices;
    vertices.setCount(numPts);
    if (!ConvertPointsToVertices(numPts, pts, vertices.begin()))
        return false;

    triangles->setReserve(numPts);
    triangles->setCount(0);
    return Triangulate(vertices.begin(), vertices.end() - 1, triangles);
}
