#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 = SkFloatToScalar(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(0);
#endif
    
    SkCanvas c(*bm);    
    draw_sweep(&c, bm->width(), bm->height(), 0);
}

static void pre_dither(const SkBitmap& bm)
{
    SkAutoLockPixels alp(bm);
    
    for (unsigned y = 0; y < bm.height(); y++) {
        DITHER_4444_SCAN(y);
        
        SkPMColor* p = bm.getAddr32(0, y);
        for (unsigned 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 SkView {
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;
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Dither");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }
    
    void drawBG(SkCanvas* canvas) {
//        canvas->drawColor(0xFFDDDDDD);
        canvas->drawColor(0xFF181818);
    }
    
    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(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);
    }

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) 
    {
     //   fSweep += SK_Scalar1;
        this->inval(NULL);
        return this->INHERITED::onFindClickHandler(x, y);
    }
    
    virtual bool onClick(Click* click) 
    {
        return this->INHERITED::onClick(click);
    }
    
private:
    typedef SkView INHERITED;
};

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

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

