/*
 * 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/SkDebug.h"
#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 {
    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();
}
