/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "src/core/SkFloatBits.h"
#include "src/core/SkStringUtils.h"

#include <array>
#include <functional>

static constexpr auto gFillTypeStrs = std::to_array<const char *>({
    "Winding",
    "EvenOdd",
    "InverseWinding",
    "InverseEvenOdd",
});

constexpr float kSentinelConicWeight = -12345;  // not a valid weight

static void append_params(SkString* str, const char label[], SkSpan<const SkPoint> pts,
                          SkScalarAsStringType strType, bool useSemicolon,
                          SkScalar conicWeight = kSentinelConicWeight) {
    str->append(label);
    str->append("(");

    const SkScalar* values = &pts[0].fX;
    size_t count = pts.size() * 2;

    for (size_t i = 0; i < count; ++i) {
        SkAppendScalar(str, values[i], strType);
        if (i < count - 1) {
            str->append(", ");
        }
    }
    if (conicWeight != kSentinelConicWeight) {
        str->append(", ");
        SkAppendScalar(str, conicWeight, strType);
    }
    str->append(useSemicolon ? ");" : ")");
    if (kHex_SkScalarAsStringType == strType) {
        str->append("  // ");
        for (size_t i = 0; i < count; ++i) {
            SkAppendScalarDec(str, values[i]);
            if (i < count - 1) {
                str->append(", ");
            }
        }
        if (conicWeight >= 0) {
            str->append(", ");
            SkAppendScalarDec(str, conicWeight);
        }
    }
    str->append("\n");
}

static void dump_iter(SkPathIter iter, SkString* builder, const char cmdPrefix[],
                      SkScalarAsStringType strType, bool useSemicolon,
                      std::function<void()> postVerbProc) {
    while (auto rec = iter.next()) {
        SkString cmd(cmdPrefix);
        SkSpan<const SkPoint> pts;
        float cw = kSentinelConicWeight;

        switch (rec->fVerb) {
            case SkPathVerb::kMove:
                cmd.append(".moveTo");
                pts = {&rec->fPoints[0], 1};
                break;
            case SkPathVerb::kLine:
                cmd.append(".lineTo");
                pts = {&rec->fPoints[1], 1};
                break;
            case SkPathVerb::kQuad:
                cmd.append(".quadTo");
                pts = {&rec->fPoints[1], 2};
                break;
            case SkPathVerb::kConic:
                cmd.append(".conicTo");
                pts = {&rec->fPoints[1], 2};
                cw = rec->conicWeight();
                break;
            case SkPathVerb::kCubic:
                cmd.append(".cubicTo");
                pts = {&rec->fPoints[1], 3};
                break;
            case SkPathVerb::kClose:
                cmd.append(".close()");
                if (useSemicolon) {
                    cmd.append(";");
                }
                cmd.append("\n");
                builder->append(cmd.c_str());
                break;
        }
        // we don't do this for kClose
        if (pts.size()) {
            append_params(builder, cmd.c_str(), pts, strType, useSemicolon, cw);
        }
        postVerbProc();
    }
}

void SkPath::dump(SkWStream* wStream, bool dumpAsHex) const {
    SkScalarAsStringType asType = dumpAsHex ? kHex_SkScalarAsStringType : kDec_SkScalarAsStringType;

    SkString builder;
    builder.printf("path.setFillType(SkPathFillType::k%s);\n",
            gFillTypeStrs[(int) this->getFillType()]);

    dump_iter(this->iter(), &builder, "path", asType, true, [&]() {
        if (!wStream && builder.size()) {
            SkDebugf("%s", builder.c_str());
            builder.reset();
        }
    });
    if (wStream) {
        wStream->writeText(builder.c_str());
    }
}

SkString SkPathBuilder::dumpToString(DumpFormat format) const {
    SkScalarAsStringType asType = format == DumpFormat::kHex ? kHex_SkScalarAsStringType
                                                             : kDec_SkScalarAsStringType;

    SkString builder;
    builder.printf("SkPathBuilder(SkPathFillType::k%s)\n",
                   gFillTypeStrs[(int) this->fillType()]);

    dump_iter(this->iter(), &builder, "", asType, false, [](){});

    return builder;
}

void SkPathBuilder::dump(DumpFormat format) const {
    SkDebugf("%s", dumpToString().c_str());
}
