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

#include "src/core/SkMathPriv.h"
#include "src/core/SkPathPriv.h"
#include "tests/SubsetPath.h"

SubsetPath::SubsetPath(const SkPath& path)
        : fPath(path)
        , fSubset(1) {
}

int SubsetPath::range(int* end) const {
    int leadingZero = SkCLZ(fSubset);
    int parts = 1 << (31 - leadingZero);
    int partIndex = fSubset - parts;
    SkASSERT(partIndex >= 0);
    int count = fSelected.size();
    int start = count * partIndex / parts;
    *end = count * (partIndex + 1) / parts;
    return start;
}

bool SubsetPath::subset(bool testFailed, SkPath* sub) {
    int start, end;
    if (!testFailed) {
        start = range(&end);
        for (; start < end; ++start) {
            fSelected[start] = true;
        }
    }
    do {
        do {
            ++fSubset;
            start = range(&end);
 //           SkDebugf("%d s=%d e=%d t=%d\n", fSubset, start, end, fTries);
            if (end - start > 1) {
                fTries = fSelected.size();
            } else if (end - start == 1) {
                if (--fTries <= 0) {
                    return false;
                }
            }
        } while (start == end);
    } while (!fSelected[start]);
    for (; start < end; ++start) {
        fSelected[start] = false;
    }
#if 1
    SkDebugf("selected: ");
    for (int index = 0; index < fSelected.size(); ++index) {
        SkDebugf("%c", fSelected[index] ? 'x' : '-');
    }
#endif
    *sub = getSubsetPath();
    return true;
}

SubsetContours::SubsetContours(const SkPath& path)
        : SubsetPath(path) {
    bool foundCurve = false;
    int contourCount = 0;
    for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) {
        switch (verb) {
            case SkPathVerb::kMove:
                break;
            case SkPathVerb::kLine:
            case SkPathVerb::kQuad:
            case SkPathVerb::kConic:
            case SkPathVerb::kCubic:
                foundCurve = true;
                break;
            case SkPathVerb::kClose:
                ++contourCount;
                foundCurve = false;
                break;
            default:
                SkDEBUGFAIL("bad verb");
                return;
        }
    }
    contourCount += foundCurve;
    for (int index = 0; index < contourCount; ++index) {
        *fSelected.append() = true;
    }
    fTries = contourCount;
}

SkPath SubsetContours::getSubsetPath() const {
    SkPath result;
    result.setFillType(fPath.getFillType());
    if (!fSelected.size()) {
        return result;
    }
    int contourCount = 0;
    bool enabled = fSelected[0];
    bool addMoveTo = true;
    for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) {
        if (enabled && addMoveTo) {
            result.moveTo(pts[0]);
            addMoveTo = false;
        }
        switch (verb) {
            case SkPathVerb::kMove:
                break;
            case SkPathVerb::kLine:
                if (enabled) {
                    result.lineTo(pts[1]);
                }
                break;
            case SkPathVerb::kQuad:
                if (enabled) {
                    result.quadTo(pts[1], pts[2]);
                }
                break;
            case SkPathVerb::kConic:
                if (enabled) {
                    result.conicTo(pts[1], pts[2], *w);
                }
                break;
            case SkPathVerb::kCubic:
                 if (enabled) {
                    result.cubicTo(pts[1], pts[2], pts[3]);
                }
                break;
            case SkPathVerb::kClose:
                if (enabled) {
                    result.close();
                }
                if (++contourCount >= fSelected.size()) {
                    break;
                }
                enabled = fSelected[contourCount];
                addMoveTo = true;
                continue;
            default:
                SkDEBUGFAIL("bad verb");
                return result;
        }
    }
    return result;
}

SubsetVerbs::SubsetVerbs(const SkPath& path)
        : SubsetPath(path) {
    int verbCount = 0;
    for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) {
        switch (verb) {
            case SkPathVerb::kMove:
                break;
            case SkPathVerb::kLine:
            case SkPathVerb::kQuad:
            case SkPathVerb::kConic:
            case SkPathVerb::kCubic:
                ++verbCount;
                break;
            case SkPathVerb::kClose:
                break;
            default:
                SkDEBUGFAIL("bad verb");
                return;
        }
    }
    for (int index = 0; index < verbCount; ++index) {
        *fSelected.append() = true;
    }
    fTries = verbCount;
}

SkPath SubsetVerbs::getSubsetPath() const {
    SkPath result;
    result.setFillType(fPath.getFillType());
    if (!fSelected.size()) {
        return result;
    }
    int verbIndex = 0;
    bool addMoveTo = true;
    bool addLineTo = false;
    for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) {
        bool enabled = SkPathVerb::kLine <= verb && verb <= SkPathVerb::kCubic
            ? fSelected[verbIndex++] : false;
        if (enabled) {
            if (addMoveTo) {
                result.moveTo(pts[0]);
                addMoveTo = false;
            } else if (addLineTo) {
                result.lineTo(pts[0]);
                addLineTo = false;
            }
        }
        switch (verb) {
            case SkPathVerb::kMove:
                break;
            case SkPathVerb::kLine:
                if (enabled) {
                    result.lineTo(pts[1]);
                }
                break;
            case SkPathVerb::kQuad:
                if (enabled) {
                    result.quadTo(pts[1], pts[2]);
                }
                break;
            case SkPathVerb::kConic:
                if (enabled) {
                    result.conicTo(pts[1], pts[2], *w);
                }
                break;
            case SkPathVerb::kCubic:
                 if (enabled) {
                    result.cubicTo(pts[1], pts[2], pts[3]);
                }
                break;
            case SkPathVerb::kClose:
                result.close();
                addMoveTo = true;
                addLineTo = false;
                continue;
            default:
                SkDEBUGFAIL("bad verb");
                return result;
        }
        addLineTo = !enabled;
    }
    return result;
}
