/*
 * 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 "SkAnimTimer.h"
#include "SkColor.h"
#include "SkRandom.h"
#include "SkRRect.h"
#include "SkSVGDOM.h"
#include "SkSVGG.h"
#include "SkSVGPath.h"
#include "SkSVGRect.h"
#include "SkSVGSVG.h"

namespace {

static const SkRect kBounds     = SkRect::MakeLTRB(0.1f, 0.1f, 0.9f, 0.9f);
static const SkSize kPaddleSize = SkSize::Make(0.03f, 0.1f);
static const SkScalar kBallSize = 0.04f;
static const SkScalar kShadowOpacity       = 0.40f;
static const SkScalar kShadowParallax      = 0.04f;
static const SkScalar kBackgroundStroke    = 0.01f;
static const uint32_t kBackgroundDashCount = 20;

static const SkScalar kBallSpeedMax  = 0.0020f;
static const SkScalar kBallSpeedMin  = 0.0005f;
static const SkScalar kBallSpeedFuzz = 0.0002f;

static const SkScalar kTimeScaleMin = 0.0f;
static const SkScalar kTimeScaleMax = 5.0f;

// Box the value within [min, max), by applying infinite reflection on the interval endpoints.
SkScalar box_reflect(SkScalar v, SkScalar min, SkScalar max) {
    const SkScalar intervalLen = max - min;
    SkASSERT(intervalLen > 0);

    // f(v) is periodic in 2 * intervalLen: one normal progression + one reflection
    const SkScalar P = intervalLen * 2;
    // relative to P origin
    const SkScalar vP = v - min;
    // map to [0, P)
    const SkScalar vMod = (vP < 0) ? P - SkScalarMod(-vP, P) : SkScalarMod(vP, P);
    // reflect if needed, to map to [0, intervalLen)
    const SkScalar vInterval = vMod < intervalLen ? vMod : P - vMod;
    // finally, reposition relative to min
    return vInterval + min;
}

// Compute <t, y> for the trajectory intersection with the next vertical edge.
std::tuple<SkScalar, SkScalar> find_yintercept(const SkPoint& pos, const SkVector& spd,
                                               const SkRect& box) {
    const SkScalar edge = spd.fX > 0 ? box.fRight : box.fLeft;
    const SkScalar    t = (edge - pos.fX) / spd.fX;
    SkASSERT(t >= 0);
    const SkScalar   dY = t * spd.fY;

    return std::make_tuple(t, box_reflect(pos.fY + dY, box.fTop, box.fBottom));
}

sk_sp<SkSVGRect> make_svg_rrect(const SkRRect& rrect) {
    sk_sp<SkSVGRect> node = SkSVGRect::Make();
    node->setX(SkSVGLength(rrect.rect().x()));
    node->setY(SkSVGLength(rrect.rect().y()));
    node->setWidth(SkSVGLength(rrect.width()));
    node->setHeight(SkSVGLength(rrect.height()));
    node->setRx(SkSVGLength(rrect.getSimpleRadii().x()));
    node->setRy(SkSVGLength(rrect.getSimpleRadii().y()));

    return node;
}

} // anonymous ns

class SVGPongView final : public SampleView {
public:
    SVGPongView() {}

protected:
    void onOnceBeforeDraw() override {
        const SkRect fieldBounds = kBounds.makeOutset(kBallSize / 2, kBallSize / 2);
        const SkRRect ball = SkRRect::MakeOval(SkRect::MakeWH(kBallSize, kBallSize));
        const SkRRect paddle = SkRRect::MakeRectXY(SkRect::MakeWH(kPaddleSize.width(),
                                                                  kPaddleSize.height()),
                                                   kPaddleSize.width() / 2,
                                                   kPaddleSize.width() / 2);
        fBall.initialize(ball,
                         SK_ColorGREEN,
                         SkPoint::Make(kBounds.centerX(), kBounds.centerY()),
                         SkVector::Make(fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax),
                                        fRand.nextRangeScalar(kBallSpeedMin, kBallSpeedMax)));
        fPaddle0.initialize(paddle,
                            SK_ColorBLUE,
                            SkPoint::Make(fieldBounds.left() - kPaddleSize.width() / 2,
                                          fieldBounds.centerY()),
                            SkVector::Make(0, 0));
        fPaddle1.initialize(paddle,
                            SK_ColorRED,
                            SkPoint::Make(fieldBounds.right() + kPaddleSize.width() / 2,
                                          fieldBounds.centerY()),
                            SkVector::Make(0, 0));

        // Background decoration.
        SkPath bgPath;
        bgPath.moveTo(kBounds.left() , fieldBounds.top());
        bgPath.lineTo(kBounds.right(), fieldBounds.top());
        bgPath.moveTo(kBounds.left() , fieldBounds.bottom());
        bgPath.lineTo(kBounds.right(), fieldBounds.bottom());
        // TODO: stroke-dash support would come in handy right about now.
        for (uint32_t i = 0; i < kBackgroundDashCount; ++i) {
            bgPath.moveTo(kBounds.centerX(),
                          kBounds.top() + (i + 0.25f) * kBounds.height() / kBackgroundDashCount);
            bgPath.lineTo(kBounds.centerX(),
                          kBounds.top() + (i + 0.75f) * kBounds.height() / kBackgroundDashCount);
        }

        sk_sp<SkSVGPath> bg = SkSVGPath::Make();
        bg->setPath(bgPath);
        bg->setFill(SkSVGPaint(SkSVGPaint::Type::kNone));
        bg->setStroke(SkSVGPaint(SkSVGColorType(SK_ColorBLACK)));
        bg->setStrokeWidth(SkSVGLength(kBackgroundStroke));

        // Build the SVG DOM tree.
        sk_sp<SkSVGSVG> root = SkSVGSVG::Make();
        root->appendChild(std::move(bg));
        root->appendChild(fPaddle0.shadowNode);
        root->appendChild(fPaddle1.shadowNode);
        root->appendChild(fBall.shadowNode);
        root->appendChild(fPaddle0.objectNode);
        root->appendChild(fPaddle1.objectNode);
        root->appendChild(fBall.objectNode);

        // Handle everything in a normalized 1x1 space.
        root->setViewBox(SkSVGViewBoxType(SkRect::MakeWH(1, 1)));

        fDom = sk_sp<SkSVGDOM>(new SkSVGDOM(SkSize::Make(this->width(), this->height())));
        fDom->setRoot(std::move(root));

        // Off we go.
        this->updatePaddleStrategy();
    }

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

        SkUnichar uni;
        if (SampleCode::CharQ(*evt, &uni)) {
            switch (uni) {
                case '[':
                    fTimeScale = SkTPin(fTimeScale - 0.1f, kTimeScaleMin, kTimeScaleMax);
                    return true;
                case ']':
                    fTimeScale = SkTPin(fTimeScale + 0.1f, kTimeScaleMin, kTimeScaleMax);
                    return true;
                default:
                    break;
            }
        }
        return this->INHERITED::onQuery(evt);
    }

    void onSizeChange() override {
        if (fDom) {
            fDom->setContainerSize(SkSize::Make(this->width(), this->height()));
        }

        this->INHERITED::onSizeChange();
    }

    void onDrawContent(SkCanvas* canvas) override {
        fDom->render(canvas);
    }

    bool onAnimate(const SkAnimTimer& timer) override {
        SkScalar dt = (timer.msec() - fLastTick) * fTimeScale;
        fLastTick = timer.msec();

        fPaddle0.posTick(dt);
        fPaddle1.posTick(dt);
        fBall.posTick(dt);

        this->enforceConstraints();

        fPaddle0.updateDom();
        fPaddle1.updateDom();
        fBall.updateDom();

        return true;
    }

private:
    struct Object {
        void initialize(const SkRRect& rrect, SkColor color,
                        const SkPoint& p, const SkVector& s) {
            objectNode = make_svg_rrect(rrect);
            objectNode->setFill(SkSVGPaint(SkSVGColorType(color)));

            shadowNode = make_svg_rrect(rrect);
            shadowNode->setFillOpacity(SkSVGNumberType(kShadowOpacity));

            pos = p;
            spd = s;
            size = SkSize::Make(rrect.width(), rrect.height());
        }

        void posTick(SkScalar dt) {
            pos += spd * dt;
        }

        void updateDom() {
            const SkPoint corner = pos - SkPoint::Make(size.width() / 2, size.height() / 2);
            objectNode->setX(SkSVGLength(corner.x()));
            objectNode->setY(SkSVGLength(corner.y()));

            // Simulate parallax shadow for a centered light source.
            SkPoint shadowOffset = pos - SkPoint::Make(kBounds.centerX(), kBounds.centerY());
            shadowOffset.scale(kShadowParallax);
            const SkPoint shadowCorner = corner + shadowOffset;

            shadowNode->setX(SkSVGLength(shadowCorner.x()));
            shadowNode->setY(SkSVGLength(shadowCorner.y()));
        }

        sk_sp<SkSVGRect> objectNode;
        sk_sp<SkSVGRect> shadowNode;
        SkPoint          pos;
        SkVector         spd;
        SkSize           size;
    };

    void enforceConstraints() {
        // Perfect vertical reflection.
        if (fBall.pos.fY < kBounds.fTop || fBall.pos.fY >= kBounds.fBottom) {
            fBall.spd.fY = -fBall.spd.fY;
            fBall.pos.fY = box_reflect(fBall.pos.fY, kBounds.fTop, kBounds.fBottom);
        }

        // Horizontal bounce - introduces a speed fuzz.
        if (fBall.pos.fX < kBounds.fLeft || fBall.pos.fX >= kBounds.fRight) {
            fBall.spd.fX = this->fuzzBallSpeed(-fBall.spd.fX);
            fBall.spd.fY = this->fuzzBallSpeed(fBall.spd.fY);
            fBall.pos.fX = box_reflect(fBall.pos.fX, kBounds.fLeft, kBounds.fRight);
            this->updatePaddleStrategy();
        }
    }

    SkScalar fuzzBallSpeed(SkScalar spd) {
        // The speed limits are absolute values.
        const SkScalar   sign = spd >= 0 ? 1.0f : -1.0f;
        const SkScalar fuzzed = fabs(spd) + fRand.nextRangeScalar(-kBallSpeedFuzz, kBallSpeedFuzz);

        return sign * SkTPin(fuzzed, kBallSpeedMin, kBallSpeedMax);
    }

    void updatePaddleStrategy() {
        Object* pitcher = fBall.spd.fX > 0 ? &fPaddle0 : &fPaddle1;
        Object* catcher = fBall.spd.fX > 0 ? &fPaddle1 : &fPaddle0;

        SkScalar t, yIntercept;
        std::tie(t, yIntercept) = find_yintercept(fBall.pos, fBall.spd, kBounds);

        // The pitcher aims for a neutral/centered position.
        pitcher->spd.fY = (kBounds.centerY() - pitcher->pos.fY) / t;

        // The catcher goes for the ball.  Duh.
        catcher->spd.fY = (yIntercept - catcher->pos.fY) / t;
    }

    sk_sp<SkSVGDOM> fDom;
    Object          fPaddle0, fPaddle1, fBall;
    SkRandom        fRand;

    SkMSec          fLastTick  = 0;
    SkScalar        fTimeScale = 1.0f;

    typedef SampleView INHERITED;
};

static SkView* SVGPongFactory() { return new SVGPongView; }
static SkViewRegister reg(SVGPongFactory);
