/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef SkOpSpan_DEFINED
#define SkOpSpan_DEFINED

#include "SkPathOpsDebug.h"
#include "SkPathOpsTypes.h"
#include "SkPoint.h"

class SkArenaAlloc;
class SkOpAngle;
class SkOpContour;
class SkOpGlobalState;
class SkOpSegment;
class SkOpSpanBase;
class SkOpSpan;
struct SkPathOpsBounds;

// subset of op span used by terminal span (when t is equal to one)
class SkOpPtT {
public:
    enum {
        kIsAlias = 1,
        kIsDuplicate = 1
    };

    const SkOpPtT* active() const;

    // please keep in sync with debugAddOpp()
    void addOpp(SkOpPtT* opp, SkOpPtT* oppPrev) {
        SkOpPtT* oldNext = this->fNext;
        SkASSERT(this != opp);
        this->fNext = opp;
        SkASSERT(oppPrev != oldNext);
        oppPrev->fNext = oldNext;
    }

    bool alias() const;
    bool coincident() const { return fCoincident; }
    bool contains(const SkOpPtT* ) const;
    bool contains(const SkOpSegment*, const SkPoint& ) const;
    bool contains(const SkOpSegment*, double t) const;
    const SkOpPtT* contains(const SkOpSegment* ) const;
    SkOpContour* contour() const;

    int debugID() const {
        return SkDEBUGRELEASE(fID, -1);
    }

    void debugAddOpp(const SkOpPtT* opp, const SkOpPtT* oppPrev) const;
    const SkOpAngle* debugAngle(int id) const;
    const SkOpCoincidence* debugCoincidence() const;
    bool debugContains(const SkOpPtT* ) const;
    const SkOpPtT* debugContains(const SkOpSegment* check) const;
    SkOpContour* debugContour(int id) const;
    const SkOpPtT* debugEnder(const SkOpPtT* end) const;
    int debugLoopLimit(bool report) const;
    bool debugMatchID(int id) const;
    const SkOpPtT* debugOppPrev(const SkOpPtT* opp) const;
    const SkOpPtT* debugPtT(int id) const;
    void debugResetCoinT() const;
    const SkOpSegment* debugSegment(int id) const;
    void debugSetCoinT(int ) const;
    const SkOpSpanBase* debugSpan(int id) const;
    void debugValidate() const;

    bool deleted() const {
        return fDeleted;
    }

    bool duplicate() const {
        return fDuplicatePt;
    }

    void dump() const;  // available to testing only
    void dumpAll() const;
    void dumpBase() const;

    const SkOpPtT* find(const SkOpSegment* ) const;
    SkOpGlobalState* globalState() const;
    void init(SkOpSpanBase* , double t, const SkPoint& , bool dup);

    void insert(SkOpPtT* span) {
        SkASSERT(span != this);
        span->fNext = fNext;
        fNext = span;
    }

    const SkOpPtT* next() const {
        return fNext;
    }

    SkOpPtT* next() {
        return fNext;
    }

    bool onEnd() const;

    // returns nullptr if this is already in the opp ptT loop
    SkOpPtT* oppPrev(const SkOpPtT* opp) const {
        // find the fOpp ptr to opp
        SkOpPtT* oppPrev = opp->fNext;
        if (oppPrev == this) {
            return nullptr;
        }
        while (oppPrev->fNext != opp) {
            oppPrev = oppPrev->fNext;
            if (oppPrev == this) {
                return nullptr;
            }
        }
        return oppPrev;
    }

    static bool Overlaps(const SkOpPtT* s1, const SkOpPtT* e1, const SkOpPtT* s2,
            const SkOpPtT* e2, const SkOpPtT** sOut, const SkOpPtT** eOut) {
        const SkOpPtT* start1 = s1->fT < e1->fT ? s1 : e1;
        const SkOpPtT* start2 = s2->fT < e2->fT ? s2 : e2;
        *sOut = between(s1->fT, start2->fT, e1->fT) ? start2
                : between(s2->fT, start1->fT, e2->fT) ? start1 : nullptr;
        const SkOpPtT* end1 = s1->fT < e1->fT ? e1 : s1;
        const SkOpPtT* end2 = s2->fT < e2->fT ? e2 : s2;
        *eOut = between(s1->fT, end2->fT, e1->fT) ? end2
                : between(s2->fT, end1->fT, e2->fT) ? end1 : nullptr;
        if (*sOut == *eOut) {
            SkOPOBJASSERT(s1, start1->fT >= end2->fT || start2->fT >= end1->fT);
            return false;
        }
        SkASSERT(!*sOut || *sOut != *eOut);
        return *sOut && *eOut;
    }

