/*
 * Copyright 2013 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/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.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 "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "src/core/SkFontPriv.h"
#include "tools/SkMetaData.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

#include <array>
#include <utility>

// limit this just so we don't take too long to draw
#define MAX_FAMILIES    30

static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
                           SkScalar y, const SkFont& font) {
    canvas->drawString(text, x, y, font, SkPaint());
    return x + font.measureText(text.c_str(), text.size(), SkTextEncoding::kUTF8);
}

static SkScalar drawCharacter(SkCanvas* canvas, SkUnichar character, SkScalar x,
                              SkScalar y, const SkFont& origFont, SkFontMgr* fm,
                              const char* fontName, const char* bcp47[], int bcp47Count,
                              const SkFontStyle& fontStyle) {
    SkFont font = origFont;
    // find typeface containing the requested character and draw it
    SkString ch;
    ch.appendUnichar(character);
    sk_sp<SkTypeface> typeface(fm->matchFamilyStyleCharacter(fontName, fontStyle,
                                                             bcp47, bcp47Count, character));
    font.setTypeface(typeface);
    x = drawString(canvas, ch, x, y, font) + 20;

    // repeat the process, but this time use the family name of the typeface
    // from the first pass.  This emulates the behavior in Blink where it
    // it expects to get the same glyph when following this pattern.
    if (typeface) {
        SkString familyName;
        typeface->getFamilyName(&familyName);
        font.setTypeface(fm->legacyMakeTypeface(familyName.c_str(), typeface->fontStyle()));
        x = drawString(canvas, ch, x, y, font) + 20;
    }

    // find typeface containing the requested character and draw it
    SkFontMgr::Request request;
    SkFontMgr::Request::CMapEntry cmapEntry{character, 0};
    request.cmapEntries = SkSpan(&cmapEntry, 1);
    request.bcp47 = SkSpan(bcp47, bcp47Count);
    request.familyName = fontName;
    SkFontArguments::VariationPosition::Coordinate model[4];
    SkFontMgr::Request::SetModel(fontStyle, model);
    request.model = SkSpan(model);
    sk_sp<SkTypeface> typeface1 = fm->fallback(request);
    font.setTypeface(typeface1);
    x = drawString(canvas, ch, x, y, font) + 20;

    return x;
}

static const char* zh = "zh";
static const char* ja = "ja";

class FontMgrGM : public skiagm::GM {
    sk_sp<SkFontMgr> fFM;

    void onOnceBeforeDraw() override {
        SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
        fFM = ToolUtils::TestFontMgr();
    }

    SkString getName() const override { return SkString("fontmgr_iter"); }

    SkISize getISize() override { return {1536, 768}; }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        SkScalar y = 20;
        SkFont font = ToolUtils::DefaultFont();
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
        font.setSubpixel(true);
        font.setSize(17);

        SkFontMgr* fm = fFM.get();
        int count = std::min(fm->countFamilies(), MAX_FAMILIES);
        if (count == 0) {
            *errorMsg = "No families in SkFontMgr";
            return DrawResult::kSkip;
        }

        for (int i = 0; i < count; ++i) {
            SkString familyName;
            fm->getFamilyName(i, &familyName);
            font.setTypeface(ToolUtils::DefaultTypeface());
            (void)drawString(canvas, familyName, 20, y, font);

            SkScalar x = 220;

            sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
            for (int j = 0; j < set->count(); ++j) {
                SkString sname;
                SkFontStyle fs;
                set->getStyle(j, &fs, &sname);
                sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.slant());

                font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
                x = drawString(canvas, sname, x, y, font) + 20;

                // check to see that we get different glyphs in japanese and chinese
                x = drawCharacter(canvas, 0x5203, x, y, font, fm, familyName.c_str(), &zh, 1, fs);
                x = drawCharacter(canvas, 0x5203, x, y, font, fm, familyName.c_str(), &ja, 1, fs);
                // check that emoji characters are found
                x = drawCharacter(canvas, 0x1f601, x, y, font, fm, familyName.c_str(), nullptr,0, fs);
            }
            y += 24;
        }
        return DrawResult::kOk;
    }
};

class FontMgrMatchGM : public skiagm::GM {
    sk_sp<SkFontMgr> fFM;

    void onOnceBeforeDraw() override {
        fFM = ToolUtils::TestFontMgr();
        SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
    }

    SkString getName() const override { return SkString("fontmgr_match"); }

    SkISize getISize() override { return {640, 1024}; }

    void iterateFamily(SkCanvas* canvas, const SkFont& font, SkFontStyleSet* fset) {
        SkFont f(font);
        SkScalar y = 0;

        for (int j = 0; j < fset->count(); ++j) {
            SkString sname;
            SkFontStyle fs;
            fset->getStyle(j, &fs, &sname);

            sname.appendf(" [%d %d]", fs.weight(), fs.width());

            f.setTypeface(sk_sp<SkTypeface>(fset->createTypeface(j)));
            SkScalar x = 0;
            x = drawString(canvas, sname, x, y, f) + 20;
            // check to see that we get different glyphs in japanese and chinese
            // and the style matches with no name
            x = drawCharacter(canvas, 0x5203, x, y, font, fFM.get(), nullptr, &zh, 1, fs);
            x = drawCharacter(canvas, 0x5203, x, y, font, fFM.get(), nullptr, &ja, 1, fs);
            y += 24;
        }
    }

    void exploreFamily(SkCanvas* canvas, const SkFont& font, SkFontStyleSet* fset) {
        SkFont f(font);
        SkScalar y = 0;

        for (int weight = 100; weight <= 900; weight += 200) {
            for (int width = 1; width <= 9; width += 2) {
                SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant);
                sk_sp<SkTypeface> face(fset->matchStyle(fs));
                if (face) {
                    SkString str;
                    str.printf("request [%d %d]", fs.weight(), fs.width());
                    f.setTypeface(std::move(face));
                    SkScalar x = 0;
                    x = drawString(canvas, str, x, y, f) + 20;
                    // check to see that we get different glyphs in japanese and chinese
                    // and the style matches with no name
                    x = drawCharacter(canvas, 0x5203, x, y, font, fFM.get(), nullptr, &zh, 1, fs);
                    x = drawCharacter(canvas, 0x5203, x, y, font, fFM.get(), nullptr, &ja, 1, fs);
                    y += 24;
                }
            }
        }
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        SkFont font = ToolUtils::DefaultFont();
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
        font.setSubpixel(true);
        font.setSize(17);

        static constexpr auto gNames = std::to_array<const char*>({
                "Helvetica Neue",
                "Arial",
                "sans",
                "Roboto",
        });

        sk_sp<SkFontStyleSet> fset;
        for (size_t i = 0; i < std::size(gNames); ++i) {
            fset = fFM->matchFamily(gNames[i]);
            if (fset->count() > 0) {
                break;
            }
        }
        if (!fset || fset->count() == 0) {
            *errorMsg = "No SkFontStyleSet";
            return DrawResult::kSkip;
        }

        canvas->translate(20, 40);
        this->exploreFamily(canvas, font, fset.get());
        canvas->translate(350, 0);
        this->iterateFamily(canvas, font, fset.get());
        return DrawResult::kOk;
    }
};

class FontMgrBoundsGM : public skiagm::GM {
public:
    FontMgrBoundsGM(float scale, float skew) : fScaleX(scale) , fSkewX(skew) {}

private:
    SkString getName() const override {
        if (fScaleX != 1 || fSkewX != 0) {
            return SkStringPrintf("fontmgr_bounds_%g_%g", fScaleX, fSkewX);
        }
        return SkString("fontmgr_bounds");
    }

    void onOnceBeforeDraw() override { fFM = ToolUtils::TestFontMgr(); }

    bool onGetControls(SkMetaData* controls) override {
        controls->setBool("Label Bounds", fLabelBounds);
        return true;
    }

    void onSetControls(const SkMetaData& controls) override {
        controls.findBool("Label Bounds", &fLabelBounds);
    }

    static SkRect show_bounds(SkCanvas* canvas, const SkFont& font, SkScalar x, SkScalar y,
                              SkColor boundsColor, bool labelBounds)
    {
        SkGlyphID left = 0, right = 0, top = 0, bottom = 0;
        SkRect min = SkRect::MakeLTRB(SK_ScalarInfinity, SK_ScalarInfinity,
                                      SK_ScalarNegativeInfinity, SK_ScalarNegativeInfinity);
        {
            int numGlyphs = font.getTypeface()->countGlyphs();
            for (int i = 0; i < numGlyphs; ++i) {
                SkGlyphID glyphId = i;
                SkRect cur = font.getBounds(glyphId, nullptr);
                if (cur.fLeft   < min.fLeft  ) { min.fLeft   = cur.fLeft;   left   = i; }
                if (cur.fTop    < min.fTop   ) { min.fTop    = cur.fTop ;   top    = i; }
                if (min.fRight  < cur.fRight ) { min.fRight  = cur.fRight;  right  = i; }
                if (min.fBottom < cur.fBottom) { min.fBottom = cur.fBottom; bottom = i; }
            }
        }

        SkRect fontBounds = SkFontPriv::GetFontBounds(font);

        SkRect drawBounds = min;
        drawBounds.join(fontBounds);

        SkAutoCanvasRestore acr(canvas, true);
        canvas->translate(x - drawBounds.left(), y);

        SkPaint boundsPaint;
        boundsPaint.setAntiAlias(true);
        boundsPaint.setColor(boundsColor);
        boundsPaint.setStyle(SkPaint::kStroke_Style);
        canvas->drawRect(fontBounds, boundsPaint);

        const SkScalar intervals[] = { 10.f, 10.f };
        boundsPaint.setPathEffect(SkDashPathEffect::Make(intervals, 0.f));
        canvas->drawRect(min, boundsPaint);

        SkFontMetrics fm;
        font.getMetrics(&fm);
        SkPaint metricsPaint(boundsPaint);
        metricsPaint.setStyle(SkPaint::kFill_Style);
        metricsPaint.setAlphaf(0.25f);
        if ((fm.fFlags & SkFontMetrics::kUnderlinePositionIsValid_Flag) &&
            (fm.fFlags & SkFontMetrics::kUnderlineThicknessIsValid_Flag))
        {
            SkRect underline{ min.fLeft,  fm.fUnderlinePosition,
                              min.fRight, fm.fUnderlinePosition + fm.fUnderlineThickness };
            canvas->drawRect(underline, metricsPaint);
        }

        if ((fm.fFlags & SkFontMetrics::kStrikeoutPositionIsValid_Flag) &&
            (fm.fFlags & SkFontMetrics::kStrikeoutThicknessIsValid_Flag))
        {
            SkRect strikeout{ min.fLeft,  fm.fStrikeoutPosition - fm.fStrikeoutThickness,
                              min.fRight, fm.fStrikeoutPosition };
            canvas->drawRect(strikeout, metricsPaint);
        }

        struct GlyphToDraw {
            SkGlyphID id;
            SkPoint location;
            SkScalar rotation;
        } glyphsToDraw [] = {
            {left,   {min.left(),    min.centerY()}, 270},
            {right,  {min.right(),   min.centerY()},  90},
            {top,    {min.centerX(), min.top()    },   0},
            {bottom, {min.centerX(), min.bottom() }, 180},
        };

        SkFont labelFont;
        labelFont.setEdging(SkFont::Edging::kAntiAlias);
        labelFont.setTypeface(ToolUtils::DefaultPortableTypeface());

        if (labelBounds) {
            SkString name;
            font.getTypeface()->getFamilyName(&name);
            canvas->drawString(name, min.fLeft, min.fBottom, labelFont, SkPaint());
        }
        for (const GlyphToDraw& glyphToDraw : glyphsToDraw) {
            SkPath path = font.getPath(glyphToDraw.id).value_or(SkPath());
            SkPaint::Style style = path.isEmpty() ? SkPaint::kFill_Style : SkPaint::kStroke_Style;
            SkPaint glyphPaint;
            glyphPaint.setStyle(style);
            canvas->drawSimpleText(&glyphToDraw.id, sizeof(glyphToDraw.id),
                                   SkTextEncoding::kGlyphID, 0, 0, font, glyphPaint);

            if (labelBounds) {
                SkAutoCanvasRestore acr2(canvas, true);
                canvas->translate(glyphToDraw.location.fX, glyphToDraw.location.fY);
                canvas->rotate(glyphToDraw.rotation);
                SkString glyphStr;
                glyphStr.appendS32(glyphToDraw.id);
                canvas->drawString(glyphStr, 0, 0, labelFont, SkPaint());
            }
        }

        return drawBounds;
    }

    SkISize getISize() override { return {1024, 850}; }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        SkFont font = ToolUtils::DefaultFont();
        font.setEdging(SkFont::Edging::kAntiAlias);
        font.setSubpixel(true);
        font.setSize(100);
        font.setScaleX(fScaleX);
        font.setSkewX(fSkewX);

        const std::array<SkColor, 2> boundsColors = {SK_ColorRED, SK_ColorBLUE};

        SkFontMgr* fm = fFM.get();
        int count = fm->countFamilies();
        if (count == 0) {
            *errorMsg = "No families in SkFontMgr under test.";
            return DrawResult::kSkip;
        }

        int index = 0;
        SkScalar x = 0, y = 0;

        canvas->translate(10, 120);

        int typefacesVisited = 0;
        for (int i = 0; i < count && typefacesVisited < 32; ++i) {
            sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
            int stylesVisited = 0;
            for (int j = 0; j < set->count() && typefacesVisited < 32 && stylesVisited < 3; ++j) {
                font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
                // Fonts with lots of glyphs are interesting, but can take a long time to find
                // the glyphs which make up the maximum extent.
                SkTypeface* typeface = font.getTypeface();
                if (typeface && 0 < typeface->countGlyphs() && typeface->countGlyphs() < 1000) {
                    ++typefacesVisited;
                    ++stylesVisited;

                    SkColor color = boundsColors[index & 1];
                    SkRect drawBounds = show_bounds(canvas, font, x, y, color, fLabelBounds);
                    x += drawBounds.width() + 20;
                    index += 1;
                    if (x > 900) {
                        x = 0;
                        y += 160;
                    }
                    if (y >= 700) {
                        return DrawResult::kOk;
                    }
                }
            }
        }
        return DrawResult::kOk;
    }

    sk_sp<SkFontMgr> fFM;
    const SkScalar fScaleX;
    const SkScalar fSkewX;
    bool fLabelBounds = false;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new FontMgrGM;)
DEF_GM(return new FontMgrMatchGM;)
DEF_GM(return new FontMgrBoundsGM(1, 0);)
DEF_GM(return new FontMgrBoundsGM(0.75f, 0);)
DEF_GM(return new FontMgrBoundsGM(1, -0.25f);)
