/*
 * 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/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkFilterQuality.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathMeasure.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/core/SkVertices.h"
#include "include/effects/SkGradientShader.h"
#include "include/private/SkTemplates.h"
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkFontPriv.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#include <initializer_list>

class DrawAtlasGM : public skiagm::GM {
    static sk_sp<SkImage> MakeAtlas(SkCanvas* caller, const SkRect& target) {
        SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
        auto        surface(ToolUtils::makeSurface(caller, info));
        SkCanvas* canvas = surface->getCanvas();
        // draw red everywhere, but we don't expect to see it in the draw, testing the notion
        // that drawAtlas draws a subset-region of the atlas.
        canvas->clear(SK_ColorRED);

        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kClear);
        SkRect r(target);
        r.inset(-1, -1);
        // zero out a place (with a 1-pixel border) to land our drawing.
        canvas->drawRect(r, paint);
        paint.setBlendMode(SkBlendMode::kSrcOver);
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(true);
        canvas->drawOval(target, paint);
        return surface->makeImageSnapshot();
    }

public:
    DrawAtlasGM() {}

protected:

    SkString onShortName() override {
        return SkString("draw-atlas");
    }

    SkISize onISize() override {
        return SkISize::Make(640, 480);
    }

    void onDraw(SkCanvas* canvas) override {
        const SkRect target = { 50, 50, 80, 90 };
        auto atlas = MakeAtlas(canvas, target);

        const struct {
            SkScalar fScale;
            SkScalar fDegrees;
            SkScalar fTx;
            SkScalar fTy;

            void apply(SkRSXform* xform) const {
                const SkScalar rad = SkDegreesToRadians(fDegrees);
                xform->fSCos = fScale * SkScalarCos(rad);
                xform->fSSin = fScale * SkScalarSin(rad);
                xform->fTx   = fTx;
                xform->fTy   = fTy;
            }
        } rec[] = {
            { 1, 0, 10, 10 },       // just translate
            { 2, 0, 110, 10 },      // scale + translate
            { 1, 30, 210, 10 },     // rotate + translate
            { 2, -30, 310, 30 },    // scale + rotate + translate
        };

        const int N = SK_ARRAY_COUNT(rec);
        SkRSXform xform[N];
        SkRect tex[N];
        SkColor colors[N];

        for (int i = 0; i < N; ++i) {
            rec[i].apply(&xform[i]);
            tex[i] = target;
            colors[i] = 0x80FF0000 + (i * 40 * 256);
        }

        SkPaint paint;
        paint.setFilterQuality(kLow_SkFilterQuality);
        paint.setAntiAlias(true);

        canvas->drawAtlas(atlas.get(), xform, tex, N, nullptr, &paint);
        canvas->translate(0, 100);
        canvas->drawAtlas(atlas.get(), xform, tex, colors, N, SkBlendMode::kSrcIn, nullptr, &paint);
    }

private:
    using INHERITED = GM;
};
DEF_GM( return new DrawAtlasGM; )

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

static void draw_text_on_path(SkCanvas* canvas, const void* text, size_t length,
                              const SkPoint xy[], const SkPath& path, const SkFont& font, const SkPaint& paint,
                              float baseline_offset) {
    SkPathMeasure meas(path, false);

    int count = font.countText(text, length, SkTextEncoding::kUTF8);
    size_t size = count * (sizeof(SkRSXform) + sizeof(SkScalar));
    SkAutoSMalloc<512> storage(size);
    SkRSXform* xform = (SkRSXform*)storage.get();
    SkScalar* widths = (SkScalar*)(xform + count);

    // Compute a conservative bounds so we can cull the draw
    const SkRect fontb = SkFontPriv::GetFontBounds(font);
    const SkScalar max = std::max(std::max(SkScalarAbs(fontb.fLeft), SkScalarAbs(fontb.fRight)),
                                std::max(SkScalarAbs(fontb.fTop), SkScalarAbs(fontb.fBottom)));
    const SkRect bounds = path.getBounds().makeOutset(max, max);

    SkAutoTArray<SkGlyphID> glyphs(count);
    font.textToGlyphs(text, length, SkTextEncoding::kUTF8, glyphs.get(), count);
    font.getWidths(glyphs.get(), count, widths);

    for (int i = 0; i < count; ++i) {
        // we want to position each character on the center of its advance
        const SkScalar offset = SkScalarHalf(widths[i]);
        SkPoint pos;
        SkVector tan;
        if (!meas.getPosTan(xy[i].x() + offset, &pos, &tan)) {
            pos = xy[i];
            tan.set(1, 0);
        }
        pos += SkVector::Make(-tan.fY, tan.fX) * baseline_offset;

        xform[i].fSCos = tan.x();
        xform[i].fSSin = tan.y();
        xform[i].fTx   = pos.x() - tan.y() * xy[i].y() - tan.x() * offset;
        xform[i].fTy   = pos.y() + tan.x() * xy[i].y() - tan.y() * offset;
    }

    canvas->drawTextBlob(SkTextBlob::MakeFromRSXform(glyphs.get(), count * sizeof(SkGlyphID),
                                         &xform[0], font, SkTextEncoding::kGlyphID),
                         0, 0, paint);

    if (true) {
        SkPaint p;
        p.setStyle(SkPaint::kStroke_Style);
        canvas->drawRect(bounds, p);
    }
}

static sk_sp<SkShader> make_shader() {
    SkPoint pts[2] = {{0, 0}, {220, 0}};
    SkColor colors[2] = {SK_ColorRED, SK_ColorBLUE};
    return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kMirror);
}

static void drawTextPath(SkCanvas* canvas, bool doStroke) {
    const char text0[] = "ABCDFGHJKLMNOPQRSTUVWXYZ";
    const int N = sizeof(text0) - 1;
    SkPoint pos[N];

    SkFont font;
    font.setSize(100);

    SkPaint paint;
    paint.setShader(make_shader());
    paint.setAntiAlias(true);
    if (doStroke) {
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(2.25f);
        paint.setStrokeJoin(SkPaint::kRound_Join);
    }

    SkScalar x = 0;
    for (int i = 0; i < N; ++i) {
        pos[i].set(x, 0);
        x += font.measureText(&text0[i], 1, SkTextEncoding::kUTF8, nullptr, &paint);
    }

    SkPath path;
    const float baseline_offset = -5;

    const SkPathDirection dirs[] = {
        SkPathDirection::kCW, SkPathDirection::kCCW,
    };
    for (auto d : dirs) {
        path.reset();
        path.addOval(SkRect::MakeXYWH(160, 160, 540, 540), d);
        draw_text_on_path(canvas, text0, N, pos, path, font, paint, baseline_offset);
    }

    paint.reset();
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawPath(path, paint);
}

DEF_SIMPLE_GM(drawTextRSXform, canvas, 430, 860) {
    canvas->scale(0.5f, 0.5f);
    const bool doStroke[] = { false, true };
    for (auto st : doStroke) {
        drawTextPath(canvas, st);
        canvas->translate(0, 860);
    }
}

// Exercise xform blob and its bounds
DEF_SIMPLE_GM(blob_rsxform, canvas, 500, 100) {
    SkFont font;
    font.setTypeface(ToolUtils::create_portable_typeface());
    font.setSize(50);

    const char text[] = "CrazyXform";
    constexpr size_t len = sizeof(text) - 1;

    SkRSXform xforms[len];
    SkScalar scale = 1;
    SkScalar x = 0, y = 0;
    for (size_t i = 0; i < len; ++i) {
        scale = SkScalarSin(i * SK_ScalarPI / (len-1)) * 0.75f + 0.5f;
        xforms[i] = SkRSXform::Make(scale, 0, x, y);
        x += 50 * scale;
    }

    auto blob = SkTextBlob::MakeFromRSXform(text, len, xforms, font);

    SkPoint offset = { 20, 70 };
    SkPaint paint;
    paint.setColor(0xFFCCCCCC);
    canvas->drawRect(blob->bounds().makeOffset(offset.fX, offset.fY), paint);
    paint.setColor(SK_ColorBLACK);
    canvas->drawTextBlob(blob, offset.fX, offset.fY, paint);
}

// Exercise xform blob and its tight bounds
DEF_SIMPLE_GM(blob_rsxform_distortable, canvas, 500, 100) {
    sk_sp<SkTypeface> typeface;
    std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
    if (distortable) {
        sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
        const SkFontArguments::VariationPosition::Coordinate position[] = {
            { SkSetFourByteTag('w','g','h','t'), 1.618033988749895f }
        };
        SkFontArguments params;
        params.setVariationDesignPosition({position, SK_ARRAY_COUNT(position)});
        typeface = fm->makeFromStream(std::move(distortable), params);
    }

    SkFont font(typeface, 50);

    const char text[] = "abcabcabc";
    constexpr size_t len = sizeof(text) - 1;

    SkRSXform xforms[len];
    SkScalar scale = 1;
    SkScalar x = 0, y = 0;
    for (size_t i = 0; i < len; ++i) {
        scale = SkScalarSin(i * SK_ScalarPI / (len-1)) * 0.75f + 0.5f;
        xforms[i] = SkRSXform::Make(scale, 0, x, y);
        x += 50 * scale;
    }

    auto blob = SkTextBlob::MakeFromRSXform(text, len, xforms, font);

    SkPoint offset = { 20, 70 };
    SkPaint paint;
    paint.setColor(0xFFCCCCCC);
    canvas->drawRect(blob->bounds().makeOffset(offset.fX, offset.fY), paint);
    paint.setColor(SK_ColorBLACK);
    canvas->drawTextBlob(blob, offset.fX, offset.fY, paint);
}

static sk_sp<SkVertices> make_vertices(sk_sp<SkImage> image, const SkRect& r,
                                       SkColor color) {
    SkPoint pos[4];
    r.toQuad(pos);
    SkColor colors[4] = { color, color, color, color };
    return SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode, 4,
                                pos, pos, colors);
}

/*
 *  drawAtlas and drawVertices have several things in common:
 *  - can create compound "shaders", combining texture and colors
 *      - these are combined via an explicit blendmode
 *  - like drawImage, they only respect parts of the paint
 *      - colorfilter, imagefilter, blendmode, alpha
 *
 *  This GM produces a series of pairs of images (atlas | vertices).
 *  Each pair should look the same, and each set shows a different combination
 *  of alpha | colorFilter | mode
 */
