
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkRegion.h"
#include "SkChunkAlloc.h"
#include "SkTDArray.h"
#include "SkTemplates.h"

#if 0

struct VEdge {
    VEdge*  fPrev;
    VEdge*  fNext;
    
    SkRegion::RunType   fX;
    SkRegion::RunType   fTop;
    SkRegion::RunType   fBottom;
    int                 fWinding;
    
    void removeFromList() {
        fPrev->fNext = fNext;
        fNext->fPrev = fPrev;
    }

    void backwardsInsert() {
        while (fPrev->fX > fX) {
            VEdge* prev = fPrev;
            VEdge* next = this;

            // remove prev from the list
            prev->fPrev->fNext = next;
            next->fPrev = prev->fPrev;
            
            // insert prev after next
            prev->fNext = next->fNext;
            next->fNext->fPrev = prev;
            next->fNext = prev;
            prev->fPrev = next;
        }
    }

    static void SetFromRect(VEdge edges[], const SkIRect& r) {
        edges[0].fX = r.fLeft;
        edges[0].fTop = r.fTop;
        edges[0].fBottom = r.fBottom;
        edges[0].fWinding = -1;
        
        edges[1].fX = r.fRight;
        edges[1].fTop = r.fTop;
        edges[1].fBottom = r.fBottom;
        edges[1].fWinding = 1;
    }
};

class Accumulator {
public:
    Accumulator(SkRegion::RunType top, int numRects);
    ~Accumulator() {}
    
    SkRegion::RunType append(SkRegion::RunType top, const VEdge* edge);
    
    int count() const { return fTotalCount; }
    void copyTo(SkRegion::RunType dst[]);
    
private:
    struct Row {
        SkRegion::RunType*  fPtr;
        SkRegion::RunType   fBottom;
        int                 fCount; // just [L R] count
    };
    SkChunkAlloc    fAlloc;
    SkTDArray<Row>  fRows;
    SkRegion::RunType fTop;
    int             fTotalCount;
    int             fRectCount;
};

Accumulator::Accumulator(SkRegion::RunType top, int numRects)
        : fAlloc((1 + numRects * 2 + 1) * sizeof(int32_t)) {
    fRectCount = numRects;
    fTop = top;
    fTotalCount = 2; // Top + final sentinel
}

//#define TRACE_ROW(code) code
#define TRACE_ROW(code)

SkRegion::RunType Accumulator::append(SkRegion::RunType currY, const VEdge* edge) {
    // worst-case size
    size_t size = fRectCount * 2 * sizeof(SkRegion::RunType);
    SkRegion::RunType* row = (SkRegion::RunType*)fAlloc.allocThrow(size);
    SkRegion::RunType* rowHead = row;
    
    SkRegion::RunType nextY = SkRegion::kRunTypeSentinel;
    int winding = edge->fWinding;

    // record the L R values for this row

    if (edge->fTop > currY) {
        nextY = SkMin32(nextY, edge->fTop);
        TRACE_ROW(SkDebugf("Y %d\n", currY);)
    } else {
        SkRegion::RunType currR;
        *row++ = edge->fX;
        TRACE_ROW(SkDebugf("Y %d [%d", currY, edge->fX);)
        edge = edge->fNext;
        for (;;) {
            if (edge->fTop > currY) {
                nextY = SkMin32(nextY, edge->fTop);
                break;
            }

            int prevWinding = winding;
            winding += edge->fWinding;
            if (0 == winding) { // we finished an interval
                currR = edge->fX;
            } else if (0 == prevWinding && edge->fX > currR) {
                *row++ = currR;
                *row++ = edge->fX;
                TRACE_ROW(SkDebugf(" %d] [%d", currR, edge->fX);)
            }
            
            nextY = SkMin32(nextY, edge->fBottom);
            edge = edge->fNext;
        }
        SkASSERT(0 == winding);
        *row++ = currR;
        TRACE_ROW(SkDebugf(" %d]\n", currR);)
    }
    int rowCount = row - rowHead;
    
    // now see if we have already seen this row, or if its unique

    Row* r = fRows.count() ? &fRows[fRows.count() - 1] : NULL;
    if (r && (r->fCount == rowCount) &&
        !memcmp(r->fPtr, rowHead,
                rowCount * sizeof(SkRegion::RunType))) {
            r->fBottom = nextY;    // update bottom
            fAlloc.unalloc(rowHead);
        } else {
            Row* r = fRows.append();
            r->fPtr = rowHead;
            r->fBottom = nextY;
            r->fCount = rowCount;
            fTotalCount += 1 + rowCount + 1;
        }
    
    return nextY;
}