    bool ptAlreadySeen(const SkOpPtT* head) const;
    SkOpPtT* prev();

    const SkOpSegment* segment() const;
    SkOpSegment* segment();

    void setCoincident() const {
        SkOPASSERT(!fDeleted);
        fCoincident = true;
    }

    void setDeleted();

    void setSpan(const SkOpSpanBase* span) {
        fSpan = const_cast<SkOpSpanBase*>(span);
    }

    const SkOpSpanBase* span() const {
        return fSpan;
    }

    SkOpSpanBase* span() {
        return fSpan;
    }

    const SkOpPtT* starter(const SkOpPtT* end) const {
        return fT < end->fT ? this : end;
    }

    double fT;
    SkPoint fPt;   // cache of point value at this t
protected:
    SkOpSpanBase* fSpan;  // contains winding data
    SkOpPtT* fNext;  // intersection on opposite curve or alias on this curve
    bool fDeleted;  // set if removed from span list
    bool fDuplicatePt;  // set if identical pt is somewhere in the next loop
    // below mutable since referrer is otherwise always const
    mutable bool fCoincident;  // set if at some point a coincident span pointed here
    SkDEBUGCODE(int fID);
};

class SkOpSpanBase {
public:
    enum class Collapsed {
        kNo,
        kYes,
        kError,
    };

    bool addOpp(SkOpSpanBase* opp);

    void bumpSpanAdds() {
        ++fSpanAdds;
    }

    bool chased() const {
        return fChased;
    }

    void checkForCollapsedCoincidence();

    const SkOpSpanBase* coinEnd() const {
        return fCoinEnd;
    }

    Collapsed collapsed(double s, double e) const;
    bool contains(const SkOpSpanBase* ) const;
    const SkOpPtT* contains(const SkOpSegment* ) const;

    bool containsCoinEnd(const SkOpSpanBase* coin) const {
        SkASSERT(this != coin);
        const SkOpSpanBase* next = this;
        while ((next = next->fCoinEnd) != this) {
            if (next == coin) {
                return true;
            }
        }
        return false;
    }

    bool containsCoinEnd(const SkOpSegment* ) const;
    SkOpContour* contour() const;

    int debugBumpCount() {
        return SkDEBUGRELEASE(++fCount, -1);
    }

    int debugID() const {
        return SkDEBUGRELEASE(fID, -1);
    }

#if DEBUG_COIN
    void debugAddOpp(SkPathOpsDebug::GlitchLog* , const SkOpSpanBase* opp) const;
#endif
    bool debugAlignedEnd(double t, const SkPoint& pt) const;
    bool debugAlignedInner() const;
    const SkOpAngle* debugAngle(int id) const;
#if DEBUG_COIN
    void debugCheckForCollapsedCoincidence(SkPathOpsDebug::GlitchLog* ) const;
#endif
    const SkOpCoincidence* debugCoincidence() const;
    bool debugCoinEndLoopCheck() const;
    SkOpContour* debugContour(int id) const;
#ifdef SK_DEBUG
    bool debugDeleted() const { return fDebugDeleted; }
#endif
#if DEBUG_COIN
    void debugInsertCoinEnd(SkPathOpsDebug::GlitchLog* ,
                            const SkOpSpanBase* ) const;
    void debugMergeMatches(SkPathOpsDebug::GlitchLog* log,
                           const SkOpSpanBase* opp) const;
#endif
    const SkOpPtT* debugPtT(int id) const;
    void debugResetCoinT() const;
    const SkOpSegment* debugSegment(int id) const;
    void debugSetCoinT(int ) const;
#ifdef SK_DEBUG
    void debugSetDeleted() { fDebugDeleted = true; }
#endif
    const SkOpSpanBase* debugSpan(int id) const;
    const SkOpSpan* debugStarter(SkOpSpanBase const** endPtr) const;
    SkOpGlobalState* globalState() const;
    void debugValidate() const;

