/*
 * 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/SkPathBuilder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.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/utils/SkTextUtils.h"
#include "tools/ToolUtils.h"

enum {
    kXfermodeCount = (int)SkBlendMode::kLastMode + 1 + 1,   // extra for arith
    kShapeSize = 22,
    kShapeSpacing = 36,
    kShapeTypeSpacing = 4 * kShapeSpacing / 3,
    kPaintSpacing = 4 * kShapeTypeSpacing,
    kLabelSpacing = 3 * kShapeSize,
    kMargin = kShapeSpacing / 2,
    kXfermodeTypeSpacing = kLabelSpacing + 2 * kPaintSpacing + kShapeTypeSpacing,
    kTitleSpacing = 3 * kShapeSpacing / 4,
    kSubtitleSpacing = 5 * kShapeSpacing / 8
};

constexpr SkColor kBGColor = 0xc8d2b887;

constexpr SkColor kShapeColors[2] = {
    0x82ff0080,   // input color unknown
    0xff00ffff,   // input color opaque
};

enum Shape {
    kSquare_Shape,
    kDiamond_Shape,
    kOval_Shape,
    kConcave_Shape,

    kLast_Shape = kConcave_Shape
};

/**
 * Verifies AA works properly on all Xfermodes, including arithmetic, with both opaque and unknown
 * src colors.
 */
class AAXfermodesGM : public skiagm::GM {
public:
    AAXfermodesGM() {}

protected:
    enum DrawingPass {
        kCheckerboard_Pass,
        kBackground_Pass,
        kShape_Pass
    };

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

    SkISize onISize() override {
        return SkISize::Make(2 * kMargin + 2 * kXfermodeTypeSpacing -
                             (kXfermodeTypeSpacing - (kLabelSpacing + 2 * kPaintSpacing)),
                             2 * kMargin + kTitleSpacing + kSubtitleSpacing +
                             (1 + (int)SkBlendMode::kLastCoeffMode) * kShapeSpacing);
    }

    void onOnceBeforeDraw() override {
        fLabelFont.setTypeface(ToolUtils::create_portable_typeface());
        fLabelFont.setSize(5 * kShapeSize/8);
        fLabelFont.setSubpixel(true);

        constexpr SkScalar radius = -1.4f * kShapeSize/2;
        SkPoint pts[4] = {
            {-radius, 0},
            {0, -1.33f * radius},
            {radius, 0},
            {0, 1.33f * radius}
        };
        fOval = SkPathBuilder().moveTo(pts[0])
                               .quadTo(pts[1], pts[2])
                               .quadTo(pts[3], pts[0])
                               .detach();

        fConcave = SkPathBuilder().moveTo(-radius, 0)
                                  .quadTo(0, 0, 0, -radius)
                                  .quadTo(0, 0, radius, 0)
                                  .quadTo(0, 0, 0, radius)
                                  .quadTo(0, 0, -radius, 0)
                                  .close()
                                  .detach();
    }

    void draw_pass(SkCanvas* canvas, DrawingPass drawingPass) {
        SkRect clipRect =
                { -kShapeSize*11/16, -kShapeSize*11/16, kShapeSize*11/16, kShapeSize*11/16 };

        canvas->save();
        if (kCheckerboard_Pass == drawingPass) {
            canvas->translate(kMargin, kMargin);
        }
        canvas->translate(0, kTitleSpacing);

        for (size_t xfermodeSet = 0; xfermodeSet < 2; xfermodeSet++) {
            size_t firstMode = ((size_t)SkBlendMode::kLastCoeffMode + 1) * xfermodeSet;
            canvas->save();

            if (kShape_Pass == drawingPass) {
                SkTextUtils::DrawString(canvas, "Src Unknown",
                        kLabelSpacing + kShapeTypeSpacing * 1.5f + kShapeSpacing / 2,
                        kSubtitleSpacing / 2 + fLabelFont.getSize() / 3, fLabelFont, SkPaint(),
                                        SkTextUtils::kCenter_Align);
                SkTextUtils::DrawString(canvas, "Src Opaque",
                        kLabelSpacing + kShapeTypeSpacing * 1.5f + kShapeSpacing / 2 +
                        kPaintSpacing, kSubtitleSpacing / 2 + fLabelFont.getSize() / 3,
                                        fLabelFont, SkPaint(), SkTextUtils::kCenter_Align);
            }

            canvas->translate(0, kSubtitleSpacing + kShapeSpacing/2);

            for (size_t m = 0; m <= (size_t)SkBlendMode::kLastCoeffMode; m++) {
                if (firstMode + m > (size_t)SkBlendMode::kLastMode) {
                    break;
                }
                SkBlendMode mode = static_cast<SkBlendMode>(firstMode + m);
                canvas->save();

                if (kShape_Pass == drawingPass) {
                    this->drawModeName(canvas, mode);
                }
                canvas->translate(kLabelSpacing + kShapeSpacing/2, 0);

                for (size_t colorIdx = 0; colorIdx < std::size(kShapeColors); colorIdx++) {
                    SkPaint paint;
                    this->setupShapePaint(canvas, kShapeColors[colorIdx], mode, &paint);
                    SkASSERT(colorIdx == 0 || 255 == paint.getAlpha());
                    canvas->save();

                    for (size_t shapeIdx = 0; shapeIdx <= kLast_Shape; shapeIdx++) {
                        if (kShape_Pass != drawingPass) {
                            canvas->save();
                            canvas->clipRect(clipRect);
                            if (kCheckerboard_Pass == drawingPass) {
                                ToolUtils::draw_checkerboard(canvas, 0xffffffff, 0xffc6c3c6, 10);
                            } else {
                                SkASSERT(kBackground_Pass == drawingPass);
                                canvas->drawColor(kBGColor, SkBlendMode::kSrc);
                            }
                            canvas->restore();
                        } else {
                            this->drawShape(canvas, static_cast<Shape>(shapeIdx), paint, mode);
                        }
                        canvas->translate(kShapeTypeSpacing, 0);
                    }

                    canvas->restore();
                    canvas->translate(kPaintSpacing, 0);
                }

                canvas->restore();
                canvas->translate(0, kShapeSpacing);
            }

            canvas->restore();
            canvas->translate(kXfermodeTypeSpacing, 0);
        }

        canvas->restore();
    }

