/*
 * 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 "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontArguments.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.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/SkMetaData.h"

#include <string.h>
#include <memory>
#include <utility>

namespace skiagm {

class FontScalerDistortableGM : public GM {
public:
    FontScalerDistortableGM() {
        this->setBGColor(0xFFFFFFFF);
    }

private:

    SkString onShortName() override {
        return SkString("fontscalerdistortable");
    }

    SkISize onISize() override {
        return SkISize::Make(550, 700);
    }

    bool fDirty = true;
    bool fOverride = false;

    size_t fAxisSliderCount = 0;
    struct AxisSlider {
        SkFourByteTag axis;
        SkScalar control[3];
        SkString name;
    };
    std::unique_ptr<AxisSlider[]> fAxisSliders;

    bool onGetControls(SkMetaData* controls) override {
        controls->setBool("Override", fOverride);
        for (size_t i = 0; i < fAxisSliderCount; ++i) {
            controls->setScalars(fAxisSliders[i].name.c_str(), 3, fAxisSliders[i].control);
        }
        return true;
    }

    void onSetControls(const SkMetaData& controls) override {
        bool oldOverride = fOverride;
        controls.findBool("Override", &fOverride);
        if (fOverride != oldOverride) {
            fDirty = true;
        }

        for (size_t i = 0; i < fAxisSliderCount; ++i) {
            SkScalar oldValue = fAxisSliders[i].control[0];
            controls.findScalars(fAxisSliders[i].name.c_str(), nullptr, fAxisSliders[i].control);
            if (oldValue != fAxisSliders[i].control[0]) {
                fDirty = true;
            }
        }
    }

    struct Info {
        sk_sp<SkTypeface> distortable;
        SkFourByteTag axisTag;
        SkScalar axisMin;
        SkScalar axisMax;
    } fInfo;

    void onOnceBeforeDraw() override {
        constexpr SkFourByteTag wght = SkSetFourByteTag('w','g','h','t');
        //constexpr SkFourByteTag wdth = SkSetFourByteTag('w','d','t','h');
        fInfo = {
            MakeResourceAsTypeface("fonts/Distortable.ttf"), wght, 0.5f, 2.0f
            //SkTypeface::MakeFromFile("/Library/Fonts/Skia.ttf"), wght, 0.48f, 3.2f
            //SkTypeface::MakeFromName("Skia", SkFontStyle()), wdth, 0.62f, 1.3f
            //SkTypeface::MakeFromFile("/System/Library/Fonts/SFNS.ttf"), wght, 100.0f, 900.0f
            //SkTypeface::MakeFromName(".SF NS", SkFontStyle()), wght, 100.0f, 900.0f
        };

        if (fInfo.distortable) {
            int axisCount = fInfo.distortable->getVariationDesignParameters(nullptr, 0);
            if (axisCount > 0) {
                auto axes = std::make_unique<SkFontParameters::Variation::Axis[]>(axisCount);
                axisCount = fInfo.distortable->getVariationDesignParameters(axes.get(), axisCount);
                if (axisCount > 0) {
                    fAxisSliders = std::make_unique<AxisSlider[]>(axisCount);
                    for (int i = 0; i < axisCount; ++i) {
                        fAxisSliders[i].axis = axes[i].tag;
                        fAxisSliders[i].control[0] = axes[i].def;
                        fAxisSliders[i].control[1] = axes[i].min;
                        fAxisSliders[i].control[2] = axes[i].max;
                        fAxisSliders[i].name.append((const char *)&axes[i].tag, 4);
                        fAxisSliders[i].name.appendS32(i);
                    }
                    fAxisSliderCount = axisCount;
                }
            }
        }
    }

    inline static constexpr int rows = 2;
    inline static constexpr int cols = 5;
    sk_sp<SkTypeface> typeface[rows][cols];

    void updateTypefaces() {
        sk_sp<SkFontMgr> fontMgr(SkFontMgr::RefDefault());

        std::unique_ptr<SkStreamAsset> distortableStream( fInfo.distortable
                                                        ? fInfo.distortable->openStream(nullptr)
                                                        : nullptr);
        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                using Coordinate = SkFontArguments::VariationPosition::Coordinate;
                int coordinateCount;
                std::unique_ptr<Coordinate[]> coordinates;
                if (fOverride) {
                    coordinateCount = fAxisSliderCount;
                    coordinates = std::make_unique<Coordinate[]>(coordinateCount);
                    for (size_t i = 0; i < fAxisSliderCount; ++i) {
                        coordinates[i].axis = fAxisSliders[i].axis;
                        coordinates[i].value = fAxisSliders[i].control[0];
                    }
                } else {
                    coordinateCount = 2;
                    coordinates = std::make_unique<Coordinate[]>(coordinateCount);
                    SkScalar styleValue = SkScalarInterp(fInfo.axisMin, fInfo.axisMax,
                                                         SkScalar(row*cols + col) / (rows*cols));
                    coordinates[0] = {fInfo.axisTag, styleValue};
                    coordinates[1] = {fInfo.axisTag, styleValue};
                }
                SkFontArguments::VariationPosition position = {coordinates.get(), coordinateCount};

                typeface[row][col] = [&]() -> sk_sp<SkTypeface> {
                    if (row == 0 && fInfo.distortable) {
                        return fInfo.distortable->makeClone(
                                SkFontArguments().setVariationDesignPosition(position));
                    }
                    if (distortableStream) {
                        return fontMgr->makeFromStream(distortableStream->duplicate(),
                                SkFontArguments().setVariationDesignPosition(position));
                    }
                    return nullptr;
                }();
            }
        }
        fDirty = false;
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        if (fDirty) {
            this->updateTypefaces();
        }

        SkPaint paint;
        paint.setAntiAlias(true);
        SkFont font;
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);

        const char* text = "abc";
        const size_t textLen = strlen(text);

        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                SkScalar x = SkIntToScalar(10);
                SkScalar y = SkIntToScalar(20);

                font.setTypeface(typeface[row][col] ? typeface[row][col] : nullptr);

                SkAutoCanvasRestore acr(canvas, true);
                canvas->translate(SkIntToScalar(30 + col * 100), SkIntToScalar(20));
                canvas->rotate(SkIntToScalar(col * 5), x, y * 10);

                {
                    SkPaint p;
                    p.setAntiAlias(true);
                    SkRect r;
                    r.setLTRB(x - 3, 15, x - 1, 280);
                    canvas->drawRect(r, p);
                }

                for (int ps = 6; ps <= 22; ps++) {
                    font.setSize(SkIntToScalar(ps));
                    canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
                    y += font.getMetrics(nullptr);
                }
            }
            canvas->translate(0, SkIntToScalar(360));
            font.setSubpixel(true);
            font.setLinearMetrics(true);
            font.setBaselineSnap(false);
        }
        return DrawResult::kOk;
    }
};

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

DEF_GM( return new FontScalerDistortableGM; )

}  // namespace skiagm
