/*
 * Copyright 2012 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 "SkColor.h"
#include "SkMatrixConvolutionImageFilter.h"
#include "SkGradientShader.h"

namespace skiagm {

class MatrixConvolutionGM : public GM {
public:
    MatrixConvolutionGM() : fInitialized(false) {
        this->setBGColor(0x00000000);
    }

protected:
    virtual SkString onShortName() {
        return SkString("matrixconvolution");
    }

    void make_bitmap() {
        fBitmap.allocN32Pixels(80, 80);
        SkBitmapDevice device(fBitmap);
        SkCanvas canvas(&device);
        canvas.clear(0x00000000);
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor(0xFFFFFFFF);
        paint.setTextSize(SkIntToScalar(180));
        SkPoint pts[2] = { SkPoint::Make(0, 0),
                           SkPoint::Make(0, SkIntToScalar(80)) };
        SkColor colors[2] = { 0xFFFFFFFF, 0x40404040 };
        SkScalar pos[2] = { 0, SkIntToScalar(80) };
        paint.setShader(SkGradientShader::CreateLinear(
            pts, colors, pos, 2, SkShader::kClamp_TileMode))->unref();
        const char* str = "e";
        canvas.drawText(str, strlen(str), SkIntToScalar(-10), SkIntToScalar(80), paint);
    }

    virtual SkISize onISize() {
        return make_isize(500, 300);
    }

    void draw(SkCanvas* canvas, int x, int y, const SkIPoint& target,
              SkMatrixConvolutionImageFilter::TileMode tileMode, bool convolveAlpha,
              const SkImageFilter::CropRect* cropRect = NULL) {
        SkScalar kernel[9] = {
            SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
            SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
            SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
        };
        SkISize kernelSize = SkISize::Make(3, 3);
        SkScalar gain = 0.3f, bias = SkIntToScalar(100);
        SkPaint paint;
        SkAutoTUnref<SkImageFilter> filter(
            SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize,
                                                        kernel,
                                                        gain,
                                                        bias,
                                                        target,
                                                        tileMode,
                                                        convolveAlpha,
                                                        NULL,
                                                        cropRect)));
        paint.setImageFilter(filter);
        canvas->save();
        canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
        canvas->clipRect(SkRect::MakeWH(SkIntToScalar(fBitmap.width()),
                                        SkIntToScalar(fBitmap.height())));
        canvas->drawBitmap(fBitmap, 0, 0, &paint);
        canvas->restore();
    }

    typedef SkMatrixConvolutionImageFilter MCIF;

    virtual void onDraw(SkCanvas* canvas) {
        if (!fInitialized) {
            make_bitmap();
            fInitialized = true;
        }
        canvas->clear(0x00000000);
        SkIPoint target = SkIPoint::Make(1, 0);
        for (int x = 10; x < 310; x += 100) {
            this->draw(canvas, x, 10, target, MCIF::kClamp_TileMode, true);
            this->draw(canvas, x, 110, target, MCIF::kClampToBlack_TileMode, true);
            this->draw(canvas, x, 210, target, MCIF::kRepeat_TileMode, true);
            target.fY++;
        }
        target.fY = 1;
        SkImageFilter::CropRect rect(SkRect::MakeXYWH(10, 5, 60, 60));
        this->draw(canvas, 310, 10, target, MCIF::kClamp_TileMode, true, &rect);
        this->draw(canvas, 310, 110, target, MCIF::kClampToBlack_TileMode, true, &rect);
        this->draw(canvas, 310, 210, target, MCIF::kRepeat_TileMode, true, &rect);

        this->draw(canvas, 410, 10, target, MCIF::kClamp_TileMode, false);
        this->draw(canvas, 410, 110, target, MCIF::kClampToBlack_TileMode, false);
        this->draw(canvas, 410, 210, target, MCIF::kRepeat_TileMode, false);
    }

private:
    typedef GM INHERITED;
    SkBitmap fBitmap;
    bool fInitialized;
};

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

static GM* MyFactory(void*) { return new MatrixConvolutionGM; }
static GMRegistry reg(MyFactory);

}
