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

#ifndef Skottie_DEFINED
#define Skottie_DEFINED

#include "include/core/SkFontMgr.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "modules/skottie/include/ExternalLayer.h"
#include "modules/skottie/include/SkottieProperty.h"
#include "modules/skresources/include/SkResources.h"

#include <memory>
#include <vector>

class SkCanvas;
struct SkRect;
class SkStream;

namespace skjson { class ObjectValue; }

namespace sksg {

class InvalidationController;
class Scene;

} // namespace sksg

namespace skottie {

namespace internal { class Animator; }

using ImageAsset = skresources::ImageAsset;
using ResourceProvider = skresources::ResourceProvider;

/**
 * A Logger subclass can be used to receive Animation::Builder parsing errors and warnings.
 */
class SK_API Logger : public SkRefCnt {
public:
    enum class Level {
        kWarning,
        kError,
    };

    virtual void log(Level, const char message[], const char* json = nullptr);
};

// Evaluates AE expressions.
template <class T>
class SK_API ExpressionEvaluator : public SkRefCnt {
public:
    // Evaluate the expression at the current time.
    virtual T evaluate(float t) = 0;
};

/**
 * Creates ExpressionEvaluators to evaluate AE expressions and return the results.
 */
class SK_API ExpressionManager : public SkRefCnt {
public:
    virtual sk_sp<ExpressionEvaluator<float>> createNumberExpressionEvaluator(
        const char expression[]) = 0;

    virtual sk_sp<ExpressionEvaluator<SkString>> createStringExpressionEvaluator(
        const char expression[]) = 0;

    virtual sk_sp<ExpressionEvaluator<std::vector<float>>> createArrayExpressionEvaluator(
        const char expression[]) = 0;
};

/**
 * Interface for receiving AE composition markers at Animation build time.
 */
class SK_API MarkerObserver : public SkRefCnt {
public:
    // t0,t1 are in the Animation::seek() domain.
    virtual void onMarker(const char name[], float t0, float t1) = 0;
};

class SK_API Animation : public SkNVRefCnt<Animation> {
public:
    class SK_API Builder final {
    public:
        enum Flags : uint32_t {
            kDeferImageLoading   = 0x01, // Normally, all static image frames are resolved at
                                         // load time via ImageAsset::getFrame(0).  With this flag,
                                         // frames are only resolved when needed, at seek() time.
            kPreferEmbeddedFonts = 0x02, // Attempt to use the embedded fonts (glyph paths,
                                         // normally used as fallback) over native Skia typefaces.
        };

        explicit Builder(uint32_t flags = 0);
        ~Builder();

        struct Stats {
            float  fTotalLoadTimeMS  = 0, // Total animation instantiation time.
                   fJsonParseTimeMS  = 0, // Time spent building a JSON DOM.
                   fSceneParseTimeMS = 0; // Time spent constructing the animation scene graph.
            size_t fJsonSize         = 0, // Input JSON size.
                   fAnimatorCount    = 0; // Number of dynamically animated properties.
        };

        /**
         * Returns various animation build stats.
         *
         * @return Stats (see above).
         */
        const Stats& getStats() const { return fStats; }

        /**
         * Specify a loader for external resources (images, etc.).
         */
        Builder& setResourceProvider(sk_sp<ResourceProvider>);

        /**
         * Specify a font manager for loading animation fonts.
         */
        Builder& setFontManager(sk_sp<SkFontMgr>);

        /**
         * Specify a PropertyObserver to receive callbacks during parsing.
         *
         * See SkottieProperty.h for more details.
         *
         */
        Builder& setPropertyObserver(sk_sp<PropertyObserver>);

        /**
         * Register a Logger with this builder.
         */
        Builder& setLogger(sk_sp<Logger>);

        /**
         * Register a MarkerObserver with this builder.
         */
        Builder& setMarkerObserver(sk_sp<MarkerObserver>);

        /**
         * Register a precomp layer interceptor.
         * This allows substituting precomp layers with custom/externally managed content.
         */
        Builder& setPrecompInterceptor(sk_sp<PrecompInterceptor>);

        /**
         * Registers an ExpressionManager to evaluate AE expressions.
         * If unspecified, expressions in the animation JSON will be ignored.
         */
        Builder& setExpressionManager(sk_sp<ExpressionManager>);

