/*
 * 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 "SampleApp.h"

#include "SkData.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkTime.h"
#include "SkWindow.h"

#include "SampleCode.h"
#include "SkTypeface.h"

#if SK_SUPPORT_GPU
#include "gl/GrGLInterface.h"
#include "gl/GrGLUtil.h"
#include "GrRenderTarget.h"
#include "GrContext.h"
#include "SkGpuDevice.h"
#else
class GrContext;
#endif

#include "SkOSFile.h"
#include "SkPDFDevice.h"
#include "SkPDFDocument.h"
#include "SkStream.h"

#include "SkGPipe.h"
#include "SamplePipeControllers.h"
#include "OverView.h"
#include "TransitionView.h"

SK_DEFINE_INST_COUNT(SampleWindow::DeviceManager)

extern SampleView* CreateSamplePictFileView(const char filename[]);

class PictFileFactory : public SkViewFactory {
    SkString fFilename;
public:
    PictFileFactory(const SkString& filename) : fFilename(filename) {}
    virtual SkView* operator() () const SK_OVERRIDE {
        return CreateSamplePictFileView(fFilename.c_str());
    }
};

#define PIPE_FILEx
#ifdef  PIPE_FILE
#define FILE_PATH "/path/to/drawing.data"
#endif

#define PIPE_NETx
#ifdef  PIPE_NET
#include "SkSockets.h"
SkTCPServer gServer;
#endif

#define USE_ARROWS_FOR_ZOOM true

#if SK_ANGLE
//#define DEFAULT_TO_ANGLE 1
#else
//#define DEFAULT_TO_GPU 1
#endif

#define ANIMATING_EVENTTYPE "nextSample"
#define ANIMATING_DELAY     750

#ifdef SK_DEBUG
    #define FPS_REPEAT_MULTIPLIER   1
#else
    #define FPS_REPEAT_MULTIPLIER   10
#endif
#define FPS_REPEAT_COUNT    (10 * FPS_REPEAT_MULTIPLIER)

static SampleWindow* gSampleWindow;

static bool gShowGMBounds;

static void postEventToSink(SkEvent* evt, SkEventSink* sink) {
    evt->setTargetID(sink->getSinkID())->post();
}

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

static const char* skip_until(const char* str, const char* skip) {
    if (!str) {
        return NULL;
    }
    return strstr(str, skip);
}

static const char* skip_past(const char* str, const char* skip) {
    const char* found = skip_until(str, skip);
    if (!found) {
        return NULL;
    }
    return found + strlen(skip);
}

static const char* gPrefFileName = "sampleapp_prefs.txt";

static bool readTitleFromPrefs(SkString* title) {
    SkFILEStream stream(gPrefFileName);
    if (!stream.isValid()) {
        return false;
    }

    int len = stream.getLength();
    SkString data(len);
    stream.read(data.writable_str(), len);
    const char* s = data.c_str();

    s = skip_past(s, "curr-slide-title");
    s = skip_past(s, "=");
    s = skip_past(s, "\"");
    const char* stop = skip_until(s, "\"");
    if (stop > s) {
        title->set(s, stop - s);
        return true;
    }
    return false;
}

static void writeTitleToPrefs(const char* title) {
    SkFILEWStream stream(gPrefFileName);
    SkString data;
    data.printf("curr-slide-title = \"%s\"\n", title);
    stream.write(data.c_str(), data.size());
}

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

class SampleWindow::DefaultDeviceManager : public SampleWindow::DeviceManager {
public:

    DefaultDeviceManager() {
#if SK_SUPPORT_GPU
        fCurContext = NULL;
        fCurIntf = NULL;
        fCurRenderTarget = NULL;
        fMSAASampleCount = 0;
#endif
        fBackend = kNone_BackEndType;
    }

    virtual ~DefaultDeviceManager() {
#if SK_SUPPORT_GPU
        SkSafeUnref(fCurContext);
        SkSafeUnref(fCurIntf);
        SkSafeUnref(fCurRenderTarget);
#endif
    }

    virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) {
        SkASSERT(kNone_BackEndType == fBackend);

        fBackend = kNone_BackEndType;

#if SK_SUPPORT_GPU
        switch (win->getDeviceType()) {
            case kRaster_DeviceType:
                // fallthrough
            case kPicture_DeviceType:
                // fallthrough
            case kGPU_DeviceType:
                // fallthrough
            case kNullGPU_DeviceType:
                // all these guys use the native backend
                fBackend = kNativeGL_BackEndType;
                break;
#if SK_ANGLE
            case kANGLE_DeviceType:
                // ANGLE is really the only odd man out
                fBackend = kANGLE_BackEndType;
                break;
#endif // SK_ANGLE
            default:
                SkASSERT(false);
                break;
        }
        AttachmentInfo attachmentInfo;
        bool result = win->attach(fBackend, msaaSampleCount, &attachmentInfo);
        if (!result) {
            SkDebugf("Failed to initialize GL");
            return;
        }
        fMSAASampleCount = msaaSampleCount;

        SkASSERT(NULL == fCurIntf);
        switch (win->getDeviceType()) {
            case kRaster_DeviceType:
                // fallthrough
            case kPicture_DeviceType:
                // fallthrough
            case kGPU_DeviceType:
                // all these guys use the native interface
                fCurIntf = GrGLCreateNativeInterface();
                break;
#if SK_ANGLE
            case kANGLE_DeviceType:
                fCurIntf = GrGLCreateANGLEInterface();
                break;
#endif // SK_ANGLE
            case kNullGPU_DeviceType:
                fCurIntf = GrGLCreateNullInterface();
                break;
            default:
                SkASSERT(false);
                break;
        }

        SkASSERT(NULL == fCurContext);
        fCurContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf);

        if (NULL == fCurContext || NULL == fCurIntf) {
            // We need some context and interface to see results
            SkSafeUnref(fCurContext);
            SkSafeUnref(fCurIntf);
            SkDebugf("Failed to setup 3D");

            win->detach();
        }
#endif // SK_SUPPORT_GPU
        // call windowSizeChanged to create the render target
        this->windowSizeChanged(win);
    }

    virtual void tearDownBackend(SampleWindow *win) {
#if SK_SUPPORT_GPU
        SkSafeUnref(fCurContext);
        fCurContext = NULL;

        SkSafeUnref(fCurIntf);
        fCurIntf = NULL;

        SkSafeUnref(fCurRenderTarget);
        fCurRenderTarget = NULL;
#endif
        win->detach();
        fBackend = kNone_BackEndType;
    }

    virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
                                   SampleWindow* win) {
#if SK_SUPPORT_GPU
        if (IsGpuDeviceType(dType) && NULL != fCurContext) {
            SkAutoTUnref<SkDevice> device(new SkGpuDevice(fCurContext, fCurRenderTarget));
            return new SkCanvas(device);
        } else
#endif
        {
            return NULL;
        }
    }

    virtual void publishCanvas(SampleWindow::DeviceType dType,
                               SkCanvas* canvas,
                               SampleWindow* win) {
#if SK_SUPPORT_GPU
        if (fCurContext) {
            // in case we have queued drawing calls
            fCurContext->flush();

            if (!IsGpuDeviceType(dType)) {
                // need to send the raster bits to the (gpu) window
                fCurContext->setRenderTarget(fCurRenderTarget);
                const SkBitmap& bm = win->getBitmap();
                fCurRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
                                             kSkia8888_GrPixelConfig,
                                             bm.getPixels(),
                                             bm.rowBytes());
            }
        }
#endif

        win->present();
    }

    virtual void windowSizeChanged(SampleWindow* win) {
#if SK_SUPPORT_GPU
        if (fCurContext) {
            AttachmentInfo attachmentInfo;
            win->attach(fBackend, fMSAASampleCount, &attachmentInfo);

            GrBackendRenderTargetDesc desc;
            desc.fWidth = SkScalarRound(win->width());
            desc.fHeight = SkScalarRound(win->height());
            desc.fConfig = kSkia8888_GrPixelConfig;
            desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
            desc.fSampleCnt = attachmentInfo.fSampleCount;
            desc.fStencilBits = attachmentInfo.fStencilBits;
            GrGLint buffer;
            GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
            desc.fRenderTargetHandle = buffer;

            SkSafeUnref(fCurRenderTarget);
            fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
        }
#endif
    }

    virtual GrContext* getGrContext() {
#if SK_SUPPORT_GPU
        return fCurContext;
#else
        return NULL;
#endif
    }

    virtual GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
#if SK_SUPPORT_GPU
        return fCurRenderTarget;
#else
        return NULL;
#endif
    }

private:

#if SK_SUPPORT_GPU
    GrContext*              fCurContext;
    const GrGLInterface*    fCurIntf;
    GrRenderTarget*         fCurRenderTarget;
    int fMSAASampleCount;
#endif

    SkOSWindow::SkBackEndTypes fBackend;

    typedef SampleWindow::DeviceManager INHERITED;
};

///////////////
static const char view_inval_msg[] = "view-inval-msg";

void SampleWindow::postInvalDelay() {
    (new SkEvent(view_inval_msg, this->getSinkID()))->postDelay(1);
}

static bool isInvalEvent(const SkEvent& evt) {
    return evt.isType(view_inval_msg);
}
//////////////////

SkFuncViewFactory::SkFuncViewFactory(SkViewCreateFunc func)
    : fCreateFunc(func) {
}

SkView* SkFuncViewFactory::operator() () const {
    return (*fCreateFunc)();
}

#include "GMSampleView.h"

SkGMSampleViewFactory::SkGMSampleViewFactory(GMFactoryFunc func)
    : fFunc(func) {
}

SkView* SkGMSampleViewFactory::operator() () const {
    return new GMSampleView(fFunc(NULL));
}

SkViewRegister* SkViewRegister::gHead;
SkViewRegister::SkViewRegister(SkViewFactory* fact) : fFact(fact) {
    fFact->ref();
    fChain = gHead;
    gHead = this;
}

SkViewRegister::SkViewRegister(SkViewCreateFunc func) {
    fFact = new SkFuncViewFactory(func);
    fChain = gHead;
    gHead = this;
}

SkViewRegister::SkViewRegister(GMFactoryFunc func) {
    fFact = new SkGMSampleViewFactory(func);
    fChain = gHead;
    gHead = this;
}

class AutoUnrefArray {
public:
    AutoUnrefArray() {}
    ~AutoUnrefArray() {
        int count = fObjs.count();
        for (int i = 0; i < count; ++i) {
            fObjs[i]->unref();
        }
    }
    SkRefCnt*& push_back() { return *fObjs.append(); }

private:
    SkTDArray<SkRefCnt*> fObjs;
};

// registers GMs as Samples
// This can't be performed during static initialization because it could be
// run before GMRegistry has been fully built.
static void SkGMRegistyToSampleRegistry() {
    static bool gOnce;
    static AutoUnrefArray fRegisters;

    if (!gOnce) {
        const skiagm::GMRegistry* gmreg = skiagm::GMRegistry::Head();
        while (gmreg) {
            fRegisters.push_back() = new SkViewRegister(gmreg->factory());
            gmreg = gmreg->next();
        }
        gOnce = true;
    }
}

#if 0
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFURLAccess.h>

static void testpdf() {
    CFStringRef path = CFStringCreateWithCString(NULL, "/test.pdf",
                                                 kCFStringEncodingUTF8);
    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path,
                                              kCFURLPOSIXPathStyle,
                                              false);
    CFRelease(path);
    CGRect box = CGRectMake(0, 0, 8*72, 10*72);
    CGContextRef cg = CGPDFContextCreateWithURL(url, &box, NULL);
    CFRelease(url);

    CGContextBeginPage(cg, &box);
    CGRect r = CGRectMake(10, 10, 40 + 0.5, 50 + 0.5);
    CGContextFillEllipseInRect(cg, r);
    CGContextEndPage(cg);
    CGContextRelease(cg);

    if (false) {
        SkBitmap bm;
        bm.setConfig(SkBitmap::kA8_Config, 64, 64);
        bm.allocPixels();
        bm.eraseColor(SK_ColorTRANSPARENT);

        SkCanvas canvas(bm);

    }
}
#endif

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

enum FlipAxisEnum {
    kFlipAxis_X = (1 << 0),
    kFlipAxis_Y = (1 << 1)
};

#include "SkDrawFilter.h"

class FlagsDrawFilter : public SkDrawFilter {
public:
    FlagsDrawFilter(SkOSMenu::TriState lcd, SkOSMenu::TriState aa, SkOSMenu::TriState filter,
                    SkOSMenu::TriState hinting) :
        fLCDState(lcd), fAAState(aa), fFilterState(filter), fHintingState(hinting) {}

    virtual bool filter(SkPaint* paint, Type t) {
        if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) {
            paint->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
        }
        if (SkOSMenu::kMixedState != fAAState) {
            paint->setAntiAlias(SkOSMenu::kOnState == fAAState);
        }
        if (SkOSMenu::kMixedState != fFilterState) {
            paint->setFilterBitmap(SkOSMenu::kOnState == fFilterState);
        }
        if (SkOSMenu::kMixedState != fHintingState) {
            paint->setHinting(SkOSMenu::kOnState == fHintingState ?
                              SkPaint::kNormal_Hinting :
                              SkPaint::kSlight_Hinting);
        }
        return true;
    }

private:
    SkOSMenu::TriState  fLCDState;
    SkOSMenu::TriState  fAAState;
    SkOSMenu::TriState  fFilterState;
    SkOSMenu::TriState  fHintingState;
};

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

#define MAX_ZOOM_LEVEL  8
#define MIN_ZOOM_LEVEL  -8

static const char gCharEvtName[] = "SampleCode_Char_Event";
static const char gKeyEvtName[] = "SampleCode_Key_Event";
static const char gTitleEvtName[] = "SampleCode_Title_Event";
static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
static const char gUpdateWindowTitleEvtName[] = "SampleCode_UpdateWindowTitle";

bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
        if (outUni) {
            *outUni = evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
        if (outKey) {
            *outKey = (SkKey)evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::TitleQ(const SkEvent& evt) {
    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
}

void SampleCode::TitleR(SkEvent* evt, const char title[]) {
    SkASSERT(evt && TitleQ(*evt));
    evt->setString(gTitleEvtName, title);
}

bool SampleCode::RequestTitle(SkView* view, SkString* title) {
    SkEvent evt(gTitleEvtName);
    if (view->doQuery(&evt)) {
        title->set(evt.findString(gTitleEvtName));
        return true;
    }
    return false;
}

bool SampleCode::PrefSizeQ(const SkEvent& evt) {
    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
}

void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
    SkASSERT(evt && PrefSizeQ(*evt));
    SkScalar size[2];
    size[0] = width;
    size[1] = height;
    evt->setScalars(gPrefSizeEvtName, 2, size);
}

bool SampleCode::FastTextQ(const SkEvent& evt) {
    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
}

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

static SkMSec gAnimTime;
static SkMSec gAnimTimePrev;

SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
SkScalar SampleCode::GetAnimSecondsDelta() {
    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
}

SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
    // since gAnimTime can be up to 32 bits, we can't convert it to a float
    // or we'll lose the low bits. Hence we use doubles for the intermediate
    // calculations
    double seconds = (double)gAnimTime / 1000.0;
    double value = SkScalarToDouble(speed) * seconds;
    if (period) {
        value = ::fmod(value, SkScalarToDouble(period));
    }
    return SkDoubleToScalar(value);
}

SkScalar SampleCode::GetAnimSinScalar(SkScalar amplitude,
                                      SkScalar periodInSec,
                                      SkScalar phaseInSec) {
    if (!periodInSec) {
        return 0;
    }
    double t = (double)gAnimTime / 1000.0 + phaseInSec;
    t *= SkScalarToFloat(2 * SK_ScalarPI) / periodInSec;
    amplitude = SK_ScalarHalf * amplitude;
    return SkScalarMul(amplitude, SkDoubleToScalar(sin(t))) + amplitude;
}

GrContext* SampleCode::GetGr() {
    return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
}

// some GMs rely on having a skiagm::GetGr function defined
namespace skiagm {
    // FIXME: this should be moved into a header
    GrContext* GetGr();
    GrContext* GetGr() { return SampleCode::GetGr(); }
}

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

static SkView* curr_view(SkWindow* wind) {
    SkView::F2BIter iter(wind);
    return iter.next();
}

static bool curr_title(SkWindow* wind, SkString* title) {
    SkView* view = curr_view(wind);
    if (view) {
        SkEvent evt(gTitleEvtName);
        if (view->doQuery(&evt)) {
            title->set(evt.findString(gTitleEvtName));
            return true;
        }
    }
    return false;
}

void SampleWindow::setZoomCenter(float x, float y)
{
    fZoomCenterX = SkFloatToScalar(x);
    fZoomCenterY = SkFloatToScalar(y);
}

bool SampleWindow::zoomIn()
{
    // Arbitrarily decided
    if (fFatBitsScale == 25) return false;
    fFatBitsScale++;
    this->inval(NULL);
    return true;
}

bool SampleWindow::zoomOut()
{
    if (fFatBitsScale == 1) return false;
    fFatBitsScale--;
    this->inval(NULL);
    return true;
}

void SampleWindow::updatePointer(int x, int y)
{
    fMouseX = x;
    fMouseY = y;
    if (fShowZoomer) {
        this->inval(NULL);
    }
}

static inline SampleWindow::DeviceType cycle_devicetype(SampleWindow::DeviceType ct) {
    static const SampleWindow::DeviceType gCT[] = {
        SampleWindow::kPicture_DeviceType,
#if SK_SUPPORT_GPU
        SampleWindow::kGPU_DeviceType,
#if SK_ANGLE
        SampleWindow::kANGLE_DeviceType,
#endif // SK_ANGLE
        SampleWindow::kRaster_DeviceType, // skip the null gpu device in normal cycling
#endif // SK_SUPPORT_GPU
        SampleWindow::kRaster_DeviceType
    };
    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gCT) == SampleWindow::kDeviceTypeCnt, array_size_mismatch);
    return gCT[ct];
}

static void usage(const char * argv0) {
    SkDebugf("%s [--slide sampleName] [-i resourcePath] [--msaa sampleCount] [--pictureDir dirPath] [--picture path]\n", argv0);
    SkDebugf("    sampleName: sample at which to start.\n");
    SkDebugf("    resourcePath: directory that stores image resources.\n");
    SkDebugf("    msaa: request multisampling with the given sample count.\n");
    SkDebugf("    dirPath: path to directory skia pictures are read from\n");
    SkDebugf("    path: path to skia picture\n");
}

SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager)
    : INHERITED(hwnd)
    , fDevManager(NULL) {

    this->registerPictFileSamples(argv, argc);
    this->registerPictFileSample(argv, argc);
    SkGMRegistyToSampleRegistry();
    {
        const SkViewRegister* reg = SkViewRegister::Head();
        while (reg) {
            *fSamples.append() = reg->factory();
            reg = reg->next();
        }
    }

    const char* resourcePath = NULL;
    fCurrIndex = -1;
    fMSAASampleCount = 0;

    const char* const commandName = argv[0];
    char* const* stop = argv + argc;
    for (++argv; argv < stop; ++argv) {
        if (strcmp(*argv, "-i") == 0) {
            argv++;
            if (argv < stop && **argv) {
                resourcePath = *argv;
            }
        } else if (strcmp(*argv, "--slide") == 0) {
            argv++;
            if (argv < stop && **argv) {
                fCurrIndex = findByTitle(*argv);
                if (fCurrIndex < 0) {
                    fprintf(stderr, "Unknown sample \"%s\"\n", *argv);
                    listTitles();
                }
            }
        } else if (strcmp(*argv, "--msaa") == 0) {
            ++argv;
            if (argv < stop && **argv) {
                fMSAASampleCount = atoi(*argv);
            }
        } else if (strcmp(*argv, "--list") == 0) {
            listTitles();
        }
        else {
            usage(commandName);
        }
    }

    if (fCurrIndex < 0) {
        SkString title;
        if (readTitleFromPrefs(&title)) {
            fCurrIndex = findByTitle(title.c_str());
        }
    }

    if (fCurrIndex < 0) {
        fCurrIndex = 0;
    }

    gSampleWindow = this;

#ifdef  PIPE_FILE
    //Clear existing file or create file if it doesn't exist
    FILE* f = fopen(FILE_PATH, "wb");
    fclose(f);
#endif

    fPicture = NULL;

    fDeviceType = kRaster_DeviceType;

#if DEFAULT_TO_GPU
    fDeviceType = kGPU_DeviceType;
#endif
#if SK_ANGLE && DEFAULT_TO_ANGLE
    fDeviceType = kANGLE_DeviceType;
#endif

    fUseClip = false;
    fNClip = false;
    fAnimating = false;
    fRotate = false;
    fPerspAnim = false;
    fPerspAnimTime = 0;
    fScale = false;
    fRequestGrabImage = false;
    fPipeState = SkOSMenu::kOffState;
    fTilingState = SkOSMenu::kOffState;
    fTileCount.set(1, 1);
    fMeasureFPS = false;
    fLCDState = SkOSMenu::kMixedState;
    fAAState = SkOSMenu::kMixedState;
    fFilterState = SkOSMenu::kMixedState;
    fHintingState = SkOSMenu::kMixedState;
    fFlipAxis = 0;
    fScrollTestX = fScrollTestY = 0;

    fMouseX = fMouseY = 0;
    fFatBitsScale = 8;
    fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
    fShowZoomer = false;

    fZoomLevel = 0;
    fZoomScale = SK_Scalar1;

    fMagnify = false;

    fSaveToPdf = false;
    fPdfCanvas = NULL;

    fTransitionNext = 6;
    fTransitionPrev = 2;

    int sinkID = this->getSinkID();
    fAppMenu = new SkOSMenu;
    fAppMenu->setTitle("Global Settings");
    int itemID;

    itemID =fAppMenu->appendList("Device Type", "Device Type", sinkID, 0,
                                "Raster", "Picture", "OpenGL",
#if SK_ANGLE
                                "ANGLE",
#endif
                                NULL);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'd');
    itemID = fAppMenu->appendTriState("AA", "AA", sinkID, fAAState);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'b');
    itemID = fAppMenu->appendTriState("LCD", "LCD", sinkID, fLCDState);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'l');
    itemID = fAppMenu->appendTriState("Filter", "Filter", sinkID, fFilterState);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'n');
    itemID = fAppMenu->appendTriState("Hinting", "Hinting", sinkID, fHintingState);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'h');

    fUsePipeMenuItemID = fAppMenu->appendTriState("Pipe", "Pipe" , sinkID,
                                                  fPipeState);
    fAppMenu->assignKeyEquivalentToItem(fUsePipeMenuItemID, 'P');

    itemID = fAppMenu->appendTriState("Tiling", "Tiling", sinkID, fTilingState);
    fAppMenu->assignKeyEquivalentToItem(itemID, 't');

    itemID = fAppMenu->appendSwitch("Slide Show", "Slide Show" , sinkID, false);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'a');
    itemID = fAppMenu->appendSwitch("Clip", "Clip" , sinkID, fUseClip);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'c');
    itemID = fAppMenu->appendSwitch("Flip X", "Flip X" , sinkID, false);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'x');
    itemID = fAppMenu->appendSwitch("Flip Y", "Flip Y" , sinkID, false);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'y');
    itemID = fAppMenu->appendSwitch("Zoomer", "Zoomer" , sinkID, fShowZoomer);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'z');
    itemID = fAppMenu->appendSwitch("Magnify", "Magnify" , sinkID, fMagnify);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'm');
    itemID =fAppMenu->appendList("Transition-Next", "Transition-Next", sinkID,
                                fTransitionNext, "Up", "Up and Right", "Right",
                                "Down and Right", "Down", "Down and Left",
                                "Left", "Up and Left", NULL);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'j');
    itemID =fAppMenu->appendList("Transition-Prev", "Transition-Prev", sinkID,
                                fTransitionPrev, "Up", "Up and Right", "Right",
                                "Down and Right", "Down", "Down and Left",
                                "Left", "Up and Left", NULL);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'k');
    itemID = fAppMenu->appendAction("Save to PDF", sinkID);
    fAppMenu->assignKeyEquivalentToItem(itemID, 'e');

    this->addMenu(fAppMenu);
    fSlideMenu = new SkOSMenu;
    this->addMenu(fSlideMenu);

//    this->setConfig(SkBitmap::kRGB_565_Config);
    this->setConfig(SkBitmap::kARGB_8888_Config);
    this->setVisibleP(true);
    this->setClipToBounds(false);

    skiagm::GM::SetResourcePath(resourcePath);

    this->loadView((*fSamples[fCurrIndex])());

    fPDFData = NULL;

    if (NULL == devManager) {
        fDevManager = new DefaultDeviceManager();
    } else {
        devManager->ref();
        fDevManager = devManager;
    }
    fDevManager->setUpBackend(this, fMSAASampleCount);

    // If another constructor set our dimensions, ensure that our
    // onSizeChange gets called.
    if (this->height() && this->width()) {
        this->onSizeChange();
    }

    // can't call this synchronously, since it may require a subclass to
    // to implement, or the caller may need us to have returned from the
    // constructor first. Hence we post an event to ourselves.
//    this->updateTitle();
    postEventToSink(new SkEvent(gUpdateWindowTitleEvtName), this);
}

SampleWindow::~SampleWindow() {
    delete fPicture;
    delete fPdfCanvas;
    fTypeface->unref();

    SkSafeUnref(fDevManager);
}

static void make_filepath(SkString* path, const char* dir, const SkString& name) {
    size_t len = strlen(dir);
    path->set(dir);
    if (len > 0 && dir[len - 1] != '/') {
        path->append("/");
    }
    path->append(name);
}

void SampleWindow::registerPictFileSample(char** argv, int argc) {
    const char* pict = NULL;

    for (int i = 0; i < argc; ++i) {
        if (!strcmp(argv[i], "--picture")) {
            i += 1;
            if (i < argc) {
                pict = argv[i];
                break;
            }
        }
    }
    if (pict) {
        SkString path(pict);
        *fSamples.append() = new PictFileFactory(path);
    }
}

void SampleWindow::registerPictFileSamples(char** argv, int argc) {
    const char* pictDir = NULL;

    for (int i = 0; i < argc; ++i) {
        if (!strcmp(argv[i], "--pictureDir")) {
            i += 1;
            if (i < argc) {
                pictDir = argv[i];
                break;
            }
        }
    }
    if (pictDir) {
        SkOSFile::Iter iter(pictDir, "skp");
        SkString filename;
        while (iter.next(&filename)) {
            SkString path;
            make_filepath(&path, pictDir, filename);
            *fSamples.append() = new PictFileFactory(path);
        }
    }
}

int SampleWindow::findByTitle(const char title[]) {
    int i, count = fSamples.count();
    for (i = 0; i < count; i++) {
        if (getSampleTitle(i).equals(title)) {
            return i;
        }
    }
    return -1;
}

void SampleWindow::listTitles() {
    int count = fSamples.count();
    SkDebugf("All Slides:\n");
    for (int i = 0; i < count; i++) {
        SkDebugf("    %s\n", getSampleTitle(i).c_str());
    }
}

static SkBitmap capture_bitmap(SkCanvas* canvas) {
    SkBitmap bm;
    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
    src.copyTo(&bm, src.config());
    return bm;
}

static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
                        SkBitmap* diff) {
    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);

    SkAutoLockPixels alp0(src);
    SkAutoLockPixels alp1(orig);
    for (int y = 0; y < src.height(); y++) {
        const void* srcP = src.getAddr(0, y);
        const void* origP = orig.getAddr(0, y);
        size_t bytes = src.width() * src.bytesPerPixel();
        if (memcmp(srcP, origP, bytes)) {
            SkDebugf("---------- difference on line %d\n", y);
            return true;
        }
    }
    return false;
}

static void drawText(SkCanvas* canvas, SkString string, SkScalar left, SkScalar top, SkPaint& paint)
{
    SkColor desiredColor = paint.getColor();
    paint.setColor(SK_ColorWHITE);
    const char* c_str = string.c_str();
    size_t size = string.size();
    SkRect bounds;
    paint.measureText(c_str, size, &bounds);
    bounds.offset(left, top);
    SkScalar inset = SkIntToScalar(-2);
    bounds.inset(inset, inset);
    canvas->drawRect(bounds, paint);
    if (desiredColor != SK_ColorBLACK) {
        paint.setColor(SK_ColorBLACK);
        canvas->drawText(c_str, size, left + SK_Scalar1, top + SK_Scalar1, paint);
    }
    paint.setColor(desiredColor);
    canvas->drawText(c_str, size, left, top, paint);
}

#define XCLIP_N  8
#define YCLIP_N  8

void SampleWindow::draw(SkCanvas* canvas) {
    // update the animation time
    if (!gAnimTimePrev && !gAnimTime) {
        // first time make delta be 0
        gAnimTime = SkTime::GetMSecs();
        gAnimTimePrev = gAnimTime;
    } else {
        gAnimTimePrev = gAnimTime;
        gAnimTime = SkTime::GetMSecs();
    }

    if (fGesture.isActive()) {
        this->updateMatrix();
    }

    if (fMeasureFPS) {
        fMeasureFPS_Time = 0;
    }

    if (fNClip) {
        this->INHERITED::draw(canvas);
        SkBitmap orig = capture_bitmap(canvas);

        const SkScalar w = this->width();
        const SkScalar h = this->height();
        const SkScalar cw = w / XCLIP_N;
        const SkScalar ch = h / YCLIP_N;
        for (int y = 0; y < YCLIP_N; y++) {
            SkRect r;
            r.fTop = y * ch;
            r.fBottom = (y + 1) * ch;
            if (y == YCLIP_N - 1) {
                r.fBottom = h;
            }
            for (int x = 0; x < XCLIP_N; x++) {
                SkAutoCanvasRestore acr(canvas, true);
                r.fLeft = x * cw;
                r.fRight = (x + 1) * cw;
                if (x == XCLIP_N - 1) {
                    r.fRight = w;
                }
                canvas->clipRect(r);
                this->INHERITED::draw(canvas);
            }
        }

        SkBitmap diff;
        if (bitmap_diff(canvas, orig, &diff)) {
        }
    } else {
        const SkScalar cw = SkScalarDiv(this->width(), SkIntToScalar(fTileCount.width()));
        const SkScalar ch = SkScalarDiv(this->height(), SkIntToScalar(fTileCount.height()));

        for (int y = 0; y < fTileCount.height(); ++y) {
            for (int x = 0; x < fTileCount.width(); ++x) {
                SkAutoCanvasRestore acr(canvas, true);
                canvas->clipRect(SkRect::MakeXYWH(x * cw, y * ch, cw, ch));
                this->INHERITED::draw(canvas);
            }
        }

        if (!fTileCount.equals(1, 1)) {
            SkPaint paint;
            paint.setColor(0x60FF00FF);
            paint.setStyle(SkPaint::kStroke_Style);
            for (int y = 0; y < fTileCount.height(); ++y) {
                for (int x = 0; x < fTileCount.width(); ++x) {
                    canvas->drawRect(SkRect::MakeXYWH(x * cw, y * ch, cw, ch), paint);
                }
            }
        }
    }
    if (fShowZoomer && !fSaveToPdf) {
        showZoomer(canvas);
    }
    if (fMagnify && !fSaveToPdf) {
        magnify(canvas);
    }

    if (fMeasureFPS && fMeasureFPS_Time) {
        this->updateTitle();
        this->postInvalDelay();
    }

    // do this last
    fDevManager->publishCanvas(fDeviceType, canvas, this);
}

static float clipW = 200;
static float clipH = 200;
void SampleWindow::magnify(SkCanvas* canvas) {
    SkRect r;
    int count = canvas->save();

    SkMatrix m = canvas->getTotalMatrix();
    if (!m.invert(&m)) {
        return;
    }
    SkPoint offset, center;
    SkScalar mouseX = fMouseX * SK_Scalar1;
    SkScalar mouseY = fMouseY * SK_Scalar1;
    m.mapXY(mouseX - clipW/2, mouseY - clipH/2, &offset);
    m.mapXY(mouseX, mouseY, &center);

    r.set(0, 0, clipW * m.getScaleX(), clipH * m.getScaleX());
    r.offset(offset.fX, offset.fY);

    SkPaint paint;
    paint.setColor(0xFF66AAEE);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(10.f * m.getScaleX());
    //lense offset
    //canvas->translate(0, -250);
    canvas->drawRect(r, paint);
    canvas->clipRect(r);

    m = canvas->getTotalMatrix();
    m.setTranslate(-center.fX, -center.fY);
    m.postScale(0.5f * fFatBitsScale, 0.5f * fFatBitsScale);
    m.postTranslate(center.fX, center.fY);
    canvas->concat(m);

    this->INHERITED::draw(canvas);

    canvas->restoreToCount(count);
}

void SampleWindow::showZoomer(SkCanvas* canvas) {
        int count = canvas->save();
        canvas->resetMatrix();
        // Ensure the mouse position is on screen.
        int width = SkScalarRound(this->width());
        int height = SkScalarRound(this->height());
        if (fMouseX >= width) fMouseX = width - 1;
        else if (fMouseX < 0) fMouseX = 0;
        if (fMouseY >= height) fMouseY = height - 1;
        else if (fMouseY < 0) fMouseY = 0;

        SkBitmap bitmap = capture_bitmap(canvas);
        bitmap.lockPixels();

        // Find the size of the zoomed in view, forced to be odd, so the examined pixel is in the middle.
        int zoomedWidth = (width >> 1) | 1;
        int zoomedHeight = (height >> 1) | 1;
        SkIRect src;
        src.set(0, 0, zoomedWidth / fFatBitsScale, zoomedHeight / fFatBitsScale);
        src.offset(fMouseX - (src.width()>>1), fMouseY - (src.height()>>1));
        SkRect dest;
        dest.set(0, 0, SkIntToScalar(zoomedWidth), SkIntToScalar(zoomedHeight));
        dest.offset(SkIntToScalar(width - zoomedWidth), SkIntToScalar(height - zoomedHeight));
        SkPaint paint;
        // Clear the background behind our zoomed in view
        paint.setColor(SK_ColorWHITE);
        canvas->drawRect(dest, paint);
        canvas->drawBitmapRect(bitmap, &src, dest);
        paint.setColor(SK_ColorBLACK);
        paint.setStyle(SkPaint::kStroke_Style);
        // Draw a border around the pixel in the middle
        SkRect originalPixel;
        originalPixel.set(SkIntToScalar(fMouseX), SkIntToScalar(fMouseY), SkIntToScalar(fMouseX + 1), SkIntToScalar(fMouseY + 1));
        SkMatrix matrix;
        SkRect scalarSrc;
        scalarSrc.set(src);
        SkColor color = bitmap.getColor(fMouseX, fMouseY);
        if (matrix.setRectToRect(scalarSrc, dest, SkMatrix::kFill_ScaleToFit)) {
            SkRect pixel;
            matrix.mapRect(&pixel, originalPixel);
            // TODO Perhaps measure the values and make the outline white if it's "dark"
            if (color == SK_ColorBLACK) {
                paint.setColor(SK_ColorWHITE);
            }
            canvas->drawRect(pixel, paint);
        }
        paint.setColor(SK_ColorBLACK);
        // Draw a border around the destination rectangle
        canvas->drawRect(dest, paint);
        paint.setStyle(SkPaint::kStrokeAndFill_Style);
        // Identify the pixel and its color on screen
        paint.setTypeface(fTypeface);
        paint.setAntiAlias(true);
        SkScalar lineHeight = paint.getFontMetrics(NULL);
        SkString string;
        string.appendf("(%i, %i)", fMouseX, fMouseY);
        SkScalar left = dest.fLeft + SkIntToScalar(3);
        SkScalar i = SK_Scalar1;
        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
        // Alpha
        i += SK_Scalar1;
        string.reset();
        string.appendf("A: %X", SkColorGetA(color));
        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
        // Red
        i += SK_Scalar1;
        string.reset();
        string.appendf("R: %X", SkColorGetR(color));
        paint.setColor(SK_ColorRED);
        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
        // Green
        i += SK_Scalar1;
        string.reset();
        string.appendf("G: %X", SkColorGetG(color));
        paint.setColor(SK_ColorGREEN);
        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
        // Blue
        i += SK_Scalar1;
        string.reset();
        string.appendf("B: %X", SkColorGetB(color));
        paint.setColor(SK_ColorBLUE);
        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
        canvas->restoreToCount(count);
}

void SampleWindow::onDraw(SkCanvas* canvas) {
}

#include "SkColorPriv.h"

#if 0 // UNUSED
static void reverseRedAndBlue(const SkBitmap& bm) {
    SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
    uint8_t* p = (uint8_t*)bm.getPixels();
    uint8_t* stop = p + bm.getSize();
    while (p < stop) {
        // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
        unsigned scale = SkAlpha255To256(p[3]);
        unsigned r = p[2];
        unsigned b = p[0];
        p[0] = SkAlphaMul(r, scale);
        p[1] = SkAlphaMul(p[1], scale);
        p[2] = SkAlphaMul(b, scale);
        p += 4;
    }
}
#endif

void SampleWindow::saveToPdf()
{
    fSaveToPdf = true;
    this->inval(NULL);
}

SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
    if (fSaveToPdf) {
        const SkBitmap& bmp = canvas->getDevice()->accessBitmap(false);
        SkISize size = SkISize::Make(bmp.width(), bmp.height());
        SkPDFDevice* pdfDevice = new SkPDFDevice(size, size,
                canvas->getTotalMatrix());
        fPdfCanvas = new SkCanvas(pdfDevice);
        pdfDevice->unref();
        canvas = fPdfCanvas;
    } else if (kPicture_DeviceType == fDeviceType) {
        fPicture = new SkPicture;
        canvas = fPicture->beginRecording(9999, 9999);
    } else {
#if SK_SUPPORT_GPU
        if (kNullGPU_DeviceType != fDeviceType)
#endif
        {
            canvas = this->INHERITED::beforeChildren(canvas);
        }
    }

    if (fUseClip) {
        canvas->drawColor(0xFFFF88FF);
        canvas->clipPath(fClipPath, SkRegion::kIntersect_Op, true);
    }

    return canvas;
}

static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
                      const SkRegion& rgn) {
    SkCanvas    canvas(bm);
    SkRegion    inval(rgn);

    inval.translate(r.fLeft, r.fTop);
    canvas.clipRegion(inval);
    canvas.drawColor(0xFFFF8080);
}
#include "SkData.h"
void SampleWindow::afterChildren(SkCanvas* orig) {
    if (fSaveToPdf) {
        fSaveToPdf = false;
        if (fShowZoomer) {
            showZoomer(fPdfCanvas);
        }
        SkString name;
        name.printf("%s.pdf", this->getTitle());
        SkPDFDocument doc;
        SkPDFDevice* device = static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
        doc.appendPage(device);
#ifdef SK_BUILD_FOR_ANDROID
        name.prepend("/sdcard/");
#endif

#ifdef SK_BUILD_FOR_IOS
        SkDynamicMemoryWStream mstream;
        doc.emitPDF(&mstream);
        fPDFData = mstream.copyToData();
#endif
        SkFILEWStream stream(name.c_str());
        if (stream.isValid()) {
            doc.emitPDF(&stream);
            const char* desc = "File saved from Skia SampleApp";
            this->onPDFSaved(this->getTitle(), desc, name.c_str());
        }

        delete fPdfCanvas;
        fPdfCanvas = NULL;

        // We took over the draw calls in order to create the PDF, so we need
        // to redraw.
        this->inval(NULL);
        return;
    }

    if (fRequestGrabImage) {
        fRequestGrabImage = false;

        SkDevice* device = orig->getDevice();
        SkBitmap bmp;
        if (device->accessBitmap(false).copyTo(&bmp, SkBitmap::kARGB_8888_Config)) {
            static int gSampleGrabCounter;
            SkString name;
            name.printf("sample_grab_%d.png", gSampleGrabCounter++);
            SkImageEncoder::EncodeFile(name.c_str(), bmp,
                                       SkImageEncoder::kPNG_Type, 100);
        }
    }

    if (kPicture_DeviceType == fDeviceType) {
        if (true) {
            SkPicture* pict = new SkPicture(*fPicture);
            fPicture->unref();
            this->installDrawFilter(orig);
            orig->drawPicture(*pict);
            pict->unref();
        } else if (true) {
            SkDynamicMemoryWStream ostream;
            fPicture->serialize(&ostream);
            fPicture->unref();

            SkAutoDataUnref data(ostream.copyToData());
            SkMemoryStream istream(data->data(), data->size());
            SkPicture pict(&istream);
            orig->drawPicture(pict);
        } else {
            fPicture->draw(orig);
            fPicture->unref();
        }
        fPicture = NULL;
    }

    // Do this after presentGL and other finishing, rather than in afterChild
    if (fMeasureFPS && fMeasureFPS_StartTime) {
        fMeasureFPS_Time += SkTime::GetMSecs() - fMeasureFPS_StartTime;
    }

    //    if ((fScrollTestX | fScrollTestY) != 0)
    if (false) {
        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
        int dx = fScrollTestX * 7;
        int dy = fScrollTestY * 7;
        SkIRect r;
        SkRegion inval;

        r.set(50, 50, 50+100, 50+100);
        bm.scrollRect(&r, dx, dy, &inval);
        paint_rgn(bm, r, inval);
    }
}

void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
    if (fScale) {
        SkScalar scale = SK_Scalar1 * 7 / 10;
        SkScalar cx = this->width() / 2;
        SkScalar cy = this->height() / 2;
        canvas->translate(cx, cy);
        canvas->scale(scale, scale);
        canvas->translate(-cx, -cy);
    }
    if (fRotate) {
        SkScalar cx = this->width() / 2;
        SkScalar cy = this->height() / 2;
        canvas->translate(cx, cy);
        canvas->rotate(SkIntToScalar(30));
        canvas->translate(-cx, -cy);
    }
    if (fPerspAnim) {
        fPerspAnimTime += SampleCode::GetAnimSecondsDelta();

        static const SkScalar gAnimPeriod = 10 * SK_Scalar1;
        static const SkScalar gAnimMag = SK_Scalar1 / 1000;
        SkScalar t = SkScalarMod(fPerspAnimTime, gAnimPeriod);
        if (SkScalarFloorToInt(SkScalarDiv(fPerspAnimTime, gAnimPeriod)) & 0x1) {
            t = gAnimPeriod - t;
        }
        t = 2 * t - gAnimPeriod;
        t = SkScalarMul(SkScalarDiv(t, gAnimPeriod), gAnimMag);
        SkMatrix m;
        m.reset();
        m.setPerspY(t);
        canvas->concat(m);
    }

    this->installDrawFilter(canvas);

    if (fMeasureFPS) {
        if (SampleView::SetRepeatDraw(child, FPS_REPEAT_COUNT)) {
            fMeasureFPS_StartTime = SkTime::GetMSecs();
        }
    } else {
        (void)SampleView::SetRepeatDraw(child, 1);
    }
    if (fPerspAnim) {
        this->inval(NULL);
    }
}

void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
    canvas->setDrawFilter(NULL);
}

static SkBitmap::Config gConfigCycle[] = {
    SkBitmap::kNo_Config,           // none -> none
    SkBitmap::kNo_Config,           // a1 -> none
    SkBitmap::kNo_Config,           // a8 -> none
    SkBitmap::kNo_Config,           // index8 -> none
    SkBitmap::kARGB_4444_Config,    // 565 -> 4444
    SkBitmap::kARGB_8888_Config,    // 4444 -> 8888
    SkBitmap::kRGB_565_Config       // 8888 -> 565
};

static SkBitmap::Config cycle_configs(SkBitmap::Config c) {
    return gConfigCycle[c];
}

void SampleWindow::changeZoomLevel(float delta) {
    fZoomLevel += SkFloatToScalar(delta);
    if (fZoomLevel > 0) {
        fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL);
        fZoomScale = fZoomLevel + SK_Scalar1;
    } else if (fZoomLevel < 0) {
        fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL);
        fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel);
    } else {
        fZoomScale = SK_Scalar1;
    }
    this->updateMatrix();
}

void SampleWindow::updateMatrix(){
    SkMatrix m;
    m.reset();
    if (fZoomLevel) {
        SkPoint center;
        //m = this->getLocalMatrix();//.invert(&m);
        m.mapXY(fZoomCenterX, fZoomCenterY, &center);
        SkScalar cx = center.fX;
        SkScalar cy = center.fY;

        m.setTranslate(-cx, -cy);
        m.postScale(fZoomScale, fZoomScale);
        m.postTranslate(cx, cy);
    }

    if (fFlipAxis) {
        m.preTranslate(fZoomCenterX, fZoomCenterY);
        if (fFlipAxis & kFlipAxis_X) {
            m.preScale(-SK_Scalar1, SK_Scalar1);
        }
        if (fFlipAxis & kFlipAxis_Y) {
            m.preScale(SK_Scalar1, -SK_Scalar1);
        }
        m.preTranslate(-fZoomCenterX, -fZoomCenterY);
        //canvas->concat(m);
    }
    // Apply any gesture matrix
    m.preConcat(fGesture.localM());
    m.preConcat(fGesture.globalM());

    this->setLocalMatrix(m);

    this->updateTitle();
    this->inval(NULL);
}
bool SampleWindow::previousSample() {
    fCurrIndex = (fCurrIndex - 1 + fSamples.count()) % fSamples.count();
    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
                                     fTransitionPrev));
    return true;
}

bool SampleWindow::nextSample() {
    fCurrIndex = (fCurrIndex + 1) % fSamples.count();
    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
                                     fTransitionNext));
    return true;
}

bool SampleWindow::goToSample(int i) {
    fCurrIndex = (i) % fSamples.count();
    this->loadView(create_transition(curr_view(this),(*fSamples[fCurrIndex])(), 6));
    return true;
}

SkString SampleWindow::getSampleTitle(int i) {
    SkView* view = (*fSamples[i])();
    SkString title;
    SampleCode::RequestTitle(view, &title);
    view->unref();
    return title;
}

int SampleWindow::sampleCount() {
    return fSamples.count();
}

void SampleWindow::showOverview() {
    this->loadView(create_transition(curr_view(this),
                                     create_overview(fSamples.count(), fSamples.begin()),
                                     4));
}

void SampleWindow::installDrawFilter(SkCanvas* canvas) {
    canvas->setDrawFilter(new FlagsDrawFilter(fLCDState, fAAState,
                                              fFilterState, fHintingState))->unref();
}

void SampleWindow::postAnimatingEvent() {
    if (fAnimating) {
        (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATING_DELAY);
    }
}

bool SampleWindow::onEvent(const SkEvent& evt) {
    if (evt.isType(gUpdateWindowTitleEvtName)) {
        this->updateTitle();
        return true;
    }
    if (evt.isType(ANIMATING_EVENTTYPE)) {
        if (fAnimating) {
            this->nextSample();
            this->postAnimatingEvent();
        }
        return true;
    }
    if (evt.isType("replace-transition-view")) {
        this->loadView((SkView*)SkEventSink::FindSink(evt.getFast32()));
        return true;
    }
    if (evt.isType("set-curr-index")) {
        this->goToSample(evt.getFast32());
        return true;
    }
    if (isInvalEvent(evt)) {
        this->inval(NULL);
        return true;
    }
    int selected = -1;
    if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) {
        this->setDeviceType((DeviceType)selected);
        return true;
    }
    if (SkOSMenu::FindTriState(evt, "Pipe", &fPipeState)) {
#ifdef PIPE_NET
        if (!fPipeState != SkOSMenu::kOnState)
            gServer.disconnectAll();
#endif
        (void)SampleView::SetUsePipe(curr_view(this), fPipeState);
        this->updateTitle();
        this->inval(NULL);
        return true;
    }
    if (SkOSMenu::FindTriState(evt, "Tiling", &fTilingState)) {
        int nx = 1, ny = 1;
        switch (fTilingState) {
            case SkOSMenu::kOffState:   nx = 1; ny = 1; break;
            case SkOSMenu::kMixedState: nx = 1; ny = 16; break;
            case SkOSMenu::kOnState:    nx = 4; ny = 4; break;
        }
        fTileCount.set(nx, ny);
        this->inval(NULL);
        return true;
    }
    if (SkOSMenu::FindSwitchState(evt, "Slide Show", NULL)) {
        this->toggleSlideshow();
        return true;
    }
    if (SkOSMenu::FindTriState(evt, "AA", &fAAState) ||
        SkOSMenu::FindTriState(evt, "LCD", &fLCDState) ||
        SkOSMenu::FindTriState(evt, "Filter", &fFilterState) ||
        SkOSMenu::FindTriState(evt, "Hinting", &fHintingState) ||
        SkOSMenu::FindSwitchState(evt, "Clip", &fUseClip) ||
        SkOSMenu::FindSwitchState(evt, "Zoomer", &fShowZoomer) ||
        SkOSMenu::FindSwitchState(evt, "Magnify", &fMagnify) ||
        SkOSMenu::FindListIndex(evt, "Transition-Next", &fTransitionNext) ||
        SkOSMenu::FindListIndex(evt, "Transition-Prev", &fTransitionPrev)) {
        this->inval(NULL);
        this->updateTitle();
        return true;
    }
    if (SkOSMenu::FindSwitchState(evt, "Flip X", NULL)) {
        fFlipAxis ^= kFlipAxis_X;
        this->updateMatrix();
        return true;
    }
    if (SkOSMenu::FindSwitchState(evt, "Flip Y", NULL)) {
        fFlipAxis ^= kFlipAxis_Y;
        this->updateMatrix();
        return true;
    }
    if (SkOSMenu::FindAction(evt,"Save to PDF")) {
        this->saveToPdf();
        return true;
    }
    return this->INHERITED::onEvent(evt);
}

bool SampleWindow::onQuery(SkEvent* query) {
    if (query->isType("get-slide-count")) {
        query->setFast32(fSamples.count());
        return true;
    }
    if (query->isType("get-slide-title")) {
        SkView* view = (*fSamples[query->getFast32()])();
        SkEvent evt(gTitleEvtName);
        if (view->doQuery(&evt)) {
            query->setString("title", evt.findString(gTitleEvtName));
        }
        SkSafeUnref(view);
        return true;
    }
    if (query->isType("use-fast-text")) {
        SkEvent evt(gFastTextEvtName);
        return curr_view(this)->doQuery(&evt);
    }
    if (query->isType("ignore-window-bitmap")) {
        query->setFast32(this->getGrContext() != NULL);
        return true;
    }
    return this->INHERITED::onQuery(query);
}

#if 0 // UNUSED
static void cleanup_for_filename(SkString* name) {
    char* str = name->writable_str();
    for (size_t i = 0; i < name->size(); i++) {
        switch (str[i]) {
            case ':': str[i] = '-'; break;
            case '/': str[i] = '-'; break;
            case ' ': str[i] = '_'; break;
            default: break;
        }
    }
}
#endif

//extern bool gIgnoreFastBlurRect;

bool SampleWindow::onHandleChar(SkUnichar uni) {
    {
        SkView* view = curr_view(this);
        if (view) {
            SkEvent evt(gCharEvtName);
            evt.setFast32(uni);
            if (view->doQuery(&evt)) {
                return true;
            }
        }
    }

    int dx = 0xFF;
    int dy = 0xFF;

    switch (uni) {
        case '5': dx =  0; dy =  0; break;
        case '8': dx =  0; dy = -1; break;
        case '6': dx =  1; dy =  0; break;
        case '2': dx =  0; dy =  1; break;
        case '4': dx = -1; dy =  0; break;
        case '7': dx = -1; dy = -1; break;
        case '9': dx =  1; dy = -1; break;
        case '3': dx =  1; dy =  1; break;
        case '1': dx = -1; dy =  1; break;

        default:
            break;
    }

    if (0xFF != dx && 0xFF != dy) {
        if ((dx | dy) == 0) {
            fScrollTestX = fScrollTestY = 0;
        } else {
            fScrollTestX += dx;
            fScrollTestY += dy;
        }
        this->inval(NULL);
        return true;
    }

    switch (uni) {
        case 'b':
            {
            postEventToSink(SkNEW_ARGS(SkEvent, ("PictFileView::toggleBBox")), curr_view(this));
            this->updateTitle();
            this->inval(NULL);
            break;
            }
        case 'B':
//            gIgnoreFastBlurRect = !gIgnoreFastBlurRect;
            this->inval(NULL);
            break;

        case 'f':
            // only
            toggleFPS();
            break;
        case 'g':
            fRequestGrabImage = true;
            this->inval(NULL);
            break;
        case 'G':
            gShowGMBounds = !gShowGMBounds;
            postEventToSink(GMSampleView::NewShowSizeEvt(gShowGMBounds),
                            curr_view(this));
            this->inval(NULL);
            break;
        case 'i':
            this->zoomIn();
            break;
        case 'o':
            this->zoomOut();
            break;
        case 'r':
            fRotate = !fRotate;
            this->inval(NULL);
            this->updateTitle();
            return true;
        case 'k':
            fPerspAnim = !fPerspAnim;
            this->inval(NULL);
            this->updateTitle();
            return true;
#if SK_SUPPORT_GPU
        case '\\':
            this->setDeviceType(kNullGPU_DeviceType);
            this->inval(NULL);
            this->updateTitle();
            return true;
        case 'p':
            {
                GrContext* grContext = this->getGrContext();
                if (grContext) {
                    size_t cacheBytes = grContext->getGpuTextureCacheBytes();
                    grContext->freeGpuResources();
                    SkDebugf("Purged %d bytes from the GPU resource cache.\n",
                             cacheBytes);
                }
            }
            return true;
#endif
        case 's':
            fScale = !fScale;
            this->inval(NULL);
            this->updateTitle();
            return true;
        default:
            break;
    }

    if (fAppMenu->handleKeyEquivalent(uni)|| fSlideMenu->handleKeyEquivalent(uni)) {
        this->onUpdateMenu(fAppMenu);
        this->onUpdateMenu(fSlideMenu);
        return true;
    }
    return this->INHERITED::onHandleChar(uni);
}

void SampleWindow::setDeviceType(DeviceType type) {
    if (type == fDeviceType)
        return;

    fDevManager->tearDownBackend(this);

    fDeviceType = type;

    fDevManager->setUpBackend(this, fMSAASampleCount);

    this->updateTitle();
    this->inval(NULL);
}

void SampleWindow::toggleSlideshow() {
    fAnimating = !fAnimating;
    this->postAnimatingEvent();
    this->updateTitle();
}

void SampleWindow::toggleRendering() {
    this->setDeviceType(cycle_devicetype(fDeviceType));
    this->updateTitle();
    this->inval(NULL);
}

void SampleWindow::toggleFPS() {
    fMeasureFPS = !fMeasureFPS;
    this->updateTitle();
    this->inval(NULL);
}

#include "SkDumpCanvas.h"

bool SampleWindow::onHandleKey(SkKey key) {
    {
        SkView* view = curr_view(this);
        if (view) {
            SkEvent evt(gKeyEvtName);
            evt.setFast32(key);
            if (view->doQuery(&evt)) {
                return true;
            }
        }
    }
    switch (key) {
        case kRight_SkKey:
            if (this->nextSample()) {
                return true;
            }
            break;
        case kLeft_SkKey:
            if (this->previousSample()) {
                return true;
            }
            return true;
        case kUp_SkKey:
            if (USE_ARROWS_FOR_ZOOM) {
                this->changeZoomLevel(1.f);
            } else {
                fNClip = !fNClip;
                this->inval(NULL);
                this->updateTitle();
            }
            return true;
        case kDown_SkKey:
            if (USE_ARROWS_FOR_ZOOM) {
                this->changeZoomLevel(-1.f);
            } else {
                this->setConfig(cycle_configs(this->getBitmap().config()));
                this->updateTitle();
            }
            return true;
        case kOK_SkKey: {
            SkString title;
            if (curr_title(this, &title)) {
                writeTitleToPrefs(title.c_str());
            }
            return true;
        }
        case kBack_SkKey:
            this->showOverview();
            return true;
        default:
            break;
    }
    return this->INHERITED::onHandleKey(key);
}

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

static const char gGestureClickType[] = "GestureClickType";

bool SampleWindow::onDispatchClick(int x, int y, Click::State state,
        void* owner, unsigned modi) {
    if (Click::kMoved_State == state) {
        updatePointer(x, y);
    }
    int w = SkScalarRound(this->width());
    int h = SkScalarRound(this->height());

    // check for the resize-box
    if (w - x < 16 && h - y < 16) {
        return false;   // let the OS handle the click
    }
    else if (fMagnify) {
        //it's only necessary to update the drawing if there's a click
        this->inval(NULL);
        return false; //prevent dragging while magnify is enabled
    } else {
        // capture control+option, and trigger debugger
        if ((modi & kControl_SkModifierKey) && (modi & kOption_SkModifierKey)) {
            if (Click::kDown_State == state) {
                SkEvent evt("debug-hit-test");
                evt.setS32("debug-hit-test-x", x);
                evt.setS32("debug-hit-test-y", y);
                curr_view(this)->doEvent(evt);
            }
            return true;
        } else {
            return this->INHERITED::onDispatchClick(x, y, state, owner, modi);
        }
    }
}

class GestureClick : public SkView::Click {
public:
    GestureClick(SkView* target) : SkView::Click(target) {
        this->setType(gGestureClickType);
    }

    static bool IsGesture(Click* click) {
        return click->isType(gGestureClickType);
    }
};

SkView::Click* SampleWindow::onFindClickHandler(SkScalar x, SkScalar y,
                                                unsigned modi) {
    return new GestureClick(this);
}

bool SampleWindow::onClick(Click* click) {
    if (GestureClick::IsGesture(click)) {
        float x = static_cast<float>(click->fICurr.fX);
        float y = static_cast<float>(click->fICurr.fY);

        switch (click->fState) {
            case SkView::Click::kDown_State:
                fGesture.touchBegin(click->fOwner, x, y);
                break;
            case SkView::Click::kMoved_State:
                fGesture.touchMoved(click->fOwner, x, y);
                this->updateMatrix();
                break;
            case SkView::Click::kUp_State:
                fGesture.touchEnd(click->fOwner);
                this->updateMatrix();
                break;
        }
        return true;
    }
    return false;
}

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

void SampleWindow::loadView(SkView* view) {
    SkView::F2BIter iter(this);
    SkView* prev = iter.next();
    if (prev) {
        prev->detachFromParent();
    }

    view->setVisibleP(true);
    view->setClipToBounds(false);
    this->attachChildToFront(view)->unref();
    view->setSize(this->width(), this->height());

    //repopulate the slide menu when a view is loaded
    fSlideMenu->reset();

    (void)SampleView::SetUsePipe(view, fPipeState);
    if (SampleView::IsSampleView(view))
        ((SampleView*)view)->requestMenu(fSlideMenu);
    this->onUpdateMenu(fSlideMenu);
    this->updateTitle();
}

static const char* gConfigNames[] = {
    "unknown config",
    "A1",
    "A8",
    "Index8",
    "565",
    "4444",
    "8888"
};

static const char* configToString(SkBitmap::Config c) {
    return gConfigNames[c];
}

static const char* gDeviceTypePrefix[] = {
    "raster: ",
    "picture: ",
#if SK_SUPPORT_GPU
    "opengl: ",
#if SK_ANGLE
    "angle: ",
#endif // SK_ANGLE
    "null-gl: "
#endif // SK_SUPPORT_GPU
};
SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gDeviceTypePrefix) == SampleWindow::kDeviceTypeCnt,
                  array_size_mismatch);

static const char* trystate_str(SkOSMenu::TriState state,
                                const char trueStr[], const char falseStr[]) {
    if (SkOSMenu::kOnState == state) {
        return trueStr;
    } else if (SkOSMenu::kOffState == state) {
        return falseStr;
    }
    return NULL;
}

void SampleWindow::updateTitle() {
    SkView* view = curr_view(this);

    SkString title;
    if (!curr_title(this, &title)) {
        title.set("<unknown>");
    }

    title.prepend(gDeviceTypePrefix[fDeviceType]);

    title.prepend(" ");
    title.prepend(configToString(this->getBitmap().config()));

    if (fAnimating) {
        title.prepend("<A> ");
    }
    if (fScale) {
        title.prepend("<S> ");
    }
    if (fRotate) {
        title.prepend("<R> ");
    }
    if (fNClip) {
        title.prepend("<C> ");
    }
    if (fPerspAnim) {
        title.prepend("<K> ");
    }

    title.prepend(trystate_str(fLCDState, "LCD ", "lcd "));
    title.prepend(trystate_str(fAAState, "AA ", "aa "));
    title.prepend(trystate_str(fFilterState, "H ", "h "));
    title.prepend(fFlipAxis & kFlipAxis_X ? "X " : NULL);
    title.prepend(fFlipAxis & kFlipAxis_Y ? "Y " : NULL);

    if (fZoomLevel) {
        title.prependf("{%.2f} ", SkScalarToFloat(fZoomLevel));
    }

    if (fMeasureFPS) {
        title.appendf(" %8.3f ms", fMeasureFPS_Time / (float)FPS_REPEAT_COUNT);
    }
    if (SampleView::IsSampleView(view)) {
        switch (fPipeState) {
            case SkOSMenu::kOnState:
                title.prepend("<Pipe> ");
                break;
            case SkOSMenu::kMixedState:
                title.prepend("<Tiled Pipe> ");
                break;

            default:
                break;
        }
        title.prepend("! ");
    }

#if SK_SUPPORT_GPU
    if (IsGpuDeviceType(fDeviceType) &&
        NULL != fDevManager &&
        fDevManager->getGrRenderTarget() &&
        fDevManager->getGrRenderTarget()->numSamples() > 0) {
        title.appendf(" [MSAA: %d]",
                       fDevManager->getGrRenderTarget()->numSamples());
    }
#endif

    this->setTitle(title.c_str());
}

void SampleWindow::onSizeChange() {
    this->INHERITED::onSizeChange();

    SkView::F2BIter iter(this);
    SkView* view = iter.next();
    view->setSize(this->width(), this->height());

    // rebuild our clippath
    {
        const SkScalar W = this->width();
        const SkScalar H = this->height();

        fClipPath.reset();
#if 0
        for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
            SkRect r;
            r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
            for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
                fClipPath.addRect(r);
        }
#else
        SkRect r;
        r.set(0, 0, W, H);
        fClipPath.addRect(r, SkPath::kCCW_Direction);
        r.set(W/4, H/4, W*3/4, H*3/4);
        fClipPath.addRect(r, SkPath::kCW_Direction);
#endif
    }

    fZoomCenterX = SkScalarHalf(this->width());
    fZoomCenterY = SkScalarHalf(this->height());

#ifdef SK_BUILD_FOR_ANDROID
    // FIXME: The first draw after a size change does not work on Android, so
    // we post an invalidate.
    this->postInvalDelay();
#endif
    this->updateTitle();    // to refresh our config
    fDevManager->windowSizeChanged(this);
}

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

static const char is_sample_view_tag[] = "sample-is-sample-view";
static const char repeat_count_tag[] = "sample-set-repeat-count";
static const char set_use_pipe_tag[] = "sample-set-use-pipe";

bool SampleView::IsSampleView(SkView* view) {
    SkEvent evt(is_sample_view_tag);
    return view->doQuery(&evt);
}

bool SampleView::SetRepeatDraw(SkView* view, int count) {
    SkEvent evt(repeat_count_tag);
    evt.setFast32(count);
    return view->doEvent(evt);
}

bool SampleView::SetUsePipe(SkView* view, SkOSMenu::TriState state) {
    SkEvent evt;
    evt.setS32(set_use_pipe_tag, state);
    return view->doEvent(evt);
}

bool SampleView::onEvent(const SkEvent& evt) {
    if (evt.isType(repeat_count_tag)) {
        fRepeatCount = evt.getFast32();
        return true;
    }

    int32_t pipeHolder;
    if (evt.findS32(set_use_pipe_tag, &pipeHolder)) {
        fPipeState = static_cast<SkOSMenu::TriState>(pipeHolder);
        return true;
    }

    if (evt.isType("debug-hit-test")) {
        fDebugHitTest = true;
        evt.findS32("debug-hit-test-x", &fDebugHitTestLoc.fX);
        evt.findS32("debug-hit-test-y", &fDebugHitTestLoc.fY);
        this->inval(NULL);
        return true;
    }

    return this->INHERITED::onEvent(evt);
}

bool SampleView::onQuery(SkEvent* evt) {
    if (evt->isType(is_sample_view_tag)) {
        return true;
    }
    return this->INHERITED::onQuery(evt);
}


class SimplePC : public SkGPipeController {
public:
    SimplePC(SkCanvas* target);
    ~SimplePC();

    virtual void* requestBlock(size_t minRequest, size_t* actual);
    virtual void notifyWritten(size_t bytes);

private:
    SkGPipeReader   fReader;
    void*           fBlock;
    size_t          fBlockSize;
    size_t          fBytesWritten;
    int             fAtomsWritten;
    SkGPipeReader::Status   fStatus;

    size_t        fTotalWritten;
};

SimplePC::SimplePC(SkCanvas* target) : fReader(target) {
    fBlock = NULL;
    fBlockSize = fBytesWritten = 0;
    fStatus = SkGPipeReader::kDone_Status;
    fTotalWritten = 0;
    fAtomsWritten = 0;
    fReader.setBitmapDecoder(&SkImageDecoder::DecodeMemory);
}

SimplePC::~SimplePC() {
//    SkASSERT(SkGPipeReader::kDone_Status == fStatus);
    if (fTotalWritten) {
        SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten,
                 fAtomsWritten, fStatus);
#ifdef  PIPE_FILE
        //File is open in append mode
        FILE* f = fopen(FILE_PATH, "ab");
        SkASSERT(f != NULL);
        fwrite((const char*)fBlock + fBytesWritten, 1, bytes, f);
        fclose(f);
#endif
#ifdef PIPE_NET
        if (fAtomsWritten > 1 && fTotalWritten > 4) { //ignore done
            gServer.acceptConnections();
            gServer.writePacket(fBlock, fTotalWritten);
        }
#endif
    }
    sk_free(fBlock);
}

void* SimplePC::requestBlock(size_t minRequest, size_t* actual) {
    sk_free(fBlock);

    fBlockSize = minRequest * 4;
    fBlock = sk_malloc_throw(fBlockSize);
    fBytesWritten = 0;
    *actual = fBlockSize;
    return fBlock;
}

void SimplePC::notifyWritten(size_t bytes) {
    SkASSERT(fBytesWritten + bytes <= fBlockSize);
    fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes);
    SkASSERT(SkGPipeReader::kError_Status != fStatus);
    fBytesWritten += bytes;
    fTotalWritten += bytes;

    fAtomsWritten += 1;
}

void SampleView::draw(SkCanvas* canvas) {
    if (SkOSMenu::kOffState == fPipeState) {
        this->INHERITED::draw(canvas);
    } else {
        SkGPipeWriter writer;
        SimplePC controller(canvas);
        TiledPipeController tc(canvas->getDevice()->accessBitmap(false),
                               &SkImageDecoder::DecodeMemory,
                               &canvas->getTotalMatrix());
        SkGPipeController* pc;
        if (SkOSMenu::kMixedState == fPipeState) {
            pc = &tc;
        } else {
            pc = &controller;
        }
        uint32_t flags = SkGPipeWriter::kCrossProcess_Flag;

        canvas = writer.startRecording(pc, flags);
        //Must draw before controller goes out of scope and sends data
        this->INHERITED::draw(canvas);
        //explicitly end recording to ensure writer is flushed before the memory
        //is freed in the deconstructor of the controller
        writer.endRecording();
    }
}

#include "SkBounder.h"

class DebugHitTestBounder : public SkBounder {
public:
    DebugHitTestBounder(int x, int y) {
        fLoc.set(x, y);
    }

    virtual bool onIRect(const SkIRect& bounds) SK_OVERRIDE {
        if (bounds.contains(fLoc.x(), fLoc.y())) {
            //
            // Set a break-point here to see what was being drawn under
            // the click point (just needed a line of code to stop the debugger)
            //
            bounds.centerX();
        }
        return true;
    }

private:
    SkIPoint fLoc;
    typedef SkBounder INHERITED;
};

void SampleView::onDraw(SkCanvas* canvas) {
    this->onDrawBackground(canvas);

    DebugHitTestBounder bounder(fDebugHitTestLoc.x(), fDebugHitTestLoc.y());
    if (fDebugHitTest) {
        canvas->setBounder(&bounder);
    }

    for (int i = 0; i < fRepeatCount; i++) {
        SkAutoCanvasRestore acr(canvas, true);
        this->onDrawContent(canvas);
    }

    fDebugHitTest = false;
    canvas->setBounder(NULL);
}

void SampleView::onDrawBackground(SkCanvas* canvas) {
    canvas->drawColor(fBGColor);
}

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

template <typename T> void SkTBSort(T array[], int count) {
    for (int i = 1; i < count - 1; i++) {
        bool didSwap = false;
        for (int j = count - 1; j > i; --j) {
            if (array[j] < array[j-1]) {
                T tmp(array[j-1]);
                array[j-1] = array[j];
                array[j] = tmp;
                didSwap = true;
            }
        }
        if (!didSwap) {
            break;
        }
    }

    for (int k = 0; k < count - 1; k++) {
        SkASSERT(!(array[k+1] < array[k]));
    }
}

#include "SkRandom.h"

static void rand_rect(SkIRect* rect, SkRandom& rand) {
    int bits = 8;
    int shift = 32 - bits;
    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
              rand.nextU() >> shift, rand.nextU() >> shift);
    rect->sort();
}

static void dumpRect(const SkIRect& r) {
    SkDebugf(" { %d, %d, %d, %d },\n",
             r.fLeft, r.fTop,
             r.fRight, r.fBottom);
}

static void test_rects(const SkIRect rect[], int count) {
    SkRegion rgn0, rgn1;

    for (int i = 0; i < count; i++) {
        rgn0.op(rect[i], SkRegion::kUnion_Op);
     //   dumpRect(rect[i]);
    }
    rgn1.setRects(rect, count);

    if (rgn0 != rgn1) {
        SkDebugf("\n");
        for (int i = 0; i < count; i++) {
            dumpRect(rect[i]);
        }
        SkDebugf("\n");
    }
}

static void test() {
    size_t i;

    const SkIRect r0[] = {
        { 0, 0, 1, 1 },
        { 2, 2, 3, 3 },
    };
    const SkIRect r1[] = {
        { 0, 0, 1, 3 },
        { 1, 1, 2, 2 },
        { 2, 0, 3, 3 },
    };
    const SkIRect r2[] = {
        { 0, 0, 1, 2 },
        { 2, 1, 3, 3 },
        { 4, 0, 5, 1 },
        { 6, 0, 7, 4 },
    };

    static const struct {
        const SkIRect* fRects;
        int            fCount;
    } gRecs[] = {
        { r0, SK_ARRAY_COUNT(r0) },
        { r1, SK_ARRAY_COUNT(r1) },
        { r2, SK_ARRAY_COUNT(r2) },
    };

    for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
        test_rects(gRecs[i].fRects, gRecs[i].fCount);
    }

    SkRandom rand;
    for (i = 0; i < 10000; i++) {
        SkRegion rgn0, rgn1;

        const int N = 8;
        SkIRect rect[N];
        for (int j = 0; j < N; j++) {
            rand_rect(&rect[j], rand);
        }
        test_rects(rect, N);
    }
}

// FIXME: this should be in a header
SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
    if (false) { // avoid bit rot, suppress warning
        test();
    }
    return new SampleWindow(hwnd, argc, argv, NULL);
}

// FIXME: this should be in a header
void get_preferred_size(int* x, int* y, int* width, int* height);
void get_preferred_size(int* x, int* y, int* width, int* height) {
    *x = 10;
    *y = 50;
    *width = 640;
    *height = 480;
}

#ifdef SK_BUILD_FOR_IOS
void save_args(int argc, char *argv[]) {
}
#endif

// FIXME: this should be in a header
void application_init();
void application_init() {
//    setenv("ANDROID_ROOT", "../../../data", 0);
#ifdef SK_BUILD_FOR_MAC
    setenv("ANDROID_ROOT", "/android/device/data", 0);
#endif
    SkGraphics::Init();
    SkEvent::Init();
}

// FIXME: this should be in a header
void application_term();
void application_term() {
    SkEvent::Term();
    SkGraphics::Term();
}