    bool deleted() const {
        return fPtT.deleted();
    }

    void dump() const;  // available to testing only
    void dumpCoin() const;
    void dumpAll() const;
    void dumpBase() const;
    void dumpHead() const;

    bool final() const {
        return fPtT.fT == 1;
    }

    SkOpAngle* fromAngle() const {
        return fFromAngle;
    }

    void initBase(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt);

    // Please keep this in sync with debugInsertCoinEnd()
    void insertCoinEnd(SkOpSpanBase* coin) {
        if (containsCoinEnd(coin)) {
            SkASSERT(coin->containsCoinEnd(this));
            return;
        }
        debugValidate();
        SkASSERT(this != coin);
        SkOpSpanBase* coinNext = coin->fCoinEnd;
        coin->fCoinEnd = this->fCoinEnd;
        this->fCoinEnd = coinNext;
        debugValidate();
    }

    void merge(SkOpSpan* span);
    bool mergeMatches(SkOpSpanBase* opp);

    const SkOpSpan* prev() const {
        return fPrev;
    }

    SkOpSpan* prev() {
        return fPrev;
    }

    const SkPoint& pt() const {
        return fPtT.fPt;
    }

    const SkOpPtT* ptT() const {
        return &fPtT;
    }

    SkOpPtT* ptT() {
        return &fPtT;
    }

    SkOpSegment* segment() const {
        return fSegment;
    }

    void setAligned() {
        fAligned = true;
    }

    void setChased(bool chased) {
        fChased = chased;
    }

    void setFromAngle(SkOpAngle* angle) {
        fFromAngle = angle;
    }

    void setPrev(SkOpSpan* prev) {
        fPrev = prev;
    }

    bool simple() const {
        fPtT.debugValidate();
        return fPtT.next()->next() == &fPtT;
    }

    int spanAddsCount() const {
        return fSpanAdds;
    }

    const SkOpSpan* starter(const SkOpSpanBase* end) const {
        const SkOpSpanBase* result = t() < end->t() ? this : end;
        return result->upCast();
    }

    SkOpSpan* starter(SkOpSpanBase* end) {
        SkASSERT(this->segment() == end->segment());
        SkOpSpanBase* result = t() < end->t() ? this : end;
        return result->upCast();
    }

    SkOpSpan* starter(SkOpSpanBase** endPtr) {
        SkOpSpanBase* end = *endPtr;
        SkASSERT(this->segment() == end->segment());
        SkOpSpanBase* result;
        if (t() < end->t()) {
            result = this;
        } else {
            result = end;
            *endPtr = this;
        }
        return result->upCast();
    }

    int step(const SkOpSpanBase* end) const {
        return t() < end->t() ? 1 : -1;
    }

    double t() const {
        return fPtT.fT;
    }

    void unaligned() {
        fAligned = false;
    }

    SkOpSpan* upCast() {
        SkASSERT(!final());
        return (SkOpSpan*) this;
    }

    const SkOpSpan* upCast() const {
        SkOPASSERT(!final());
        return (const SkOpSpan*) this;
    }

    SkOpSpan* upCastable() {
        return final() ? nullptr : upCast();
    }

    const SkOpSpan* upCastable() const {
        return final() ? nullptr : upCast();
    }

private:
    void alignInner();

protected:  // no direct access to internals to avoid treating a span base as a span
    SkOpPtT fPtT;  // list of points and t values associated with the start of this span
    SkOpSegment* fSegment;  // segment that contains this span
    SkOpSpanBase* fCoinEnd;  // linked list of coincident spans that end here (may point to itself)
    SkOpAngle* fFromAngle;  // points to next angle from span start to end
    SkOpSpan* fPrev;  // previous intersection point
    int fSpanAdds;  // number of times intersections have been added to span
    bool fAligned;
    bool fChased;  // set after span has been added to chase array
    SkDEBUGCODE(int fCount);  // number of pt/t pairs added
    SkDEBUGCODE(int fID);
    SkDEBUGCODE(bool fDebugDeleted);  // set when span was merged with another span
};

class SkOpSpan : public SkOpSpanBase {
public:
    bool alreadyAdded() const {
        if (fAlreadyAdded) {
            return true;
        }
        return false;
    }

