/*
 * Copyright 2019 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/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"

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

#ifdef SK_BUILD_FOR_MAC

#include "include/core/SkSurface.h"

#import <ApplicationServices/ApplicationServices.h>

static void std_cg_setup(CGContextRef ctx) {
    CGContextSetAllowsFontSubpixelQuantization(ctx, false);
    CGContextSetShouldSubpixelQuantizeFonts(ctx, false);

    // Because CG always draws from the horizontal baseline,
    // if there is a non-integral translation from the horizontal origin to the vertical origin,
    // then CG cannot draw the glyph in the correct location without subpixel positioning.
    CGContextSetAllowsFontSubpixelPositioning(ctx, true);
    CGContextSetShouldSubpixelPositionFonts(ctx, true);

    CGContextSetAllowsFontSmoothing(ctx, true);
    CGContextSetShouldAntialias(ctx, true);

    CGContextSetTextDrawingMode(ctx, kCGTextFill);

    // Draw black on white to create mask. (Special path exists to speed this up in CG.)
    CGContextSetGrayFillColor(ctx, 0.0f, 1.0f);
}

static CGContextRef make_cg_ctx(const SkPixmap& pm) {
    CGBitmapInfo info;
    CGColorSpaceRef cs;

    switch (pm.colorType()) {
        case kRGBA_8888_SkColorType:
            info = kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst;
            cs = CGColorSpaceCreateDeviceRGB();
            break;
        case kGray_8_SkColorType:
            info = kCGImageAlphaNone;
            cs = CGColorSpaceCreateDeviceGray();
            break;
        case kAlpha_8_SkColorType:
            info = kCGImageAlphaOnly;
            cs = nullptr;
            break;
        default:
            return nullptr;
    }
    auto ctx = CGBitmapContextCreate(pm.writable_addr(), pm.width(), pm.height(), 8, pm.rowBytes(),
                                     cs, info);
    std_cg_setup(ctx);
    return ctx;
}

static void test_mac_fonts(SkCanvas* canvas, SkScalar size, SkScalar xpos) {
    int w = 32;
    int h = 32;

    canvas->scale(10, 10);
    SkScalar y = 1;

    for (SkColorType ct : {kRGBA_8888_SkColorType, kGray_8_SkColorType, kAlpha_8_SkColorType}) {
        SkImageInfo ii = SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType);
        auto surf = SkSurface::MakeRaster(ii);
        SkPixmap pm;
        surf->peekPixels(&pm);
        CGContextRef ctx = make_cg_ctx(pm);
        CGContextSelectFont(ctx, "Times", size, kCGEncodingMacRoman);

        SkScalar x = 1;
        for (bool smooth : {false, true}) {
            surf->getCanvas()->clear(ct == kAlpha_8_SkColorType ? 0 : 0xFFFFFFFF);
            CGContextSetShouldSmoothFonts(ctx, smooth);
            CGContextShowTextAtPoint(ctx, 2 + xpos, 2, "A", 1);

            surf->draw(canvas, x, y, nullptr);
            x += pm.width();
        }
        y += pm.height();
    }
}

class MacAAFontsGM : public skiagm::GM {
    SkScalar fSize = 16;
    SkScalar fXPos = 0;

public:
    MacAAFontsGM() {}
    ~MacAAFontsGM() override {}

protected:
    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        test_mac_fonts(canvas, fSize, fXPos);

        return DrawResult::kOk;
    }

    SkISize onISize() override { return { 1024, 768 }; }

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

    bool onHandleKey(SkUnichar uni) override {
        switch (uni) {
            case 'i': fSize += 1; return true;
            case 'k': fSize -= 1; return true;
            case 'j': fXPos -= 1.0f/16; return true;
            case 'l': fXPos += 1.0f/16; return true;
            default: break;
        }
        return false;
    }
};
DEF_GM(return new MacAAFontsGM;)

#endif

DEF_SIMPLE_GM(macaa_colors, canvas, 800, 500) {
    const SkColor GRAY = 0xFF808080;
    const SkColor colors[] = {
        SK_ColorBLACK, SK_ColorWHITE,
        SK_ColorBLACK, GRAY,
        SK_ColorWHITE, SK_ColorBLACK,
        SK_ColorWHITE, GRAY,
    };
    const SkScalar sizes[] = {10, 12, 15, 18, 24};

    const SkScalar width = 200;
    const SkScalar height = 500;
    const char str[] = "Hamburgefons";
    const size_t len = strlen(str);

    SkFont font;
    font.setTypeface(SkTypeface::MakeFromName("Times", SkFontStyle()));

    for (size_t i = 0; i < SK_ARRAY_COUNT(colors); i += 2) {
        canvas->save();

        SkPaint paint;
        paint.setColor(colors[i+1]);
        canvas->drawRect({0, 0, width, height}, paint);
        paint.setColor(colors[i]);

        SkScalar y = 10;
        SkScalar x = 10;
        for (SkScalar ps : sizes) {
            font.setSize(ps);
            for (bool lcd : {false, true}) {
                font.setEdging(lcd ? SkFont::Edging::kSubpixelAntiAlias
                                   : SkFont::Edging::kAntiAlias);
                for (auto h : {SkFontHinting::kNone, SkFontHinting::kNormal}) {
                    font.setHinting(h);

                    y += font.getSpacing() + 2;
                    canvas->drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
                }
            }
            y += 8;
        }
        canvas->restore();
        canvas->translate(width, 0);
    }
}
