/*
 * Copyright 2021 Google Inc.
 *
 * 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/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#include <string.h>
#include <initializer_list>

namespace skiagm {

class ColrV1GM : public GM {
public:

  // TODO(drott): Consolidate test fonts.
  enum ColrV1TestType {
    kSkiaSampleFont,
    kColorFontsRepoGradients,
    kColorFontsRepoScaling,
    kColorFontsRepoExtendMode,
    kColorFontsRepoRotate,
    kColorFontsRepoSkew,
    kColorFontsRepoTransform,
    kColorFontsRepoClipBox,
    kColorFontsRepoComposite,
    kColorFontsRepoForeground
  };

  ColrV1GM(ColrV1TestType testType, SkScalar skewX, SkScalar rotateDeg)
          : fSkewX(skewX), fRotateDeg(rotateDeg), fTestType(testType) {}

protected:
    static SkString testTypeToString(ColrV1TestType testType) {
        switch (testType) {
            case kSkiaSampleFont:
                return SkString("skia");
            case kColorFontsRepoGradients:
                return SkString("gradients");
            case kColorFontsRepoScaling:
                return SkString("scaling");
            case kColorFontsRepoExtendMode:
                return SkString("extend_mode");
            case kColorFontsRepoRotate:
                return SkString("rotate");
            case kColorFontsRepoSkew:
                return SkString("skew");
            case kColorFontsRepoTransform:
                return SkString("transform");
            case kColorFontsRepoClipBox:
                return SkString("clipbox");
            case kColorFontsRepoComposite:
                return SkString("composite");
            case kColorFontsRepoForeground:
                return SkString("foreground");
        }
        SkASSERT(false); /* not reached */
        return SkString();
    }

    struct EmojiFont {
        sk_sp<SkTypeface> fTypeface;
        std::vector<uint16_t> fGlyphs;
        size_t bytesize() { return fGlyphs.size() * sizeof(uint16_t); }
    } fEmojiFont;

    void onOnceBeforeDraw() override {
        if (fTestType == kSkiaSampleFont) {
            fEmojiFont.fTypeface = MakeResourceAsTypeface("fonts/colrv1_samples.ttf");
            fEmojiFont.fGlyphs = {19, 33, 34, 35, 20, 21, 22, 23, 24, 25};
            return;
        }

        fEmojiFont.fTypeface = MakeResourceAsTypeface("fonts/more_samples-glyf_colr_1.ttf");

        switch (fTestType) {
            case kSkiaSampleFont:
                SkASSERT(false);
                break;
            case kColorFontsRepoGradients:
                fEmojiFont.fGlyphs = {2, 5, 6, 7, 8, 55};
                break;
            case kColorFontsRepoScaling:
                fEmojiFont.fGlyphs = {9, 10, 11, 12, 13, 14};
                break;
            case kColorFontsRepoExtendMode:
                fEmojiFont.fGlyphs = {15, 16, 17, 18, 19, 20};
                break;
            case kColorFontsRepoRotate:
                fEmojiFont.fGlyphs = {21, 22, 23, 24};
                break;
            case kColorFontsRepoSkew:
                fEmojiFont.fGlyphs = {25, 26, 27, 28, 29, 30};
                break;
            case kColorFontsRepoTransform:
                fEmojiFont.fGlyphs = {31, 32, 33, 34};
                break;
            case kColorFontsRepoClipBox:
                fEmojiFont.fGlyphs = {35, 36, 37, 38, 39};
                break;
            case kColorFontsRepoComposite:
                fEmojiFont.fGlyphs = {40, 41, 42, 43, 44, 45, 46};
                break;
            case kColorFontsRepoForeground:
                fEmojiFont.fGlyphs = {47, 48, 49, 50, 51, 52, 53, 54};
                break;
        }
    }

    SkString onShortName() override {
        SkString gm_name = SkStringPrintf("colrv1_%s_samples",
                                          testTypeToString(fTestType).c_str());
        if (fSkewX) {
            gm_name.append("_skew");
        }

        if (fRotateDeg) {
            gm_name.append("_rotate");
        }
        return gm_name;
    }

    SkISize onISize() override { return SkISize::Make(1400, 600); }

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

        canvas->translate(200, 20);

        if (!fEmojiFont.fTypeface) {
          *errorMsg = "Did not recognize COLR v1 font format.";
          return DrawResult::kSkip;
        }

        canvas->rotate(fRotateDeg);
        canvas->skew(fSkewX, 0);

        SkFont font(fEmojiFont.fTypeface);

        SkFontMetrics metrics;
        SkScalar y = 0;
        std::vector<SkColor> paint_colors = {
                SK_ColorBLACK, SK_ColorGREEN, SK_ColorRED, SK_ColorBLUE};
        auto paint_color_iterator = paint_colors.begin();
        for (SkScalar textSize : { 12, 18, 30, 120 }) {
            font.setSize(textSize);
            font.getMetrics(&metrics);
            y += -metrics.fAscent;
            paint.setColor(*paint_color_iterator);
            canvas->drawSimpleText(fEmojiFont.fGlyphs.data(),
                                   fEmojiFont.bytesize(),
                                   SkTextEncoding::kGlyphID,
                                   10, y, font, paint);
            y += metrics.fDescent + metrics.fLeading;
            paint_color_iterator++;
        }
        return DrawResult::kOk;
    }

private:
    using INHERITED = GM;
    SkScalar fSkewX;
    SkScalar fRotateDeg;
    ColrV1TestType fTestType;
};

DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, -0.5f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, 0.f, 20.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, -0.5f, 20.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoGradients, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoScaling, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoExtendMode, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoRotate, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoSkew, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoTransform, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoClipBox, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoClipBox, -0.5f, 20.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoComposite, 0.f, 0.f);)
DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoForeground, 0.f, 0.f);)

}  // namespace skiagm
