#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGraphics.h"
#include "SkRandom.h"
#include "SkFlipPixelRef.h"
#include "SkPageFlipper.h"

#include <pthread.h>

#define WIDTH   200
#define HEIGHT  200

static bool gDone;

static void bounce(SkScalar* x, SkScalar* dx, const int max) {
    *x += *dx;
    if (*x < 0) {
        *x = 0;
        if (*dx < 0) {
            *dx = -*dx;
        }
    } else if (*x > SkIntToScalar(max)) {
        *x = SkIntToScalar(max);
        if (*dx > 0) {
            *dx = -*dx;
        }
    }
}

static void* draw_proc(void* context) {
    const int OVALW = 32;
    const int OVALH = 32;

    const SkBitmap* bm = static_cast<const SkBitmap*>(context);
    SkFlipPixelRef* ref = static_cast<SkFlipPixelRef*>(bm->pixelRef());

    const int DSCALE = 1;
    SkScalar    dx = SkIntToScalar(7) / DSCALE;
    SkScalar    dy = SkIntToScalar(5) / DSCALE;
    SkScalar    x = 0;
    SkScalar    y = 0;

    SkPaint paint;
    
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorRED);
    
    SkRect oval;
    oval.setEmpty();

    while (!gDone) {
        ref->inval(oval, true);
        oval.set(x, y, x + SkIntToScalar(OVALW), y + SkIntToScalar(OVALH));
        ref->inval(oval, true);

        SkAutoFlipUpdate    update(ref);
        
        if (!update.dirty().isEmpty()) {
            // this must be local to the loop, since it needs to forget the pixels
            // its writing to after each iteration, since we do the swap
            SkCanvas    canvas(update.bitmap());

//            SkDebugf("----- dirty [%d %d %d %d]\n", dirty.getBounds().fLeft, dirty.getBounds().fTop, dirty.getBounds().width(), dirty.getBounds().height());
            canvas.clipRegion(update.dirty());
            
            canvas.drawColor(0, SkXfermode::kClear_Mode);            
            canvas.drawOval(oval, paint);
        }
        bounce(&x, &dx, WIDTH-OVALW);
        bounce(&y, &dy, HEIGHT-OVALH);
        
#if 1
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < 10000; j++) {
                SkFixedMul(j, 10);
            }
        }
#endif
    }
    return NULL;
}

static const SkBitmap::Config gConfigs[] = {
    SkBitmap::kARGB_8888_Config,
#if 1
    SkBitmap::kRGB_565_Config,
    SkBitmap::kARGB_4444_Config,
    SkBitmap::kA8_Config
#endif
};

class PageFlipView : public SampleView {
public:
    
    enum { N = SK_ARRAY_COUNT(gConfigs) };
    
    pthread_t   fThreads[N];
    SkBitmap    fBitmaps[N];

	PageFlipView() {
        gDone = false;
        for (int i = 0; i < N; i++) {
            int             status;
            pthread_attr_t  attr;
            
            status = pthread_attr_init(&attr);
            SkASSERT(0 == status);

            fBitmaps[i].setConfig(gConfigs[i], WIDTH, HEIGHT);
            SkFlipPixelRef* pr = new SkFlipPixelRef(gConfigs[i], WIDTH, HEIGHT);
            fBitmaps[i].setPixelRef(pr)->unref();
            fBitmaps[i].eraseColor(0);

            status = pthread_create(&fThreads[i], &attr,  draw_proc, &fBitmaps[i]);
            SkASSERT(0 == status);
        }
        this->setBGColor(0xFFDDDDDD);
    }
    
    virtual ~PageFlipView() {
        gDone = true;
        for (int i = 0; i < N; i++) {
            void* ret;
            int status = pthread_join(fThreads[i], &ret);
            SkASSERT(0 == status);
        }
    }
    
protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "PageFlip");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        SkScalar x = SkIntToScalar(10);
        SkScalar y = SkIntToScalar(10);
        for (int i = 0; i < N; i++) {
            canvas->drawBitmap(fBitmaps[i], x, y);
            x += SkIntToScalar(fBitmaps[i].width() + 20);
        }
        this->inval(NULL);
    }
    
    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
        this->inval(NULL);
        return this->INHERITED::onFindClickHandler(x, y);
    }
    
    virtual bool onClick(Click* click) {
        return this->INHERITED::onClick(click);
    }
    
private:
    typedef SampleView INHERITED;
};

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

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

