/*
 * 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 "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkDebug.h"
#include "src/base/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 {
    SkPathBuilder result;
    result.setFillType(fPath.getFillType());
    if (!fSelected.size()) {
        return result.detach();
    }
    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.detach();
        }
    }
    return result.detach();
}

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 {
    SkPathBuilder result;
    result.setFillType(fPath.getFillType());
    if (!fSelected.size()) {
        return result.detach();
    }
    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.detach();
        }
        addLineTo = !enabled;
    }
    return result.detach();
}
