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

#include "SkPathOpsTSect.h"

template<typename TCurve, typename OppCurve>
char SkTCoincident<TCurve, OppCurve>::dumpIsCoincidentStr() const {
    if (!!fMatch != fMatch) {
        return '?';
    }
    return fMatch ? '*' : 0;
}

template<typename TCurve, typename OppCurve>
void SkTCoincident<TCurve, OppCurve>::dump() const {
    SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY,
            fMatch ? " match" : "");
}

template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugSpan(int id) const {
    const SkTSpan<TCurve, OppCurve>* test = fHead;
    do {
        if (test->debugID() == id) {
            return test;
        }
    } while ((test = test->next()));
    return nullptr;
}

template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugT(double t) const {
    const SkTSpan<TCurve, OppCurve>* test = fHead;
    const SkTSpan<TCurve, OppCurve>* closest = nullptr;
    double bestDist = DBL_MAX;
    do {
        if (between(test->fStartT, t, test->fEndT)) {
            return test;
        }
        double testDist = SkTMin(fabs(test->fStartT - t), fabs(test->fEndT - t));
        if (bestDist > testDist) {
            bestDist = testDist;
            closest = test;
        }
    } while ((test = test->next()));
    SkASSERT(closest);
    return closest;
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dump() const {
    dumpCommon(fHead);
}

extern int gDumpTSectNum;

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpBoth(SkTSect<OppCurve, TCurve>* opp) const {
#if DEBUG_T_SECT_DUMP <= 2
#if DEBUG_T_SECT_DUMP == 2
    SkDebugf("%d ", ++gDumpTSectNum);
#endif
    this->dump();
    SkDebugf(" ");
    opp->dump();
    SkDebugf("\n");
#elif DEBUG_T_SECT_DUMP == 3
    SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum);
    if (this->fHead) {
        this->dumpCurves();
    }
    if (opp->fHead) {
        opp->dumpCurves();
    }
    SkDebugf("</div>\n\n");
#endif
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpBounded(int id) const {
    const SkTSpan<TCurve, OppCurve>* bounded = debugSpan(id);
    if (!bounded) {
        SkDebugf("no span matches %d\n", id);
        return;
    }
    const SkTSpan<OppCurve, TCurve>* test = bounded->debugOpp()->fHead;
    do {
        if (test->findOppSpan(bounded)) {
            test->dump();
            SkDebugf(" ");
        }
    } while ((test = test->next()));
    SkDebugf("\n");
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpBounds() const {
    const SkTSpan<TCurve, OppCurve>* test = fHead;
    do {
        test->dumpBounds();
    } while ((test = test->next()));
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCoin() const {
    dumpCommon(fCoincident);
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCoinCurves() const {
    dumpCommonCurves(fCoincident);
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCommon(const SkTSpan<TCurve, OppCurve>* test) const {
    SkDebugf("id=%d", debugID());
    if (!test) {
        SkDebugf(" (empty)");
        return;
    }
    do {
        SkDebugf(" ");
        test->dump();
    } while ((test = test->next()));
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* test) const {
    do {
        test->fPart.dumpID(test->debugID());
    } while ((test = test->next()));
}

template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCurves() const {
    dumpCommonCurves(fHead);
}

template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugSpan(int id) const {
    return SkDEBUGRELEASE(fDebugSect->debugSpan(id), nullptr);
}

template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugT(double t) const {
    return SkDEBUGRELEASE(fDebugSect->debugT(t), nullptr);
}

template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpAll() const {
    dumpID();
    SkDebugf("=(%g,%g) [", fStartT, fEndT);
    const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded;
    while (testBounded) {
        const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded;
        const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext;
        span->dumpID();
        SkDebugf("=(%g,%g)", span->fStartT, span->fEndT);
        if (next) {
            SkDebugf(" ");
        }
        testBounded = next;
    }
    SkDebugf("]\n");
}

template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dump() const {
    dumpID();
    SkDebugf("=(%g,%g) [", fStartT, fEndT);
    const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded;
    while (testBounded) {
        const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded;
        const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext;
        span->dumpID();
        if (next) {
            SkDebugf(",");
        }
        testBounded = next;
    }
    SkDebugf("]");
}

template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpBounded(int id) const {
    SkDEBUGCODE(fDebugSect->dumpBounded(id));
}

template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpBounds() const {
    dumpID();
    SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n",
            fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax,
            fCollapsed ? " collapsed" : "");
}

template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpCoin() const {
    dumpID();
    SkDebugf(" coinStart ");
    fCoinStart.dump();
    SkDebugf(" coinEnd ");
    fCoinEnd.dump();
}

template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpID() const {
    char cS = fCoinStart.dumpIsCoincidentStr();
    if (cS) {
        SkDebugf("%c", cS);
    }
    SkDebugf("%d", debugID());
    char cE = fCoinEnd.dumpIsCoincidentStr();
    if (cE) {
        SkDebugf("%c", cE);
    }
}