    bool clearCoincident() {
        SkASSERT(!final());
        if (fCoincident == this) {
            return false;
        }
        fCoincident = this;
        return true;
    }

    int computeWindSum();
    bool containsCoincidence(const SkOpSegment* ) const;

    bool containsCoincidence(const SkOpSpan* coin) const {
        SkASSERT(this != coin);
        const SkOpSpan* next = this;
        while ((next = next->fCoincident) != this) {
            if (next == coin) {
                return true;
            }
        }
        return false;
    }

    bool debugCoinLoopCheck() const;
#if DEBUG_COIN
    void debugInsertCoincidence(SkPathOpsDebug::GlitchLog* , const SkOpSpan* ) const;
    void debugInsertCoincidence(SkPathOpsDebug::GlitchLog* ,
                                const SkOpSegment* , bool flipped, bool ordered) const;
#endif
    void dumpCoin() const;
    bool dumpSpan() const;

    bool done() const {
        SkASSERT(!final());
        return fDone;
    }

    void init(SkOpSegment* parent, SkOpSpan* prev, double t, const SkPoint& pt);
    bool insertCoincidence(const SkOpSegment* , bool flipped, bool ordered);

    // Please keep this in sync with debugInsertCoincidence()
    void insertCoincidence(SkOpSpan* coin) {
        if (containsCoincidence(coin)) {
            SkASSERT(coin->containsCoincidence(this));
            return;
        }
        debugValidate();
        SkASSERT(this != coin);
        SkOpSpan* coinNext = coin->fCoincident;
        coin->fCoincident = this->fCoincident;
        this->fCoincident = coinNext;
        debugValidate();
    }

    bool isCanceled() const {
        SkASSERT(!final());
        return fWindValue == 0 && fOppValue == 0;
    }

    bool isCoincident() const {
        SkASSERT(!final());
        return fCoincident != this;
    }

    void markAdded() {
        fAlreadyAdded = true;
    }

    SkOpSpanBase* next() const {
        SkASSERT(!final());
        return fNext;
    }

    int oppSum() const {
        SkASSERT(!final());
        return fOppSum;
    }

    int oppValue() const {
        SkASSERT(!final());
        return fOppValue;
    }

    void release(const SkOpPtT* );

    SkOpPtT* setCoinStart(SkOpSpan* oldCoinStart, SkOpSegment* oppSegment);

    void setDone(bool done) {
        SkASSERT(!final());
        fDone = done;
    }

    void setNext(SkOpSpanBase* nextT) {
        SkASSERT(!final());
        fNext = nextT;
    }

    void setOppSum(int oppSum);

    void setOppValue(int oppValue) {
        SkASSERT(!final());
        SkASSERT(fOppSum == SK_MinS32);
        SkOPASSERT(!oppValue || !fDone);
        fOppValue = oppValue;
    }

    void setToAngle(SkOpAngle* angle) {
        SkASSERT(!final());
        fToAngle = angle;
    }

    void setWindSum(int windSum);

    void setWindValue(int windValue) {
        SkASSERT(!final());
        SkASSERT(windValue >= 0);
        SkASSERT(fWindSum == SK_MinS32);
        SkOPASSERT(!windValue || !fDone);
        fWindValue = windValue;
    }

    bool sortableTop(SkOpContour* );

    SkOpAngle* toAngle() const {
        SkASSERT(!final());
        return fToAngle;
    }

    int windSum() const {
        SkASSERT(!final());
        return fWindSum;
    }

    int windValue() const {
        SkOPASSERT(!final());
        return fWindValue;
    }

private:  // no direct access to internals to avoid treating a span base as a span
    SkOpSpan* fCoincident;  // linked list of spans coincident with this one (may point to itself)
    SkOpAngle* fToAngle;  // points to next angle from span start to end
    SkOpSpanBase* fNext;  // next intersection point
    int fWindSum;  // accumulated from contours surrounding this one.
    int fOppSum;  // for binary operators: the opposite winding sum
    int fWindValue;  // 0 == canceled; 1 == normal; >1 == coincident
    int fOppValue;  // normally 0 -- when binary coincident edges combine, opp value goes here
    int fTopTTry; // specifies direction and t value to try next
    bool fDone;  // if set, this span to next higher T has been processed
    bool fAlreadyAdded;
};

#endif