void Accumulator::copyTo(SkRegion::RunType dst[]) {
    SkDEBUGCODE(SkRegion::RunType* startDst = dst;)
    
    *dst++ = fTop;
    
    const Row* curr = fRows.begin();
    const Row* stop = fRows.end();
    while (curr < stop) {
        *dst++ = curr->fBottom;
        memcpy(dst, curr->fPtr, curr->fCount * sizeof(SkRegion::RunType));
        dst += curr->fCount;
        *dst++ = SkRegion::kRunTypeSentinel;
        curr += 1;
    }
    *dst++ = SkRegion::kRunTypeSentinel;
    SkASSERT(dst - startDst == fTotalCount);
}

///////////////////////////////////////////////////////////////////////////////

template <typename T> int SkTCmp2Int(const T& a, const T& b) {
    return (a < b) ? -1 : ((b < a) ? 1 : 0);
}

static inline int SkCmp32(int32_t a, int32_t b) {
    return (a < b) ? -1 : ((b < a) ? 1 : 0);
}

static int compare_edgeptr(const void* p0, const void* p1) {
    const VEdge* e0 = *static_cast<VEdge*const*>(p0);
    const VEdge* e1 = *static_cast<VEdge*const*>(p1);

    SkRegion::RunType v0 = e0->fTop;
    SkRegion::RunType v1 = e1->fTop;

    if (v0 == v1) {
        v0 = e0->fX;
        v1 = e1->fX;
    }
    return SkCmp32(v0, v1);
}

// fillout edge[] from rects[], sorted. Return the head, and set the tail
//
static VEdge* sort_edges(VEdge** edgePtr, VEdge edge[], const SkIRect rects[],
                         int rectCount, VEdge** edgeTail) {
    int i;
    VEdge** ptr = edgePtr;
    for (int i = 0; i < rectCount; i++) {
        if (!rects[i].isEmpty()) {
            VEdge::SetFromRect(edge, rects[i]);
            *ptr++ = edge++;
            *ptr++ = edge++;
        }
    }
    
    int edgeCount = ptr - edgePtr;
    if (0 == edgeCount) {
        // all the rects[] were empty
        return NULL;
    }

    qsort(edgePtr, edgeCount, sizeof(*edgePtr), compare_edgeptr);
    for (i = 1; i < edgeCount; i++) {
        edgePtr[i - 1]->fNext = edgePtr[i];
        edgePtr[i]->fPrev = edgePtr[i - 1];
    }
    *edgeTail = edgePtr[edgeCount - 1];
    return edgePtr[0];
}

bool SkRegion::setRects(const SkIRect rects[], int rectCount) {
    if (0 == rectCount) {
        return this->setEmpty();
    }
    if (1 == rectCount) {
        return this->setRect(rects[0]);
    }

    int edgeCount = rectCount * 2;
    SkAutoMalloc memory((sizeof(VEdge) + sizeof(VEdge*)) * edgeCount);
    VEdge** edgePtr = (VEdge**)memory.get();
    VEdge* tail, *head = (VEdge*)(edgePtr + edgeCount);
    head = sort_edges(edgePtr, head, rects, rectCount, &tail);
    // check if we have no edges
    if (NULL == head) {
        return this->setEmpty();
    }

    // at this stage, we don't really care about edgeCount, or if rectCount is
    // larger that it should be (since sort_edges might have skipped some
    // empty rects[]). rectCount now is just used for worst-case allocations

    VEdge headEdge, tailEdge;
    headEdge.fPrev = NULL;
    headEdge.fNext = head;
    headEdge.fTop = SK_MinS32;
    headEdge.fX = SK_MinS32;
    head->fPrev = &headEdge;
    
    tailEdge.fPrev = tail;
    tailEdge.fNext = NULL;
    tailEdge.fTop = SK_MaxS32;
    tail->fNext = &tailEdge;

    int32_t currY = head->fTop;
    Accumulator accum(currY, rectCount);
    
    while (head->fNext) {
        VEdge* edge = head;
        // accumulate the current
        SkRegion::RunType nextY = accum.append(currY, edge);
        // remove the old
        while (edge->fTop <= currY) {
            VEdge* next = edge->fNext;
            if (edge->fBottom <= nextY) {
                edge->removeFromList();
            }
            edge = next;
        }
        // insert (sorted) the new
        while (edge->fTop == nextY) {
            VEdge* next = edge->fNext;
            edge->backwardsInsert();
            edge = next;
        }
        currY = nextY;
        head = headEdge.fNext;
    }

    SkAutoTArray<RunType> runs(accum.count());
    accum.copyTo(runs.get());
    return this->setRuns(runs.get(), accum.count());
}

#endif
