#ifndef _RIVE_NODE_BASE_HPP_
#define _RIVE_NODE_BASE_HPP_
#include "rive/core/field_types/core_double_type.hpp"
#include "rive/transform_component.hpp"
#ifdef WITH_RIVE_EDITOR
#include "editor_native/generated/editor_field_types.hpp"
#endif
namespace rive
{
class NodeBase : public TransformComponent
{
protected:
  typedef TransformComponent Super;

public:
  static const uint16_t typeKey = 2;

  uint16_t coreType() const override { return typeKey; }

  static const uint16_t xPropertyKey = 13;
  static const uint16_t xArtboardPropertyKey = 9;
  static const uint16_t yPropertyKey = 14;
  static const uint16_t yArtboardPropertyKey = 10;
  static const uint16_t computedLocalXPropertyKey = 806;
  static const uint16_t computedLocalYPropertyKey = 807;
  static const uint16_t computedWorldXPropertyKey = 808;
  static const uint16_t computedWorldYPropertyKey = 809;
  static const uint16_t computedRootXPropertyKey = 864;
  static const uint16_t computedRootYPropertyKey = 865;
  static const uint16_t computedWidthPropertyKey = 810;
  static const uint16_t computedHeightPropertyKey = 811;

protected:
  float m_X = 0.0f;
  float m_Y = 0.0f;

public:
  inline float x() const override { return m_X; }
  void x(float value)
  {
    if (m_X == value)
    {
      return;
    }
    RIVE_EDITOR_CHANGING(xPropertyKey, &m_X, &value);
    m_X = value;
    RIVE_EDITOR_CHANGED(xChanged());
    notifyPropertyChanged(xPropertyKey);
  }

  inline float y() const override { return m_Y; }
  void y(float value)
  {
    if (m_Y == value)
    {
      return;
    }
    RIVE_EDITOR_CHANGING(yPropertyKey, &m_Y, &value);
    m_Y = value;
    RIVE_EDITOR_CHANGED(yChanged());
    notifyPropertyChanged(yPropertyKey);
  }

  virtual void setComputedLocalX(float value) = 0;
  virtual float computedLocalX() = 0;
  void computedLocalX(float value)
  {
    if (computedLocalX() == value)
    {
      return;
    }
    setComputedLocalX(value);
    computedLocalXChanged();
    notifyPropertyChanged(computedLocalXPropertyKey);
  }

  virtual void setComputedLocalY(float value) = 0;
  virtual float computedLocalY() = 0;
  void computedLocalY(float value)
  {
    if (computedLocalY() == value)
    {
      return;
    }
    setComputedLocalY(value);
    computedLocalYChanged();
    notifyPropertyChanged(computedLocalYPropertyKey);
  }

  virtual void setComputedWorldX(float value) = 0;
  virtual float computedWorldX() = 0;
  void computedWorldX(float value)
  {
    if (computedWorldX() == value)
    {
      return;
    }
    setComputedWorldX(value);
    computedWorldXChanged();
    notifyPropertyChanged(computedWorldXPropertyKey);
  }

  virtual void setComputedWorldY(float value) = 0;
  virtual float computedWorldY() = 0;
  void computedWorldY(float value)
  {
    if (computedWorldY() == value)
    {
      return;
    }
    setComputedWorldY(value);
    computedWorldYChanged();
    notifyPropertyChanged(computedWorldYPropertyKey);
  }

  virtual void setComputedRootX(float value) = 0;
  virtual float computedRootX() = 0;
  void computedRootX(float value)
  {
    if (computedRootX() == value)
    {
      return;
    }
    setComputedRootX(value);
    computedRootXChanged();
    notifyPropertyChanged(computedRootXPropertyKey);
  }

  virtual void setComputedRootY(float value) = 0;
  virtual float computedRootY() = 0;
  void computedRootY(float value)
  {
    if (computedRootY() == value)
    {
      return;
    }
    setComputedRootY(value);
    computedRootYChanged();
    notifyPropertyChanged(computedRootYPropertyKey);
  }

  virtual void setComputedWidth(float value) = 0;
  virtual float computedWidth() = 0;
  void computedWidth(float value)
  {
    if (computedWidth() == value)
    {
      return;
    }
    setComputedWidth(value);
    computedWidthChanged();
    notifyPropertyChanged(computedWidthPropertyKey);
  }

  virtual void setComputedHeight(float value) = 0;
  virtual float computedHeight() = 0;
  void computedHeight(float value)
  {
    if (computedHeight() == value)
    {
      return;
    }
    setComputedHeight(value);
    computedHeightChanged();
    notifyPropertyChanged(computedHeightPropertyKey);
  }

  Core* clone() const override;
  void copy(const NodeBase& object)
  {
    m_X = object.m_X;
    m_Y = object.m_Y;
    RIVE_EDITOR_COPY(object);
    TransformComponent::copy(object);
  }

  bool deserialize(uint16_t propertyKey, BinaryReader& reader) override
  {
    switch (propertyKey)
    {
      case xPropertyKey:
        m_X = CoreDoubleType::deserialize(reader);
        return true;
      case yPropertyKey:
        m_Y = CoreDoubleType::deserialize(reader);
        return true;
    }
    RIVE_EDITOR_DESERIALIZE(propertyKey, reader);
    return TransformComponent::deserialize(propertyKey, reader);
  }

protected:
  virtual void xChanged() {}
  virtual void yChanged() {}
  virtual void computedLocalXChanged() {}
  virtual void computedLocalYChanged() {}
  virtual void computedWorldXChanged() {}
  virtual void computedWorldYChanged() {}
  virtual void computedRootXChanged() {}
  virtual void computedRootYChanged() {}
  virtual void computedWidthChanged() {}
  virtual void computedHeightChanged() {}
#ifdef WITH_RIVE_EDITOR
#include "editor_native/generated/node_ext.inl"
#endif
};
} // namespace rive

#endif