/*
 * 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/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;
    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;
    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
