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

#include "bench/SKPAnimationBench.h"
#include "include/core/SkMultiPictureDraw.h"
#include "include/core/SkSurface.h"
#include "tools/flags/CommandLineFlags.h"

SKPAnimationBench::SKPAnimationBench(const char* name, const SkPicture* pic, const SkIRect& clip,
                                     Animation* animation, bool doLooping)
    : INHERITED(name, pic, clip, 1.0, false, doLooping)
    , fAnimation(SkRef(animation)) {
    fUniqueName.printf("%s_%s", name, fAnimation->getTag());
}

const char* SKPAnimationBench::onGetUniqueName() {
    return fUniqueName.c_str();
}

void SKPAnimationBench::onPerCanvasPreDraw(SkCanvas* canvas) {
    INHERITED::onPerCanvasPreDraw(canvas);
    fDevBounds = canvas->getDeviceClipBounds();
    SkAssertResult(!fDevBounds.isEmpty());
    fAnimationTimer.start();
}

void SKPAnimationBench::drawPicture() {
    fAnimationTimer.end();

    for (int j = 0; j < this->tileRects().count(); ++j) {
        SkMatrix trans = SkMatrix::MakeTrans(-1.f * this->tileRects()[j].fLeft,
                                             -1.f * this->tileRects()[j].fTop);
        fAnimation->preConcatFrameMatrix(fAnimationTimer.fWall, fDevBounds, &trans);
        this->surfaces()[j]->getCanvas()->drawPicture(this->picture(), &trans, nullptr);
    }

    for (int j = 0; j < this->tileRects().count(); ++j) {
       this->surfaces()[j]->getCanvas()->flush();
    }
}

class ZoomAnimation : public SKPAnimationBench::Animation {
public:
    ZoomAnimation(SkScalar zoomMax, double zoomPeriodMs)
        : fZoomMax(zoomMax)
        , fZoomPeriodMs(zoomPeriodMs) {
    }

    virtual const char* getTag() { return "zoom"; }

    virtual void preConcatFrameMatrix(double animationTimeMs, const SkIRect& devBounds,
                                      SkMatrix* drawMatrix) {
        double t = fmod(animationTimeMs / fZoomPeriodMs, 1.0); // t is in [0, 1).
        t = fabs(2 * t - 1); // Make t ping-pong between 0 and 1
        SkScalar zoom = static_cast<SkScalar>(pow(fZoomMax, t));

        SkPoint center = SkPoint::Make((devBounds.fLeft + devBounds.fRight) / 2.0f,
                                       (devBounds.fTop + devBounds.fBottom) / 2.0f);
        drawMatrix->preTranslate(center.fX, center.fY);
        drawMatrix->preScale(zoom, zoom);
        drawMatrix->preTranslate(-center.fX, -center.fY);
    }

private:
    double   fZoomMax;
    double   fZoomPeriodMs;
};

SKPAnimationBench::Animation* SKPAnimationBench::CreateZoomAnimation(SkScalar zoomMax,
                                                                     double zoomPeriodMs) {
    return new ZoomAnimation(zoomMax, zoomPeriodMs);
}
