
/*
 * 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 "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "Sk1DPathEffect.h"
#include "SkCornerPathEffect.h"
#include "SkPathMeasure.h"
#include "SkRandom.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkDither.h"

static void draw_sweep(SkCanvas* c, int width, int height, SkScalar angle) {
    SkRect  r;
    SkPaint p;

    p.setAntiAlias(true);
//    p.setDither(true);
    p.setStrokeWidth(SkIntToScalar(width/10));
    p.setStyle(SkPaint::kStroke_Style);

    r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));

    //    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorCYAN };
    SkColor colors[] = { 0x4c737373, 0x4c737373, 0xffffd300 };
    SkShader* s = SkGradientShader::CreateSweep(r.centerX(), r.centerY(),
                                                colors, NULL, SK_ARRAY_COUNT(colors));
    p.setShader(s)->unref();

    SkAutoCanvasRestore acr(c, true);

    c->translate(r.centerX(), r.centerY());
    c->rotate(angle);
    c->translate(-r.centerX(), -r.centerY());

    SkRect bounds = r;
    r.inset(p.getStrokeWidth(), p.getStrokeWidth());
    SkRect innerBounds = r;

    if (true) {
        c->drawOval(r, p);
    } else {
        SkScalar x = r.centerX();
        SkScalar y = r.centerY();
        SkScalar radius = r.width() / 2;
        SkScalar thickness = p.getStrokeWidth();
        SkScalar sweep = 360.0f;
        SkPath path;

        path.moveTo(x + radius, y);
        // outer top
        path.lineTo(x + radius + thickness, y);
        // outer arc
        path.arcTo(bounds, 0, sweep, false);
        // inner arc
        path.arcTo(innerBounds, sweep, -sweep, false);
        path.close();
    }
}

static void make_bm(SkBitmap* bm) {
    bm->setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
    bm->allocPixels();
#if 0
    bm->eraseColor(SK_ColorBLUE);
    return;
#else
    bm->eraseColor(SK_ColorTRANSPARENT);
#endif

    SkCanvas c(*bm);
    draw_sweep(&c, bm->width(), bm->height(), 0);
}

static void pre_dither(const SkBitmap& bm) {
    SkAutoLockPixels alp(bm);

    for (int y = 0; y < bm.height(); y++) {
        DITHER_4444_SCAN(y);

        SkPMColor* p = bm.getAddr32(0, y);
        for (int x = 0; x < bm.width(); x++) {
            SkPMColor c = *p;

            unsigned a = SkGetPackedA32(c);
            unsigned r = SkGetPackedR32(c);
            unsigned g = SkGetPackedG32(c);
            unsigned b = SkGetPackedB32(c);

            unsigned d = DITHER_VALUE(x);

            a = SkDITHER_A32To4444(a, d);
            r = SkDITHER_R32To4444(r, d);
            g = SkDITHER_G32To4444(g, d);
            b = SkDITHER_B32To4444(b, d);

            a = SkA4444ToA32(a);
            r = SkR4444ToR32(r);
            g = SkG4444ToG32(g);
            b = SkB4444ToB32(b);

            *p++ = SkPackARGB32(a, r, g, b);
        }
    }
}

class DitherView : public SampleView {
public:
    SkBitmap    fBM, fBMPreDither, fBM16;
    SkScalar fAngle;

    DitherView() {
        make_bm(&fBM);
        make_bm(&fBMPreDither);
        pre_dither(fBMPreDither);
        fBM.copyTo(&fBM16, SkBitmap::kARGB_4444_Config);

        fAngle = 0;

        this->setBGColor(0xFF181818);
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Dither");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        SkPaint paint;
        SkScalar x = SkIntToScalar(10);
        SkScalar y = SkIntToScalar(10);
        const SkScalar DX = SkIntToScalar(fBM.width() + 10);

        paint.setAntiAlias(true);

        if (true) {
            canvas->drawBitmap(fBM, x, y, &paint);
            x += DX;
            paint.setDither(true);
            canvas->drawBitmap(fBM, x, y, &paint);

            x += DX;
            paint.setDither(false);
            canvas->drawBitmap(fBMPreDither, x, y, &paint);

            x += DX;
            canvas->drawBitmap(fBM16, x, y, &paint);
        }

        canvas->translate(DX, DX*2);
        draw_sweep(canvas, fBM.width(), fBM.height(), fAngle);
        canvas->translate(DX, 0);
        draw_sweep(canvas, fBM.width()>>1, fBM.height()>>1, fAngle);
        canvas->translate(DX, 0);
        draw_sweep(canvas, fBM.width()>>2, fBM.height()>>2, fAngle);

        fAngle += SK_Scalar1/2;
        this->inval(NULL);
    }

private:
    typedef SampleView INHERITED;
};

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

static SkView* MyFactory() { return new DitherView; }
static SkViewRegister reg(MyFactory);
