/*
 * 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.h"
#include "SkCanvas.h"
#include "SkColorFilterImageFilter.h"
#include "SkGradientShader.h"
#include "SkTableColorFilter.h"

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),
                                        SkShader::kClamp_TileMode);
}
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), SkShader::kClamp_TileMode);
}
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:
    virtual SkString onShortName() {
        return SkString("tablecolorfilter");
    }

    virtual SkISize onISize() {
        return SkISize::Make(700, 1650);
    }

    virtual void onDraw(SkCanvas* canvas) {
        canvas->drawColor(sk_tool_utils::color_to_565(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 collpsing 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;
            canvas->drawBitmap(bm, x, y, &paint);

            // 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->drawBitmap(bm, x, y, &paint);
            }

            paint.setColorFilter(nullptr);

            for (unsigned i = 0; i < SK_ARRAY_COUNT(gColorFilterMakers); ++i) {
                sk_sp<SkColorFilter> colorFilter1(gColorFilterMakers[i]());
                sk_sp<SkImageFilter> imageFilter1(SkColorFilterImageFilter::Make(
                            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(SkColorFilterImageFilter::Make(
                                std::move(colorFilter2), imageFilter1, nullptr));
                    paint.setImageFilter(std::move(imageFilter2));
                    canvas->drawBitmap(bm, x, y, &paint);
                    x += xOffset;
                }
            }

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

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

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

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

public:
    ComposeColorFilterGM(const SkColor colors[], const SkXfermode::Mode modes[],
                         const char suffix[])
        : fColors(colors), fModes(modes)
    {
        fName.printf("colorcomposefilter_%s", suffix);
    }

protected:
    virtual SkString onShortName() {
        return fName;
    }

    virtual SkISize onISize() {
        return SkISize::Make(790, 790);
    }

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

        canvas->drawColor(sk_tool_utils::color_to_565(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++] = SkColorFilter::MakeModeFilter(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(SkColorFilter::MakeComposeFilter(filters[y], filters[x]));
                canvas->drawRect(r, paint);
                canvas->translate(r.width() + spacer, 0);
            }
            canvas->restore();
            canvas->translate(0, r.height() + spacer);
        }
    }

private:
    typedef GM INHERITED;
};

const SkColor gColors0[] = { SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW };
const SkXfermode::Mode gModes0[] = {
    SkXfermode::kOverlay_Mode,
    SkXfermode::kDarken_Mode,
    SkXfermode::kColorBurn_Mode,
    SkXfermode::kExclusion_Mode,
};
DEF_GM( return new ComposeColorFilterGM(gColors0, gModes0, "wacky"); )

const SkColor gColors1[] = { 0x80FF0000, 0x8000FF00, 0x800000FF };
const SkXfermode::Mode gModes1[] = {
    SkXfermode::kSrcOver_Mode,
    SkXfermode::kXor_Mode,
    SkXfermode::kDstOut_Mode,
    SkXfermode::kSrcATop_Mode,
};
DEF_GM( return new ComposeColorFilterGM(gColors1, gModes1, "alpha"); )
