/*
 * Copyright 2011 Skia
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SampleApp_DEFINED
#define SampleApp_DEFINED

#include "SkOSMenu.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkSurface.h"
#include "SkTDArray.h"
#include "SkTouchGesture.h"
#include "SkWindow.h"
#include "timer/Timer.h"

#include "SkPipe.h"

class GrContext;
class GrRenderTarget;

class SkCanvas;
class SkData;
class SkDocument;
class SkEvent;
class SkTypeface;
class SkViewFactory;

class SampleWindow : public SkOSWindow {
    SkTDArray<const SkViewFactory*> fSamples;
public:
    enum DeviceType {
        kRaster_DeviceType,
#if SK_SUPPORT_GPU
        kGPU_DeviceType,
#if SK_ANGLE
        kANGLE_DeviceType,
#endif // SK_ANGLE
#endif // SK_SUPPORT_GPU
        kDeviceTypeCnt
    };

    static bool IsGpuDeviceType(DeviceType devType) {
    #if SK_SUPPORT_GPU
        switch (devType) {
            case kGPU_DeviceType:
    #if SK_ANGLE
            case kANGLE_DeviceType:
    #endif // SK_ANGLE
                return true;
            default:
                return false;
        }
    #endif // SK_SUPPORT_GPU
        return false;
    }

    /**
     * SampleApp ports can subclass this manager class if they want to:
     *      * filter the types of devices supported
     *      * customize plugging of SkBaseDevice objects into an SkCanvas
     *      * customize publishing the results of draw to the OS window
     *      * manage GrContext / GrRenderTarget lifetimes
     */
    class DeviceManager : public SkRefCnt {
    public:


        virtual void setUpBackend(SampleWindow* win, int msaaSampleCount, bool deepColor) = 0;

        virtual void tearDownBackend(SampleWindow* win) = 0;

        // called before drawing. should install correct device
        // type on the canvas. Will skip drawing if returns false.
        virtual sk_sp<SkSurface> makeSurface(DeviceType dType, SampleWindow* win) = 0;

        // called after drawing, should get the results onto the
        // screen.
        virtual void publishCanvas(DeviceType dType,
                                   SkCanvas* canvas,
                                   SampleWindow* win) = 0;

        // called when window changes size, guaranteed to be called
        // at least once before first draw (after init)
        virtual void windowSizeChanged(SampleWindow* win) = 0;

        // return the GrContext backing gpu devices (nullptr if not built with GPU support)
        virtual GrContext* getGrContext() = 0;

        // return the GrRenderTarget backing gpu devices (nullptr if not built with GPU support)
        virtual int numColorSamples() const = 0;

        // return the color depth of the output device
        virtual int getColorBits() = 0;

    private:
        typedef SkRefCnt INHERITED;
    };

    SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
    virtual ~SampleWindow();

    sk_sp<SkSurface> makeSurface() override {
        sk_sp<SkSurface> surface;
        if (fDevManager) {
            surface = fDevManager->makeSurface(fDeviceType, this);
        }
        if (!surface) {
            surface = this->INHERITED::makeSurface();
        }
        return surface;
    }

    void draw(SkCanvas*) override;

    void setDeviceType(DeviceType type);
    void setDeviceColorType(SkColorType, sk_sp<SkColorSpace>);
    void toggleRendering();
    void toggleSlideshow();
    void toggleFPS();
    void showOverview();
    void toggleDistanceFieldFonts();
    void setPixelGeometry(int pixelGeometryIndex);

    GrContext* getGrContext() const { return fDevManager->getGrContext(); }

    void setZoomCenter(float x, float y);
    void changeZoomLevel(float delta);
    void changeOffset(SkVector delta);
    bool nextSample();
    bool previousSample();
    bool goToSample(int i);
    SkString getSampleTitle(int i);
    int  sampleCount();
    bool handleTouch(int ownerId, float x, float y,
            SkView::Click::State state);
    void saveToPdf();
    void postInvalDelay();

    DeviceType getDeviceType() const { return fDeviceType; }
    int getColorConfigIndex() const { return fColorConfigIndex; }

protected:
    void onDraw(SkCanvas* canvas) override;
    bool onHandleKey(SkKey key) override;
    bool onHandleChar(SkUnichar) override;
    void onSizeChange() override;

    SkCanvas* beforeChildren(SkCanvas*) override;
    void afterChildren(SkCanvas*) override;
    void beforeChild(SkView* child, SkCanvas* canvas) override;

    bool onEvent(const SkEvent& evt) override;
    bool onQuery(SkEvent* evt) override;

    virtual bool onDispatchClick(int x, int y, Click::State, void* owner,
                                 unsigned modi) override;
    bool onClick(Click* click) override;
    virtual Click* onFindClickHandler(SkScalar x, SkScalar y,
                                      unsigned modi) override;

private:
    class DefaultDeviceManager;

    int fCurrIndex;

    std::unique_ptr<SkDynamicMemoryWStream> fPipeStream;
    SkPipeSerializer        fPipeSerializer;
    SkPipeDeserializer      fPipeDeserializer;

    SkPictureRecorder fRecorder;
    std::unique_ptr<SkCanvas> fFlagsFilterCanvas;
    SkPath fClipPath;

    SkTouchGesture fGesture;
    SkScalar fZoomLevel;
    SkScalar fZoomScale;
    SkVector fOffset;

    DeviceType fDeviceType;
    DeviceManager* fDevManager;

    bool fSaveToPdf;
    bool fSaveToSKP;
    sk_sp<SkDocument> fPDFDocument;

    bool fUseClip;
    bool fUsePicture;
    bool fAnimating;
    bool fRotate;
    bool fPerspAnim;
    bool fRequestGrabImage;
    bool fMeasureFPS;
    bool fUseDeferredCanvas;
    WallTimer fTimer;
    double fMeasureFPS_Time;
    bool fMagnify;
    int fTilingMode;

    // The following are for the 'fatbits' drawing
    // Latest position of the mouse.
    int fMouseX, fMouseY;
    int fFatBitsScale;
    // Used by the text showing position and color values.
    sk_sp<SkTypeface> fTypeface;
    bool fShowZoomer;

    SkOSMenu::TriState fLCDState;
    SkOSMenu::TriState fAAState;
    SkOSMenu::TriState fSubpixelState;
    int fHintingState;
    int fPixelGeometryIndex;
    int fFilterQualityIndex;
    unsigned   fFlipAxis;

    int fMSAASampleCount;
    bool fDeepColor;
    int fColorConfigIndex;

    SkScalar fZoomCenterX, fZoomCenterY;

    //Stores global settings
    SkOSMenu* fAppMenu; // We pass ownership to SkWindow, when we call addMenu
    //Stores slide specific settings
    SkOSMenu* fSlideMenu; // We pass ownership to SkWindow, when we call addMenu

    void loadView(SkView*);
    void updateTitle();
    bool getRawTitle(SkString*);

    bool zoomIn();
    bool zoomOut();
    void updatePointer(int x, int y);
    void magnify(SkCanvas* canvas);
    void showZoomer(SkCanvas* canvas);
    void updateMatrix();
    void postAnimatingEvent();
    int findByTitle(const char*);
    void listTitles();
    SkSize tileSize() const;
    bool sendAnimatePulse();

    typedef SkOSWindow INHERITED;
};

#endif