    void onDraw(SkCanvas* canvas) override {
        draw_pass(canvas, kCheckerboard_Pass);
        canvas->saveLayer(nullptr, nullptr);

        canvas->translate(kMargin, kMargin);
        draw_pass(canvas, kBackground_Pass);

        SkFont titleFont(fLabelFont);
        titleFont.setSize(9 * titleFont.getSize() / 8);
        titleFont.setEmbolden(true);
        SkTextUtils::DrawString(canvas, "Porter Duff",
                                kLabelSpacing + 4 * kShapeTypeSpacing,
                                kTitleSpacing / 2 + titleFont.getSize() / 3, titleFont, SkPaint(),
                                SkTextUtils::kCenter_Align);
        SkTextUtils::DrawString(canvas, "Advanced",
                                kXfermodeTypeSpacing + kLabelSpacing + 4 * kShapeTypeSpacing,
                                kTitleSpacing / 2 + titleFont.getSize() / 3, titleFont, SkPaint(),
                                SkTextUtils::kCenter_Align);

        draw_pass(canvas, kShape_Pass);
        canvas->restore();
    }

    void drawModeName(SkCanvas* canvas, SkBlendMode mode) {
        const char* modeName = SkBlendMode_Name(mode);
        SkTextUtils::DrawString(canvas, modeName, kLabelSpacing - kShapeSize / 4,
                                fLabelFont.getSize() / 4, fLabelFont, SkPaint(),
                                SkTextUtils::kRight_Align);
    }

    void setupShapePaint(SkCanvas* canvas, SkColor color, SkBlendMode mode, SkPaint* paint) {
        paint->setColor(color);

        if (mode == SkBlendMode::kPlus) {
            // Check for overflow, otherwise we might get confusing AA artifacts.
            int maxSum = std::max(std::max(SkColorGetA(kBGColor) + SkColorGetA(color),
                                       SkColorGetR(kBGColor) + SkColorGetR(color)),
                                std::max(SkColorGetG(kBGColor) + SkColorGetG(color),
                                       SkColorGetB(kBGColor) + SkColorGetB(color)));

            if (maxSum > 255) {
                SkPaint dimPaint;
                dimPaint.setAntiAlias(false);
                dimPaint.setBlendMode(SkBlendMode::kDstIn);
                if (255 != paint->getAlpha()) {
                    // Dim the src and dst colors.
                    dimPaint.setARGB(255 * 255 / maxSum, 0, 0, 0);
                    paint->setAlpha(255 * paint->getAlpha() / maxSum);
                } else {
                    // Just clear the dst, we need to preserve the paint's opacity.
                    dimPaint.setARGB(0, 0, 0, 0);
                }
                canvas->drawRect({ -kShapeSpacing/2, -kShapeSpacing/2,
                                   kShapeSpacing/2 + 3 * kShapeTypeSpacing, kShapeSpacing/2 },
                                 dimPaint);
            }
        }
    }

    void drawShape(SkCanvas* canvas, Shape shape, const SkPaint& paint, SkBlendMode mode) {
        SkASSERT(mode <= SkBlendMode::kLastMode);
        SkPaint shapePaint(paint);
        shapePaint.setAntiAlias(kSquare_Shape != shape);
        shapePaint.setBlendMode(mode);

        switch (shape) {
            case kSquare_Shape:
                canvas->drawRect({ -kShapeSize/2, -kShapeSize/2, kShapeSize/2, kShapeSize/2 },
                                 shapePaint);
                break;

            case kDiamond_Shape:
                canvas->save();
                canvas->rotate(45);
                canvas->drawRect({ -kShapeSize/2, -kShapeSize/2, kShapeSize/2, kShapeSize/2 },
                                 shapePaint);
                canvas->restore();
                break;

            case kOval_Shape:
                canvas->save();
                canvas->rotate(static_cast<SkScalar>((511 * (int)mode + 257) % 360));
                canvas->drawPath(fOval, shapePaint);
                canvas->restore();
                break;

            case kConcave_Shape:
                canvas->drawPath(fConcave, shapePaint);
                break;

            default:
                SK_ABORT("Invalid shape.");
        }
    }

private:
    SkFont    fLabelFont;
    SkPath    fOval;
    SkPath    fConcave;

    using INHERITED = skiagm::GM;
};
DEF_GM( return new AAXfermodesGM; )
