/*
 * 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 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::CreateLinear(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))->unref();
    canvas.drawPaint(paint);
}
static 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::CreateRadial(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))->unref();
    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 SkColorFilter* make_null_cf() {
    return nullptr;
}

static SkColorFilter* make_cf0() {
    uint8_t table[256]; make_table0(table);
    return SkTableColorFilter::Create(table);
}
static SkColorFilter* make_cf1() {
    uint8_t table[256]; make_table1(table);
    return SkTableColorFilter::Create(table);
}
static SkColorFilter* make_cf2() {
    uint8_t table[256]; make_table2(table);
    return SkTableColorFilter::Create(table);
}
static 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::CreateARGB(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 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]())->unref();
                canvas->drawBitmap(bm, x, y, &paint);
            }

            paint.setColorFilter(nullptr);

            for (unsigned i = 0; i < SK_ARRAY_COUNT(gColorFilterMakers); ++i) {
                SkAutoTUnref<SkColorFilter> colorFilter1(gColorFilterMakers[i]());
                SkAutoTUnref<SkImageFilter> imageFilter1(SkColorFilterImageFilter::Create(
                            colorFilter1, nullptr, 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) {
                    SkAutoTUnref<SkColorFilter> colorFilter2(gColorFilterMakers[j]());
                    SkAutoTUnref<SkImageFilter> imageFilter2(SkColorFilterImageFilter::Create(
                                colorFilter2, imageFilter1, nullptr));
                    paint.setImageFilter(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;
        SkAutoTUnref<SkColorFilter> filters[MODES];
        int index = 0;
        for (int i = 0; i < MODE_COUNT; ++i) {
            for (int j = 0; j < COLOR_COUNT; ++j) {
                filters[index++].reset(SkColorFilter::CreateModeFilter(fColors[j], fModes[i]));
            }
        }

        SkPaint paint;
        paint.setShader(make_shader1(50, 50))->unref();
        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) {
                SkAutoTUnref<SkColorFilter> compose(SkColorFilter::CreateComposeFilter(filters[y],
                                                                                       filters[x]));
                paint.setColorFilter(compose);
                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"); )
