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

#ifndef SkottieProperty_DEFINED
#define SkottieProperty_DEFINED

#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkTypeface.h"
#include "include/utils/SkTextUtils.h"
#include "modules/skottie/src/text/SkottieShaper.h"

#include <functional>

class SkMatrix;

namespace sksg {

class Color;
class OpacityEffect;

} // namespace sksg

namespace skottie {

using ColorPropertyValue   = SkColor;
using OpacityPropertyValue = float;

enum class TextPaintOrder : uint8_t {
    kFillStroke,
    kStrokeFill,
};

struct TextPropertyValue {
    sk_sp<SkTypeface>       fTypeface;
    SkString                fText;
    float                   fTextSize       = 0,
                            fMinTextSize    = 0,                                 // when auto-sizing
                            fMaxTextSize    = std::numeric_limits<float>::max(), // when auto-sizing
                            fStrokeWidth    = 0,
                            fLineHeight     = 0,
                            fLineShift      = 0,
                            fAscent         = 0;
    size_t                  fMaxLines       = 0;                                 // when auto-sizing
    SkTextUtils::Align      fHAlign         = SkTextUtils::kLeft_Align;
    Shaper::VAlign          fVAlign         = Shaper::VAlign::kTop;
    Shaper::ResizePolicy    fResize         = Shaper::ResizePolicy::kNone;
    Shaper::LinebreakPolicy fLineBreak      = Shaper::LinebreakPolicy::kExplicit;
    Shaper::Direction       fDirection      = Shaper::Direction::kLTR;
    Shaper::Capitalization  fCapitalization = Shaper::Capitalization::kNone;
    SkRect                  fBox            = SkRect::MakeEmpty();
    SkColor                 fFillColor      = SK_ColorTRANSPARENT,
                            fStrokeColor    = SK_ColorTRANSPARENT;
    TextPaintOrder          fPaintOrder     = TextPaintOrder::kFillStroke;
    SkPaint::Join           fStrokeJoin     = SkPaint::Join::kMiter_Join;
    bool                    fHasFill        = false,
                            fHasStroke      = false;

    bool operator==(const TextPropertyValue& other) const;
    bool operator!=(const TextPropertyValue& other) const;
};

struct TransformPropertyValue {
    SkPoint  fAnchorPoint,
             fPosition;
    SkVector fScale;
    SkScalar fRotation,
             fSkew,
             fSkewAxis;

    bool operator==(const TransformPropertyValue& other) const;
    bool operator!=(const TransformPropertyValue& other) const;
};

namespace internal { class AnimationBuilder; }

/**
 * Property handles are adapters between user-facing AE model/values
 * and the internal scene-graph representation.
 */
template <typename ValueT, typename NodeT>
class SK_API PropertyHandle final {
public:
    explicit PropertyHandle(sk_sp<NodeT> node) : fNode(std::move(node)) {}
    ~PropertyHandle();

    ValueT get() const;
    void set(const ValueT&);

private:
    const sk_sp<NodeT> fNode;
};

namespace internal {

class TextAdapter;
class TransformAdapter2D;

} // namespace internal

using ColorPropertyHandle     = PropertyHandle<ColorPropertyValue,
                                               sksg::Color>;
using OpacityPropertyHandle   = PropertyHandle<OpacityPropertyValue,
                                               sksg::OpacityEffect>;
using TextPropertyHandle      = PropertyHandle<TextPropertyValue,
                                               internal::TextAdapter>;
using TransformPropertyHandle = PropertyHandle<TransformPropertyValue,
                                               internal::TransformAdapter2D>;

/**
 * A PropertyObserver can be used to track and manipulate certain properties of "interesting"
 * Lottie nodes.
 *
 * When registered with an animation builder, PropertyObserver receives notifications for
 * various properties of layer and shape nodes.  The |node_name| argument corresponds to the
 * name ("nm") node property.
 */
class SK_API PropertyObserver : public SkRefCnt {
public:
    enum class NodeType {COMPOSITION, LAYER, EFFECT, OTHER};

    template <typename T>
    using LazyHandle = std::function<std::unique_ptr<T>()>;

    virtual void onColorProperty    (const char node_name[],
                                     const LazyHandle<ColorPropertyHandle>&);
    virtual void onOpacityProperty  (const char node_name[],
                                     const LazyHandle<OpacityPropertyHandle>&);
    virtual void onTextProperty     (const char node_name[],
                                     const LazyHandle<TextPropertyHandle>&);
    virtual void onTransformProperty(const char node_name[],
                                     const LazyHandle<TransformPropertyHandle>&);
    virtual void onEnterNode(const char node_name[], NodeType node_type);
    virtual void onLeavingNode(const char node_name[], NodeType node_type);
};

} // namespace skottie

#endif // SkottieProperty_DEFINED
