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

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

#if defined(SK_TYPEFACE_FACTORY_FONTATIONS)
#include "include/ports/SkTypeface_fontations.h"
#endif

#include <string.h>

namespace skiagm {

// Copied from https://github.com/googlefonts/color-fonts#colrv1-test-font glyph descriptions
// markdown file.
namespace ColrV1TestDefinitions {
const uint32_t color_circles_palette[] = {0xf0e00, 0xf0e01};
}

namespace {
const char kColrCpalTestFontPath[] = "fonts/test_glyphs-glyf_colr_1.ttf";

constexpr SkFontArguments::Palette::Override kColorOverridesAll[] = {
        // A gradient of dark to light purple for the circle palette test glyph.
        // Randomly ordered with `shuf`.
        // Add a repeat (later overrides override earlier overrides).
        // Add three out of bounds entries (font has 12 palette entries).
        // clang-format off
        { 6, 0xffffff00},
        { 2, 0xff76078f},
        { 4, 0xffb404c4},
        { 1, 0xff510970},
        { 6, 0xfffa00ff},
        { 8, 0xff888888},
        {10, 0xff888888},
        { 9, 0xff888888},
        { 7, 0xff888888},
        {11, 0xff888888},
        { 0, 0xff310b55},
        { 3, 0xff9606aa},
        { 5, 0xffd802e2},
        {13, 0xff00ffff},
        {12, 0xff00ffff},
        {static_cast<uint16_t>(-1), 0xff00ff00},
        // clang-format on
};

constexpr SkFontArguments::Palette::Override kColorOverridesOne[] = {
        {2, 0xff02dfe2},
};

constexpr SkFontArguments::Palette kLightPaletteOverride{2, nullptr, 0};
constexpr SkFontArguments::Palette kDarkPaletteOverride{1, nullptr, 0};
constexpr SkFontArguments::Palette kOnePaletteOverride{
        0, kColorOverridesOne, std::size(kColorOverridesOne)};
constexpr SkFontArguments::Palette kAllPaletteOverride{
        0, kColorOverridesAll, std::size(kColorOverridesAll)};

sk_sp<SkTypeface> MakeTypefaceFromResource(const char* resource, const SkFontArguments& args) {
    return ToolUtils::TestFontMgr()->makeFromStream(GetResourceAsStream(resource), args);
}

}  // namespace

class FontPaletteGM : public GM {
public:
    FontPaletteGM(const char* test_name, const SkFontArguments::Palette& paletteOverride)
            : fName(test_name), fPalette(paletteOverride) {}

protected:
    sk_sp<SkTypeface> fTypefaceDefault;
    sk_sp<SkTypeface> fTypefaceFromStream;
    sk_sp<SkTypeface> fTypefaceCloned;

    void onOnceBeforeDraw() override {
        SkFontArguments paletteArguments;
        paletteArguments.setPalette(fPalette);

        fTypefaceDefault = MakeTypefaceFromResource(kColrCpalTestFontPath, SkFontArguments());
        fTypefaceCloned =
                fTypefaceDefault ? fTypefaceDefault->makeClone(paletteArguments) : nullptr;

        fTypefaceFromStream = MakeTypefaceFromResource(kColrCpalTestFontPath, paletteArguments);
    }

    SkString getName() const override {
        SkString gm_name = SkStringPrintf("font_palette_%s", fName.c_str());
        return gm_name;
    }

    SkISize getISize() override { return SkISize::Make(1000, 400); }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        canvas->drawColor(SK_ColorWHITE);
        SkPaint paint;

        canvas->translate(10, 20);

        if (!fTypefaceCloned || !fTypefaceFromStream) {
            *errorMsg = "Did not recognize COLR v1 test font format.";
            return DrawResult::kSkip;
        }

        SkFontMetrics metrics;
        SkScalar y = 0;
        SkScalar textSize = 200;
        for (auto& typeface : {fTypefaceFromStream, fTypefaceCloned}) {
            SkFont defaultFont(fTypefaceDefault);
            SkFont paletteFont(typeface);
            defaultFont.setSize(textSize);
            paletteFont.setSize(textSize);

            defaultFont.getMetrics(&metrics);
            y += -metrics.fAscent;
            // Set a recognizable foreground color which is not to be overriden.
            paint.setColor(SK_ColorGRAY);
            // Draw the default palette on the left, for COLRv0 and COLRv1.
            canvas->drawSimpleText(
                    ColrV1TestDefinitions::color_circles_palette,
                    std::size(ColrV1TestDefinitions::color_circles_palette) * sizeof(uint32_t),
                    SkTextEncoding::kUTF32,
                    0,
                    y,
                    defaultFont,
                    paint);
            // Draw the overriden palette on the right.
            canvas->drawSimpleText(
                    ColrV1TestDefinitions::color_circles_palette,
                    std::size(ColrV1TestDefinitions::color_circles_palette) * sizeof(uint32_t),
                    SkTextEncoding::kUTF32,
                    440,
                    y,
                    paletteFont,
                    paint);
            y += metrics.fDescent + metrics.fLeading;
        }
        return DrawResult::kOk;
    }

private:
    using INHERITED = GM;
    SkString fName;
    SkFontArguments::Palette fPalette;
};

DEF_GM(return new FontPaletteGM("default", SkFontArguments::Palette()))
DEF_GM(return new FontPaletteGM("light", kLightPaletteOverride))
DEF_GM(return new FontPaletteGM("dark", kDarkPaletteOverride))
DEF_GM(return new FontPaletteGM("one", kOnePaletteOverride))
DEF_GM(return new FontPaletteGM("all", kAllPaletteOverride))

}  // namespace skiagm