        /**
         * Animation factories.
         */
        sk_sp<Animation> make(SkStream*);
        sk_sp<Animation> make(const char* data, size_t length);
        sk_sp<Animation> makeFromFile(const char path[]);

    private:
        const uint32_t          fFlags;

        sk_sp<ResourceProvider>   fResourceProvider;
        sk_sp<SkFontMgr>          fFontMgr;
        sk_sp<PropertyObserver>   fPropertyObserver;
        sk_sp<Logger>             fLogger;
        sk_sp<MarkerObserver  >   fMarkerObserver;
        sk_sp<PrecompInterceptor> fPrecompInterceptor;
        sk_sp<ExpressionManager>  fExpressionManager;
        Stats                     fStats;
    };

    /**
     * Animation factories.
     *
     * Use the Builder helper above for more options/control.
     */
    static sk_sp<Animation> Make(const char* data, size_t length);
    static sk_sp<Animation> Make(SkStream*);
    static sk_sp<Animation> MakeFromFile(const char path[]);

    ~Animation();

    enum RenderFlag : uint32_t {
        // When rendering into a known transparent buffer, clients can pass
        // this flag to avoid some unnecessary compositing overhead for
        // animations using layer blend modes.
        kSkipTopLevelIsolation   = 0x01,
        // By default, content is clipped to the intrinsic animation
        // bounds (as determined by its size).  If this flag is set,
        // then the animation can draw outside of the bounds.
        kDisableTopLevelClipping = 0x02,
    };
    using RenderFlags = uint32_t;

    /**
     * Draws the current animation frame.
     *
     * It is undefined behavior to call render() on a newly created Animation
     * before specifying an initial frame via one of the seek() variants.
     *
     * @param canvas   destination canvas
     * @param dst      optional destination rect
     * @param flags    optional RenderFlags
     */
    void render(SkCanvas* canvas, const SkRect* dst = nullptr) const;
    void render(SkCanvas* canvas, const SkRect* dst, RenderFlags) const;

    /**
     * [Deprecated: use one of the other versions.]
     *
     * Updates the animation state for |t|.
     *
     * @param t   normalized [0..1] frame selector (0 -> first frame, 1 -> final frame)
     * @param ic  optional invalidation controller (dirty region tracking)
     *
     */
    void seek(SkScalar t, sksg::InvalidationController* ic = nullptr) {
        this->seekFrameTime(t * this->duration(), ic);
    }

    /**
     * Update the animation state to match |t|, specified as a frame index
     * i.e. relative to duration() * fps().
     *
     * Fractional values are allowed and meaningful - e.g.
     *
     *   0.0 -> first frame
     *   1.0 -> second frame
     *   0.5 -> halfway between first and second frame
     */
    void seekFrame(double t, sksg::InvalidationController* ic = nullptr);

    /** Update the animation state to match t, specifed in frame time
     *  i.e. relative to duration().
     */
    void seekFrameTime(double t, sksg::InvalidationController* = nullptr);

    /**
     * Returns the animation duration in seconds.
     */
    double duration() const { return fDuration; }

    /**
     * Returns the animation frame rate (frames / second).
     */
    double fps() const { return fFPS; }

    /**
     * Animation in point, in frame index units.
     */
    double inPoint()  const { return fInPoint;  }

    /**
     * Animation out point, in frame index units.
     */
    double outPoint() const { return fOutPoint; }

    const SkString& version() const { return fVersion; }
    const SkSize&      size() const { return fSize;    }

private:
    enum Flags : uint32_t {
        kRequiresTopLevelIsolation = 1 << 0, // Needs to draw into a layer due to layer blending.
    };

    Animation(std::unique_ptr<sksg::Scene>,
              std::vector<sk_sp<internal::Animator>>&&,
              SkString ver, const SkSize& size,
              double inPoint, double outPoint, double duration, double fps, uint32_t flags);

    const std::unique_ptr<sksg::Scene>           fScene;
    const std::vector<sk_sp<internal::Animator>> fAnimators;
    const SkString                               fVersion;
    const SkSize                                 fSize;
    const double                                 fInPoint,
                                                 fOutPoint,
                                                 fDuration,
                                                 fFPS;
    const uint32_t                               fFlags;

    using INHERITED = SkNVRefCnt<Animation>;
};

} // namespace skottie

#endif // Skottie_DEFINED
