/*
 * Copyright 2014 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 "SkColorCubeFilter.h"
#include "SkData.h"
#include "SkGradientShader.h"
#include "SkTemplates.h"

namespace skiagm {

static SkShader* MakeLinear() {
    static const SkPoint pts[2] = {
            { 0, 0 },
            { SkIntToScalar(80), SkIntToScalar(80) }
        };
    static const SkColor colors[] = { SK_ColorYELLOW, SK_ColorBLUE };
    return SkGradientShader::CreateLinear(
        pts, colors, nullptr, 2, SkShader::kRepeat_TileMode, 0, &SkMatrix::I());
}

class ColorCubeGM : public GM {
public:
    ColorCubeGM()
    : fInitialized(false)
    , f3DLut4(nullptr)
    , f3DLut8(nullptr)
    , f3DLut16(nullptr)
    , f3DLut32(nullptr)
    , f3DLut64(nullptr)
    {
        this->setBGColor(0xFF000000);
    }

    ~ColorCubeGM() {
        SkSafeUnref(f3DLut4);
        SkSafeUnref(f3DLut8);
        SkSafeUnref(f3DLut16);
        SkSafeUnref(f3DLut32);
        SkSafeUnref(f3DLut64);
    }

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

    void make_3Dluts() {
        make_3Dlut(&f3DLut4, 4, true, false, false);
        make_3Dlut(&f3DLut8, 8, false, true, false);
        make_3Dlut(&f3DLut16, 16, false, true, true);
        make_3Dlut(&f3DLut32, 32, true, true, false);
        make_3Dlut(&f3DLut64, 64, true, false, true);
    }

    void make_bitmap() {
        fBitmap.allocN32Pixels(80, 80);
        SkCanvas canvas(fBitmap);
        canvas.clear(0x00000000);
        SkPaint paint;
        paint.setAntiAlias(true);
        SkShader* shader = MakeLinear();
        paint.setShader(shader);
        SkRect r = { 0, 0, SkIntToScalar(80), SkIntToScalar(80) };
        canvas.drawRect(r, paint);
        shader->unref();
    }

    void make_3Dlut(SkData** data, int size, bool invR, bool invG, bool invB) {
        *data = SkData::NewUninitialized(sizeof(SkColor) * size * size * size);
        SkColor* pixels = (SkColor*)((*data)->writable_data());
        SkAutoTMalloc<uint8_t> lutMemory(size);
        SkAutoTMalloc<uint8_t> invLutMemory(size);
        uint8_t* lut = lutMemory.get();
        uint8_t* invLut = invLutMemory.get();
        const int maxIndex = size - 1;
        for (int i = 0; i < size; i++) {
            lut[i] = (i * 255) / maxIndex;
            invLut[i] = ((maxIndex - i) * 255) / maxIndex;
        }
        for (int r = 0; r < size; ++r) {
            for (int g = 0; g < size; ++g) {
                for (int b = 0; b < size; ++b) {
                    pixels[(size * ((size * b) + g)) + r] = sk_tool_utils::color_to_565(
                            SkColorSetARGB(0xFF,
                            invR ? invLut[r] : lut[r],
                            invG ? invLut[g] : lut[g],
                            invB ? invLut[b] : lut[b]));
                }
            }
        }
    }

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

    virtual void onDraw(SkCanvas* canvas) {
        if (!fInitialized) {
            this->make_bitmap();
            this->make_3Dluts();
            fInitialized = true;
        }
        canvas->clear(0x00000000);
        SkPaint paint;
        paint.setColorFilter(SkColorCubeFilter::Create(f3DLut4, 4))->unref();
        canvas->drawBitmap(fBitmap, 10, 10, &paint);

        paint.setColorFilter(SkColorCubeFilter::Create(f3DLut8, 8))->unref();
        canvas->drawBitmap(fBitmap, 110, 10, &paint);

        paint.setColorFilter(SkColorCubeFilter::Create(f3DLut16, 16))->unref();
        canvas->drawBitmap(fBitmap, 210, 10, &paint);

        paint.setColorFilter(SkColorCubeFilter::Create(f3DLut32, 32))->unref();
        canvas->drawBitmap(fBitmap, 310, 10, &paint);

        paint.setColorFilter(SkColorCubeFilter::Create(f3DLut64, 64))->unref();
        canvas->drawBitmap(fBitmap, 410, 10, &paint);
    }

private:
    typedef GM INHERITED;
    bool fInitialized;
    SkBitmap fBitmap;
    SkData* f3DLut4;
    SkData* f3DLut8;
    SkData* f3DLut16;
    SkData* f3DLut32;
    SkData* f3DLut64;
};

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

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

}