DEF_SIMPLE_GM(compare_atlas_vertices, canvas, 560, 585) {
    const SkRect tex = SkRect::MakeWH(128, 128);
    const SkRSXform xform = SkRSXform::Make(1, 0, 0, 0);
    const SkColor color = 0x884488CC;

    auto image = GetResourceAsImage("images/mandrill_128.png");
    auto verts = make_vertices(image, tex, color);
    const sk_sp<SkColorFilter> filters[] = {
        nullptr,
        SkColorFilters::Blend(0xFF00FF88, SkBlendMode::kModulate),
    };
    const SkBlendMode modes[] = {
        SkBlendMode::kSrcOver,
        SkBlendMode::kPlus,
    };

    canvas->translate(10, 10);
    SkPaint paint;
    for (SkBlendMode mode : modes) {
        for (float alpha : { 1.0f, 0.5f }) {
            paint.setAlphaf(alpha);
            canvas->save();
            for (const sk_sp<SkColorFilter>& cf : filters) {
                paint.setColorFilter(cf);
                canvas->drawAtlas(image, &xform, &tex, &color, 1,
                                  mode, &tex, &paint);
                canvas->translate(128, 0);
                paint.setShader(image->makeShader());
                canvas->drawVertices(verts, mode, paint);
                paint.setShader(nullptr);
                canvas->translate(145, 0);
            }
            canvas->restore();
            canvas->translate(0, 145);
        }
    }
}
