/*
 * Copyright 2011 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/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.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/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "include/effects/SkImageFilters.h"
#include "include/effects/SkTableColorFilter.h"

#include <math.h>
#include <utility>

static sk_sp<SkShader> make_shader0(int w, int h) {
    SkPoint pts[] = { {0, 0}, {SkIntToScalar(w), SkIntToScalar(h)} };
    SkColor colors[] = {
        SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
        SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
    };
    return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
                                        SkTileMode::kClamp);
}
static void make_bm0(SkBitmap* bm) {
    int W = 120;
    int H = 120;
    bm->allocN32Pixels(W, H);
    bm->eraseColor(SK_ColorTRANSPARENT);

    SkCanvas canvas(*bm);
    SkPaint paint;
    paint.setShader(make_shader0(W, H));
    canvas.drawPaint(paint);
}
static sk_sp<SkShader> make_shader1(int w, int h) {
    SkScalar cx = SkIntToScalar(w)/2;
    SkScalar cy = SkIntToScalar(h)/2;
    SkColor colors[] = {
        SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
    };
    return SkGradientShader::MakeRadial(SkPoint::Make(cx, cy), cx, colors, nullptr,
                                        SK_ARRAY_COUNT(colors), SkTileMode::kClamp);
}
static void make_bm1(SkBitmap* bm) {
    int W = 120;
    int H = 120;
    SkScalar cx = SkIntToScalar(W)/2;
    SkScalar cy = SkIntToScalar(H)/2;
    bm->allocN32Pixels(W, H);
    bm->eraseColor(SK_ColorTRANSPARENT);

    SkCanvas canvas(*bm);
    SkPaint paint;
    paint.setShader(make_shader1(W, H));
    paint.setAntiAlias(true);
    canvas.drawCircle(cx, cy, cx, paint);
}

static void make_table0(uint8_t table[]) {
    for (int i = 0; i < 256; ++i) {
        int n = i >> 5;
        table[i] = (n << 5) | (n << 2) | (n >> 1);
    }
}
static void make_table1(uint8_t table[]) {
    for (int i = 0; i < 256; ++i) {
        table[i] = i * i / 255;
    }
}
static void make_table2(uint8_t table[]) {
    for (int i = 0; i < 256; ++i) {
        float fi = i / 255.0f;
        table[i] = static_cast<uint8_t>(sqrtf(fi) * 255);
    }
}

static sk_sp<SkColorFilter> make_null_cf() {
    return nullptr;
}

static sk_sp<SkColorFilter> make_cf0() {
    uint8_t table[256]; make_table0(table);
    return SkTableColorFilter::Make(table);
}
static sk_sp<SkColorFilter> make_cf1() {
    uint8_t table[256]; make_table1(table);
    return SkTableColorFilter::Make(table);
}
static sk_sp<SkColorFilter> make_cf2() {
    uint8_t table[256]; make_table2(table);
    return SkTableColorFilter::Make(table);
}
static sk_sp<SkColorFilter> make_cf3() {
    uint8_t table0[256]; make_table0(table0);
    uint8_t table1[256]; make_table1(table1);
    uint8_t table2[256]; make_table2(table2);
    return SkTableColorFilter::MakeARGB(nullptr, table0, table1, table2);
}

class TableColorFilterGM : public skiagm::GM {
public:
    TableColorFilterGM() {}

protected:
    SkString onShortName() override {
        return SkString("tablecolorfilter");
    }

    SkISize onISize() override {
        return {700, 1650};
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->drawColor(0xFFDDDDDD);
        canvas->translate(20, 20);

        static sk_sp<SkColorFilter> (*gColorFilterMakers[])() = {
            make_null_cf, make_cf0, make_cf1, make_cf2, make_cf3
        };
        static void (*gBitmapMakers[])(SkBitmap*) = { make_bm0, make_bm1 };

        // This test will be done once for each bitmap with the results stacked vertically.
        // For a single bitmap the resulting image will be the following:
        //  - A first line with the original bitmap, followed by the image drawn once
        //  with each of the N color filters
        //  - N lines of the bitmap drawn N times, this will cover all N*N combinations of
        //  pair of color filters in order to test the collapsing of consecutive table
        //  color filters.
        //
        //  Here is a graphical representation of the result for 2 bitmaps and 2 filters
        //  with the number corresponding to the number of filters the bitmap goes through:
        //
        //  --bitmap1
        //  011
        //  22
        //  22
        //  --bitmap2
        //  011
        //  22
        //  22

        SkScalar x = 0, y = 0;
        for (size_t bitmapMaker = 0; bitmapMaker < SK_ARRAY_COUNT(gBitmapMakers); ++bitmapMaker) {
            SkBitmap bm;
            gBitmapMakers[bitmapMaker](&bm);

            SkScalar xOffset = SkScalar(bm.width() * 9 / 8);
            SkScalar yOffset = SkScalar(bm.height() * 9 / 8);

            // Draw the first element of the first line
            x = 0;
            SkPaint paint;
            SkSamplingOptions sampling;

            canvas->drawImage(bm.asImage(), x, y);

            // Draws the rest of the first line for this bitmap
            // each draw being at xOffset of the previous one
            for (unsigned i = 1; i < SK_ARRAY_COUNT(gColorFilterMakers); ++i) {
                x += xOffset;
                paint.setColorFilter(gColorFilterMakers[i]());
                canvas->drawImage(bm.asImage(), x, y, sampling, &paint);
            }

            paint.setColorFilter(nullptr);

            for (unsigned i = 0; i < SK_ARRAY_COUNT(gColorFilterMakers); ++i) {
                sk_sp<SkColorFilter> colorFilter1(gColorFilterMakers[i]());
                sk_sp<SkImageFilter> imageFilter1(SkImageFilters::ColorFilter(
                        std::move(colorFilter1), nullptr));

                // Move down to the next line and draw it
                // each draw being at xOffset of the previous one
                y += yOffset;
                x = 0;
                for (unsigned j = 1; j < SK_ARRAY_COUNT(gColorFilterMakers); ++j) {
                    sk_sp<SkColorFilter> colorFilter2(gColorFilterMakers[j]());
                    sk_sp<SkImageFilter> imageFilter2(SkImageFilters::ColorFilter(
                            std::move(colorFilter2), imageFilter1, nullptr));
                    paint.setImageFilter(std::move(imageFilter2));
                    canvas->drawImage(bm.asImage(), x, y, sampling, &paint);
                    x += xOffset;
                }
            }

            // Move down one line to the beginning of the block for next bitmap
            y += yOffset;
        }
    }

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

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

class ComposeColorFilterGM : public skiagm::GM {
    enum {
        COLOR_COUNT = 3,
        MODE_COUNT = 4,
    };
    const SkColor*      fColors;
    const SkBlendMode*  fModes;
    const char*         fName;

public:
    ComposeColorFilterGM(const SkColor colors[], const SkBlendMode modes[], const char* name)
        : fColors(colors), fModes(modes), fName(name) {}

private:
    SkString onShortName() override { return SkString(fName); }

    SkISize onISize() override { return {790, 790}; }

    void onDraw(SkCanvas* canvas) override {
        SkBitmap bm;
        make_bm1(&bm);

        canvas->drawColor(0xFFDDDDDD);

        const int MODES = MODE_COUNT * COLOR_COUNT;
        sk_sp<SkColorFilter> filters[MODES];
        int index = 0;
        for (int i = 0; i < MODE_COUNT; ++i) {
            for (int j = 0; j < COLOR_COUNT; ++j) {
                filters[index++] = SkColorFilters::Blend(fColors[j], fModes[i]);
            }
        }

        SkPaint paint;
        paint.setShader(make_shader1(50, 50));
        SkRect r = SkRect::MakeWH(50, 50);
        const SkScalar spacer = 10;

        canvas->translate(spacer, spacer);

        canvas->drawRect(r, paint); // orig

        for (int i = 0; i < MODES; ++i) {
            paint.setColorFilter(filters[i]);

            canvas->save();
            canvas->translate((i + 1) * (r.width() + spacer), 0);
            canvas->drawRect(r, paint);
            canvas->restore();

            canvas->save();
            canvas->translate(0, (i + 1) * (r.width() + spacer));
            canvas->drawRect(r, paint);
            canvas->restore();
        }

        canvas->translate(r.width() + spacer, r.width() + spacer);

        for (int y = 0; y < MODES; ++y) {
            canvas->save();
            for (int x = 0; x < MODES; ++x) {
                paint.setColorFilter(filters[y]->makeComposed(filters[x]));
                canvas->drawRect(r, paint);
                canvas->translate(r.width() + spacer, 0);
            }
            canvas->restore();
            canvas->translate(0, r.height() + spacer);
        }
    }
};

const SkColor gColors0[] = { SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW };
const SkBlendMode gModes0[] = {
    SkBlendMode::kOverlay,
    SkBlendMode::kDarken,
    SkBlendMode::kColorBurn,
    SkBlendMode::kExclusion,
};
DEF_GM( return new ComposeColorFilterGM(gColors0, gModes0, "colorcomposefilter_wacky"); )

const SkColor gColors1[] = { 0x80FF0000, 0x8000FF00, 0x800000FF };
const SkBlendMode gModes1[] = {
    SkBlendMode::kSrcOver,
    SkBlendMode::kXor,
    SkBlendMode::kDstOut,
    SkBlendMode::kSrcATop,
};
DEF_GM( return new ComposeColorFilterGM(gColors1, gModes1, "colorcomposefilter_alpha"); )
