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

#include "tools/skottie_ios_app/SkottieViewController.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTime.h"
#include "modules/skottie/include/Skottie.h"

#include <cmath>

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

class SkAnimationDraw {
public:
    SkAnimationDraw() = default;
    ~SkAnimationDraw() = default;

    explicit operator bool() const { return fAnimation != nullptr; }

    void draw(SkSize size, SkCanvas* canvas) {
        if (size.width() != fSize.width() || size.height() != fSize.height()) {
            // Cache the current matrix; change only if size changes.
            if (fAnimationSize.width() > 0 && fAnimationSize.height() > 0) {
                float scale = std::min(size.width() / fAnimationSize.width(),
                                       size.height() / fAnimationSize.height());
                fMatrix.setScaleTranslate(
                        scale, scale,
                        (size.width()  - fAnimationSize.width()  * scale) * 0.5f,
                        (size.height() - fAnimationSize.height() * scale) * 0.5f);
            } else {
                fMatrix = SkMatrix();
            }
            fSize = size;
        }
        canvas->concat(fMatrix);
        SkRect rect = {0, 0, fAnimationSize.width(), fAnimationSize.height()};
        canvas->drawRect(rect, SkPaint(SkColors::kWhite));
        fAnimation->render(canvas);
    }

    void load(const void* data, size_t length) {
        skottie::Animation::Builder builder;
        fAnimation = builder.make((const char*)data, (size_t)length);
        fSize = {0, 0};
        fAnimationSize = fAnimation ? fAnimation->size() : SkSize{0, 0};
    }

    void seek(double time) { if (fAnimation) { fAnimation->seekFrameTime(time, nullptr); } }

    float duration() { return fAnimation ? fAnimation->duration() : 0; }

    SkSize size() { return fAnimationSize; }

private:
    sk_sp<skottie::Animation> fAnimation; // owner
    SkSize fSize;
    SkSize fAnimationSize;
    SkMatrix fMatrix;

    SkAnimationDraw(const SkAnimationDraw&) = delete;
    SkAnimationDraw& operator=(const SkAnimationDraw&) = delete;
};

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

class SkTimeKeeper {
private:
    double fStartTime = 0; // used when running
    float fAnimationMoment = 0; // when paused.
    float fDuration = 0;
    bool fPaused = false;
    bool fStopAtEnd = false;

public:
    void setStopAtEnd(bool s) { fStopAtEnd = s; }

    float currentTime() {
        if (0 == fDuration) {
            return 0;
        }
        if (fPaused) {
            return fAnimationMoment;
        }
        double time = 1e-9 * (SkTime::GetNSecs() - fStartTime);
        if (fStopAtEnd && time >= fDuration) {
            fPaused = true;
            fAnimationMoment = fDuration;
            return fAnimationMoment;
        }
        return std::fmod(time, fDuration);
    }

    void setDuration(float d) {
        fDuration = d;
        fStartTime = SkTime::GetNSecs();
        fAnimationMoment = 0;
    }

    bool paused() const { return fPaused; }

    float duration() const { return fDuration; }

    void seek(float seconds) {
        if (fPaused) {
            fAnimationMoment = std::fmod(seconds, fDuration);
        } else {
            fStartTime = SkTime::GetNSecs() - 1e9 * seconds;
        }
    }

    void togglePaused() {
        if (fPaused) {
            double offset = (fAnimationMoment >= fDuration) ? 0 : -1e9 * fAnimationMoment;
            fStartTime = SkTime::GetNSecs() + offset;
            fPaused = false;
        } else {
            fAnimationMoment = this->currentTime();
            fPaused = true;
        }
    }
};

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

@implementation SkottieViewController {
    SkAnimationDraw fDraw;
    SkTimeKeeper fClock;
}

- (bool)loadAnimation:(NSData*) data {
    fDraw.load((const void*)[data bytes], (size_t)[data length]);
    fClock.setDuration(fDraw.duration());
    return (bool)fDraw;
}

- (void)setStopAtEnd:(bool)stop { fClock.setStopAtEnd(stop); }

- (float)animationDurationSeconds { return fClock.duration(); }

- (float)currentTime { return fDraw ? fClock.currentTime() : 0; }

- (void)seek:(float)seconds {
    if (fDraw) {
        fClock.seek(seconds);
    }
}

- (CGSize)size { return {(CGFloat)fDraw.size().width(), (CGFloat)fDraw.size().height()}; }

- (bool)togglePaused {
    fClock.togglePaused();
    return fClock.paused();
}

- (bool)isPaused { return fClock.paused(); }

- (void)draw:(CGRect)rect toCanvas:(SkCanvas*)canvas atSize:(CGSize)size {
    // TODO(halcanary): Use the rect and the InvalidationController to speed up rendering.
    if (rect.size.width > 0 && rect.size.height > 0 && fDraw && canvas) {
        if (!fClock.paused()) {
            fDraw.seek(fClock.currentTime());
        }
        fDraw.draw(SkSize{(float)size.width, (float)size.height}, canvas);
    }
}

@end
