/*
 * 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/SkFont.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/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

namespace skiagm {

constexpr int kWidth = 750;
constexpr int kHeight = 750;

class LcdOverlapGM : public skiagm::GM {
public:
    LcdOverlapGM() {
        const int kPointSize = 25;
        fTextHeight = SkIntToScalar(kPointSize);
    }

protected:
    SkString getName() const override { return SkString("lcdoverlap"); }

    void onOnceBeforeDraw() override {
        // build text blob
        SkTextBlobBuilder builder;

        SkFont      font(ToolUtils::DefaultPortableTypeface(), 32);
        const char* text = "able was I ere I saw elba";
        font.setSubpixel(true);
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
        ToolUtils::add_to_text_blob(&builder, text, font, 0, 0);
        fBlob = builder.make();
    }

    SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }

    void drawTestCase(SkCanvas* canvas, SkScalar x, SkScalar y, SkBlendMode mode,
                      SkBlendMode mode2) {
        const SkColor colors[] {
                SK_ColorRED,
                SK_ColorGREEN,
                SK_ColorBLUE,
                SK_ColorYELLOW,
                SK_ColorCYAN,
                SK_ColorMAGENTA,
        };

        for (size_t i = 0; i < std::size(colors); i++) {
            canvas->save();
            canvas->translate(x, y);
            canvas->rotate(360.0f / std::size(colors) * i);
            canvas->translate(-fBlob->bounds().width() / 2.0f - fBlob->bounds().left() + 0.5f, 0);

            SkPaint textPaint;
            textPaint.setColor(colors[i]);
            textPaint.setBlendMode(i % 2 == 0 ? mode : mode2);
            canvas->drawTextBlob(fBlob, 0, 0, textPaint);
            canvas->restore();
        }
    }

    void onDraw(SkCanvas* canvas) override {
        SkScalar offsetX = kWidth / 4.0f;
        SkScalar offsetY = kHeight / 4.0f;
        drawTestCase(canvas, offsetX, offsetY,  SkBlendMode::kSrc, SkBlendMode::kSrc);
        drawTestCase(canvas, 3 * offsetX, offsetY,  SkBlendMode::kSrcOver, SkBlendMode::kSrcOver);
        drawTestCase(canvas, offsetX, 3 * offsetY,  SkBlendMode::kHardLight,
                     SkBlendMode::kLuminosity);
        drawTestCase(canvas, 3 * offsetX, 3 * offsetY,  SkBlendMode::kSrcOver, SkBlendMode::kSrc);
    }

private:
    SkScalar fTextHeight;
    sk_sp<SkTextBlob> fBlob;
    using INHERITED = skiagm::GM;
};

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

DEF_GM( return new LcdOverlapGM; )
}  // namespace skiagm
