/*
 * Copyright 2016 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 "SkPictureRecorder.h"
#include "SkShadowPaintFilterCanvas.h"
#include "SkShadowShader.h"
#include "SkSurface.h"

#ifdef SK_EXPERIMENTAL_SHADOWING

class ShadowingView : public SampleView {
public:
    ShadowingView()
        : fSceneChanged(true)
        , fLightsChanged(true)
        , fMoveLight(false)
        , fClearShadowMaps(false)
        , fSelectedRectID(-1)
        , fSelectedSliderID(-1)
        , fLightDepth(400.0f)  {
        this->setBGColor(0xFFCCCCCC);

        this->updateLights(100, 100);

        fTestRects[0].fColor = 0xFFEE8888;
        fTestRects[0].fDepth = 80;
        fTestRects[0].fGeometry = SkRect::MakeLTRB(300,200,350,250);

        fTestRects[1].fColor = 0xFF88EE88;
        fTestRects[1].fDepth = 160;
        fTestRects[1].fGeometry = SkRect::MakeLTRB(200,300,250,350);

        fTestRects[2].fColor = 0xFF8888EE;
        fTestRects[2].fDepth = 240;
        fTestRects[2].fGeometry = SkRect::MakeLTRB(100,100,150,150);

        fSliders[0].fGeometry = SkRect::MakeLTRB(20, 400, 30, 420);
        fSliders[0].fOffset = 0.0f;
        fSliders[0].fScale = 0.1f;

        fSliders[1].fGeometry = SkRect::MakeLTRB(100, 420, 110, 440);
        fSliders[1].fOffset = 0.0f;
        fSliders[1].fScale = 10.0f;

        fSliders[2].fGeometry = SkRect::MakeLTRB(0, 440, 10, 460);
        fSliders[2].fOffset = 0.0f;
        fSliders[2].fScale = 0.0025f;

        fShadowParams.fShadowRadius = 4.0f;
        fShadowParams.fBiasingConstant = 0.3f;
        fShadowParams.fMinVariance = 2048; // we need a higher min variance for point lights
        fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType;
    }

protected:
    bool onQuery(SkEvent *evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "shadowing");
            return true;
        }

        SkUnichar uni;
        if (SampleCode::CharQ(*evt, &uni)) {
            switch (uni) {
                case 'L':
                    fMoveLight = !fMoveLight;
                    break;
                case 'd':
                    // Raster generated shadow maps have their origin in the UL corner
                    // GPU shadow maps can have an arbitrary origin.
                    // We override the 'd' keypress so that when the device is cycled,
                    // the shadow maps will be re-generated according to the new backend.
                    fClearShadowMaps = true;
                    break;
                case 'q':
                    fLightDepth += 5.0f;
                    fMoveLight = true;
                    break;
                case 'B':
                    if (SkShadowParams::kVariance_ShadowType == fShadowParams.fType) {
                        fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType;
                    } else if (SkShadowParams::kNoBlur_ShadowType ==
                               fShadowParams.fType) {
                        fShadowParams.fType = SkShadowParams::kVariance_ShadowType;
                    }
                    fLightsChanged = true;
                    break;
                case 'w':
                    fLightDepth -= 5.0f;
                    fMoveLight = true;
                    break;
                default:
                    break;
            }
        }
        return this->INHERITED::onQuery(evt);
    }

    sk_sp<SkPicture> makeTestPicture(int width, int height) {
        SkPictureRecorder recorder;

        // LONG RANGE TODO: eventually add SkBBHFactory (bounding box factory)
        SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height));

        SkASSERT(canvas->getTotalMatrix().isIdentity());
        SkPaint paint;
        paint.setColor(SK_ColorGRAY);

        // LONG RANGE TODO: tag occluders
        // LONG RANGE TODO: track number of IDs we need (hopefully less than 256)
        //                  and determinate the mapping from z to id

        // universal receiver, "ground"
        canvas->drawRect(SkRect::MakeIWH(width, height), paint);

        for (int i = 0; i < kNumTestRects; i++) {
            paint.setColor(fTestRects[i].fColor);
            if (i == 0) {
                canvas->translateZ(fTestRects[0].fDepth);
            } else {
                canvas->translateZ(fTestRects[i].fDepth - fTestRects[i-1].fDepth);
            }
            canvas->drawRect(fTestRects[i].fGeometry, paint);
        }

        return recorder.finishRecordingAsPicture();
    }

    void onDrawContent(SkCanvas *canvas) override {
        if (fSceneChanged) {
            fPicture = this->makeTestPicture(kWidth, kHeight);
        }

        if (fSceneChanged || fLightsChanged || fClearShadowMaps) {
            for (int i = 0; i < fLights->numLights(); i++) {
                fLights->light(i).setShadowMap(nullptr);
            }

            fSceneChanged = false;
            fLightsChanged = false;
            fClearShadowMaps = false;
        }

        canvas->setLights(fLights);
        canvas->drawShadowedPicture(fPicture, nullptr, nullptr, fShadowParams);

        for (int i = 0; i < kNumSliders; i++) {
            SkPaint paint;
            paint.setColor(SK_ColorBLACK);
            canvas->drawRect(fSliders[i].fGeometry, paint);
        }
    }

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

    void updateLights(int x, int y) {
        SkLights::Builder builder;
        builder.add(SkLights::Light::MakePoint(SkColor3f::Make(1.0f, 1.0f, 1.0f),
                                               SkVector3::Make(x,
                                                               kHeight - y,
                                                               fLightDepth),
                                               400, true));
        fLights = builder.finish();
    }

    void updateFromSelectedSlider() {
        SkScalar newValue = fSliders[fSelectedSliderID].fGeometry.fLeft *
                            fSliders[fSelectedSliderID].fScale +
                            fSliders[fSelectedSliderID].fOffset;

        switch (fSelectedSliderID) {
            case 0:
                fShadowParams.fShadowRadius = newValue;
                break;
            case 1:
                fShadowParams.fMinVariance = newValue;
                break;
            case 2:
                fShadowParams.fBiasingConstant = newValue;
                break;
            default:
                break;
        }
    }

    bool onClick(Click *click) override {
        SkScalar x = click->fCurr.fX;
        SkScalar y = click->fCurr.fY;

        SkScalar dx = x - click->fPrev.fX;
        SkScalar dy = y - click->fPrev.fY;

        if (fMoveLight) {
            if (dx != 0 || dy != 0) {
                this->updateLights(x, y);
                fLightsChanged = true;
                this->inval(nullptr);
            }
            return true;
        }

        if (click->fState == Click::State::kUp_State) {
            fSelectedRectID = -1;
            fSelectedSliderID = -1;
            return true;
        }

        if (fSelectedRectID > -1) {
            fTestRects[fSelectedRectID].fGeometry.offset(dx, dy);

            fSceneChanged = true;
            this->inval(nullptr);
            return true;
        }

        if (fSelectedSliderID > -1) {
            fSliders[fSelectedSliderID].fGeometry.offset(dx, 0);

            this->updateFromSelectedSlider();

            fLightsChanged = true;
            this->inval(nullptr);
            return true;
        }

        // assume last elements are highest
        for (int i = kNumTestRects - 1; i >= 0; i--) {
            if (fTestRects[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
                fSelectedRectID = i;
                fTestRects[i].fGeometry.offset(dx, dy);

                fSceneChanged = true;
                this->inval(nullptr);
                break;
            }
        }

        for (int i = 0; i <= kNumSliders; i++) {
            if (fSliders[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
                fSelectedSliderID = i;
                fSliders[i].fGeometry.offset(dx, 0);

                this->updateFromSelectedSlider();

                fLightsChanged = true;

                this->inval(nullptr);
                break;
            }
        }

        return true;
    }

private:
    static constexpr int kNumTestRects = 3;
    static constexpr int kNumSliders = 3;

    static const int kWidth = 400;
    static const int kHeight = 400;

    bool fSceneChanged;
    bool fLightsChanged;
    bool fMoveLight;
    bool fClearShadowMaps;

    struct {
        SkRect  fGeometry;
        int     fDepth;
        SkColor fColor;
    } fTestRects[kNumTestRects];
    int fSelectedRectID;

    struct {
        SkRect   fGeometry;
        SkScalar fOffset;
        SkScalar fScale;
    } fSliders[kNumSliders];
    int fSelectedSliderID;

    SkScalar fLightDepth;

    sk_sp<SkPicture> fPicture;
    SkShadowParams fShadowParams;
    sk_sp<SkLights> fLights;

    typedef SampleView INHERITED;
};

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

#endif
