#pragma once

#include "DerivedNodeProp.h"

#include <memory>
#include <string>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdocumentation"

#include "include/core/SkPaint.h"

#pragma clang diagnostic pop

namespace RNSkia {

class StrokeCapProp : public DerivedProp<SkPaint::Cap> {
public:
  explicit StrokeCapProp(PropId name,
                         const std::function<void(BaseNodeProp *)> &onChange)
      : DerivedProp<SkPaint::Cap>(onChange) {
    _strokeCap = defineProperty<NodeProp>(name);
  }

  void updateDerivedValue() override {
    if (_strokeCap->isSet() && (_strokeCap->isChanged())) {
      auto capValue = _strokeCap->value().getAsString();
      setDerivedValue(getCapFromString(capValue));
    }
  }

  static SkPaint::Cap getCapFromString(const std::string &value) {
    if (value == "round") {
      return SkPaint::Cap::kRound_Cap;
    } else if (value == "butt") {
      return SkPaint::Cap::kButt_Cap;
    } else if (value == "square") {
      return SkPaint::Cap::kSquare_Cap;
    }
    throw std::runtime_error("Property value \"" + value +
                             "\" is not a legal stroke cap.");
  }

private:
  NodeProp *_strokeCap;
};

class StrokeJoinProp : public DerivedProp<SkPaint::Join> {
public:
  explicit StrokeJoinProp(PropId name,
                          const std::function<void(BaseNodeProp *)> &onChange)
      : DerivedProp<SkPaint::Join>(onChange) {
    _strokeJoin = defineProperty<NodeProp>(name);
  }

  void updateDerivedValue() override {
    if (_strokeJoin->isSet() && (_strokeJoin->isChanged())) {
      auto joinValue = _strokeJoin->value().getAsString();
      setDerivedValue(getJoinFromString(joinValue));
    }
  }

  static SkPaint::Join getJoinFromString(const std::string &value) {
    if (value == "miter") {
      return SkPaint::Join::kMiter_Join;
    } else if (value == "round") {
      return SkPaint::Join::kRound_Join;
    } else if (value == "bevel") {
      return SkPaint::Join::kBevel_Join;
    }
    throw std::runtime_error("Property value \"" + value +
                             "\" is not a legal stroke join.");
  }

private:
  NodeProp *_strokeJoin;
};

} // namespace RNSkia
