/**
 * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
 *
 * Do not edit this file as changes may cause incorrect behavior and will be lost
 * once the code is regenerated.
 *
 * @generated by codegen project: GenerateModuleH.js
 */

#pragma once

#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>

namespace facebook::react {


  
#pragma mark - NativeSpeechEventProps

template <typename P0>
struct NativeSpeechEventProps {
  P0 id;
  bool operator==(const NativeSpeechEventProps &other) const {
    return id == other.id;
  }
};

template <typename T>
struct NativeSpeechEventPropsBridging {
  static T types;

  static T fromJs(
      jsi::Runtime &rt,
      const jsi::Object &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    T result{
      bridging::fromJs<decltype(types.id)>(rt, value.getProperty(rt, "id"), jsInvoker)};
    return result;
  }

#ifdef DEBUG
  static double idToJs(jsi::Runtime &rt, decltype(types.id) value) {
    return bridging::toJs(rt, value);
  }
#endif

  static jsi::Object toJs(
      jsi::Runtime &rt,
      const T &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    auto result = facebook::jsi::Object(rt);
    result.setProperty(rt, "id", bridging::toJs(rt, value.id, jsInvoker));
    return result;
  }
};



#pragma mark - NativeSpeechProgressEventProps

template <typename P0, typename P1, typename P2>
struct NativeSpeechProgressEventProps {
  P0 id;
  P1 length;
  P2 location;
  bool operator==(const NativeSpeechProgressEventProps &other) const {
    return id == other.id && length == other.length && location == other.location;
  }
};

template <typename T>
struct NativeSpeechProgressEventPropsBridging {
  static T types;

  static T fromJs(
      jsi::Runtime &rt,
      const jsi::Object &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    T result{
      bridging::fromJs<decltype(types.id)>(rt, value.getProperty(rt, "id"), jsInvoker),
      bridging::fromJs<decltype(types.length)>(rt, value.getProperty(rt, "length"), jsInvoker),
      bridging::fromJs<decltype(types.location)>(rt, value.getProperty(rt, "location"), jsInvoker)};
    return result;
  }

#ifdef DEBUG
  static double idToJs(jsi::Runtime &rt, decltype(types.id) value) {
    return bridging::toJs(rt, value);
  }

  static double lengthToJs(jsi::Runtime &rt, decltype(types.length) value) {
    return bridging::toJs(rt, value);
  }

  static double locationToJs(jsi::Runtime &rt, decltype(types.location) value) {
    return bridging::toJs(rt, value);
  }
#endif

  static jsi::Object toJs(
      jsi::Runtime &rt,
      const T &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    auto result = facebook::jsi::Object(rt);
    result.setProperty(rt, "id", bridging::toJs(rt, value.id, jsInvoker));
    result.setProperty(rt, "length", bridging::toJs(rt, value.length, jsInvoker));
    result.setProperty(rt, "location", bridging::toJs(rt, value.location, jsInvoker));
    return result;
  }
};



#pragma mark - NativeSpeechVoiceOptions

template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct NativeSpeechVoiceOptions {
  P0 language;
  P1 volume;
  P2 voice;
  P3 pitch;
  P4 rate;
  bool operator==(const NativeSpeechVoiceOptions &other) const {
    return language == other.language && volume == other.volume && voice == other.voice && pitch == other.pitch && rate == other.rate;
  }
};

template <typename T>
struct NativeSpeechVoiceOptionsBridging {
  static T types;

  static T fromJs(
      jsi::Runtime &rt,
      const jsi::Object &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    T result{
      bridging::fromJs<decltype(types.language)>(rt, value.getProperty(rt, "language"), jsInvoker),
      bridging::fromJs<decltype(types.volume)>(rt, value.getProperty(rt, "volume"), jsInvoker),
      bridging::fromJs<decltype(types.voice)>(rt, value.getProperty(rt, "voice"), jsInvoker),
      bridging::fromJs<decltype(types.pitch)>(rt, value.getProperty(rt, "pitch"), jsInvoker),
      bridging::fromJs<decltype(types.rate)>(rt, value.getProperty(rt, "rate"), jsInvoker)};
    return result;
  }

#ifdef DEBUG
  static jsi::String languageToJs(jsi::Runtime &rt, decltype(types.language) value) {
    return bridging::toJs(rt, value);
  }

  static double volumeToJs(jsi::Runtime &rt, decltype(types.volume) value) {
    return bridging::toJs(rt, value);
  }

  static jsi::String voiceToJs(jsi::Runtime &rt, decltype(types.voice) value) {
    return bridging::toJs(rt, value);
  }

  static double pitchToJs(jsi::Runtime &rt, decltype(types.pitch) value) {
    return bridging::toJs(rt, value);
  }

  static double rateToJs(jsi::Runtime &rt, decltype(types.rate) value) {
    return bridging::toJs(rt, value);
  }
#endif

  static jsi::Object toJs(
      jsi::Runtime &rt,
      const T &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    auto result = facebook::jsi::Object(rt);
    if (value.language) {
      result.setProperty(rt, "language", bridging::toJs(rt, value.language.value(), jsInvoker));
    }
    if (value.volume) {
      result.setProperty(rt, "volume", bridging::toJs(rt, value.volume.value(), jsInvoker));
    }
    if (value.voice) {
      result.setProperty(rt, "voice", bridging::toJs(rt, value.voice.value(), jsInvoker));
    }
    if (value.pitch) {
      result.setProperty(rt, "pitch", bridging::toJs(rt, value.pitch.value(), jsInvoker));
    }
    if (value.rate) {
      result.setProperty(rt, "rate", bridging::toJs(rt, value.rate.value(), jsInvoker));
    }
    return result;
  }
};



#pragma mark - NativeSpeechVoiceProps

template <typename P0, typename P1, typename P2, typename P3>
struct NativeSpeechVoiceProps {
  P0 name;
  P1 quality;
  P2 language;
  P3 identifier;
  bool operator==(const NativeSpeechVoiceProps &other) const {
    return name == other.name && quality == other.quality && language == other.language && identifier == other.identifier;
  }
};

template <typename T>
struct NativeSpeechVoicePropsBridging {
  static T types;

  static T fromJs(
      jsi::Runtime &rt,
      const jsi::Object &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    T result{
      bridging::fromJs<decltype(types.name)>(rt, value.getProperty(rt, "name"), jsInvoker),
      bridging::fromJs<decltype(types.quality)>(rt, value.getProperty(rt, "quality"), jsInvoker),
      bridging::fromJs<decltype(types.language)>(rt, value.getProperty(rt, "language"), jsInvoker),
      bridging::fromJs<decltype(types.identifier)>(rt, value.getProperty(rt, "identifier"), jsInvoker)};
    return result;
  }

#ifdef DEBUG
  static jsi::String nameToJs(jsi::Runtime &rt, decltype(types.name) value) {
    return bridging::toJs(rt, value);
  }

  static jsi::String qualityToJs(jsi::Runtime &rt, decltype(types.quality) value) {
    return bridging::toJs(rt, value);
  }

  static jsi::String languageToJs(jsi::Runtime &rt, decltype(types.language) value) {
    return bridging::toJs(rt, value);
  }

  static jsi::String identifierToJs(jsi::Runtime &rt, decltype(types.identifier) value) {
    return bridging::toJs(rt, value);
  }
#endif

  static jsi::Object toJs(
      jsi::Runtime &rt,
      const T &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    auto result = facebook::jsi::Object(rt);
    result.setProperty(rt, "name", bridging::toJs(rt, value.name, jsInvoker));
    result.setProperty(rt, "quality", bridging::toJs(rt, value.quality, jsInvoker));
    result.setProperty(rt, "language", bridging::toJs(rt, value.language, jsInvoker));
    result.setProperty(rt, "identifier", bridging::toJs(rt, value.identifier, jsInvoker));
    return result;
  }
};

class JSI_EXPORT NativeSpeechCxxSpecJSI : public TurboModule {
protected:
  NativeSpeechCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);

public:
  virtual void reset(jsi::Runtime &rt) = 0;
  virtual jsi::Value stop(jsi::Runtime &rt) = 0;
  virtual jsi::Value pause(jsi::Runtime &rt) = 0;
  virtual jsi::Value resume(jsi::Runtime &rt) = 0;
  virtual jsi::Value isSpeaking(jsi::Runtime &rt) = 0;
  virtual jsi::Value speak(jsi::Runtime &rt, jsi::String text) = 0;
  virtual void initialize(jsi::Runtime &rt, jsi::Object options) = 0;
  virtual jsi::Value getAvailableVoices(jsi::Runtime &rt, jsi::String language) = 0;
  virtual jsi::Value speakWithOptions(jsi::Runtime &rt, jsi::String text, jsi::Object options) = 0;

};

template <typename T>
class JSI_EXPORT NativeSpeechCxxSpec : public TurboModule {
public:
  jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
    return delegate_.create(rt, propName);
  }

  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override {
    return delegate_.getPropertyNames(runtime);
  }

  static constexpr std::string_view kModuleName = "Speech";

protected:
  NativeSpeechCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
    : TurboModule(std::string{NativeSpeechCxxSpec::kModuleName}, jsInvoker),
      delegate_(reinterpret_cast<T*>(this), jsInvoker) {}

  template <typename OnErrorType> void emitOnError(OnErrorType value) {
    static_assert(bridging::supportsFromJs<OnErrorType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onError"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

  template <typename OnStartType> void emitOnStart(OnStartType value) {
    static_assert(bridging::supportsFromJs<OnStartType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onStart"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

  template <typename OnFinishType> void emitOnFinish(OnFinishType value) {
    static_assert(bridging::supportsFromJs<OnFinishType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onFinish"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

  template <typename OnPauseType> void emitOnPause(OnPauseType value) {
    static_assert(bridging::supportsFromJs<OnPauseType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onPause"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

  template <typename OnResumeType> void emitOnResume(OnResumeType value) {
    static_assert(bridging::supportsFromJs<OnResumeType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onResume"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

  template <typename OnStoppedType> void emitOnStopped(OnStoppedType value) {
    static_assert(bridging::supportsFromJs<OnStoppedType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onStopped"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

  template <typename OnProgressType> void emitOnProgress(OnProgressType value) {
    static_assert(bridging::supportsFromJs<OnProgressType, jsi::Object>, "value cannnot be converted to jsi::Object");
    static_cast<AsyncEventEmitter<jsi::Value>&>(*delegate_.eventEmitterMap_["onProgress"]).emit([jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value {
      return bridging::toJs(rt, eventValue, jsInvoker);
    });
  }

private:
  class Delegate : public NativeSpeechCxxSpecJSI {
  public:
    Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
      NativeSpeechCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {
      eventEmitterMap_["onError"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
      eventEmitterMap_["onStart"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
      eventEmitterMap_["onFinish"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
      eventEmitterMap_["onPause"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
      eventEmitterMap_["onResume"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
      eventEmitterMap_["onStopped"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
      eventEmitterMap_["onProgress"] = std::make_shared<AsyncEventEmitter<jsi::Value>>();
    }

    void reset(jsi::Runtime &rt) override {
      static_assert(
          bridging::getParameterCount(&T::reset) == 1,
          "Expected reset(...) to have 1 parameters");

      return bridging::callFromJs<void>(
          rt, &T::reset, jsInvoker_, instance_);
    }
    jsi::Value stop(jsi::Runtime &rt) override {
      static_assert(
          bridging::getParameterCount(&T::stop) == 1,
          "Expected stop(...) to have 1 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::stop, jsInvoker_, instance_);
    }
    jsi::Value pause(jsi::Runtime &rt) override {
      static_assert(
          bridging::getParameterCount(&T::pause) == 1,
          "Expected pause(...) to have 1 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::pause, jsInvoker_, instance_);
    }
    jsi::Value resume(jsi::Runtime &rt) override {
      static_assert(
          bridging::getParameterCount(&T::resume) == 1,
          "Expected resume(...) to have 1 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::resume, jsInvoker_, instance_);
    }
    jsi::Value isSpeaking(jsi::Runtime &rt) override {
      static_assert(
          bridging::getParameterCount(&T::isSpeaking) == 1,
          "Expected isSpeaking(...) to have 1 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::isSpeaking, jsInvoker_, instance_);
    }
    jsi::Value speak(jsi::Runtime &rt, jsi::String text) override {
      static_assert(
          bridging::getParameterCount(&T::speak) == 2,
          "Expected speak(...) to have 2 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::speak, jsInvoker_, instance_, std::move(text));
    }
    void initialize(jsi::Runtime &rt, jsi::Object options) override {
      static_assert(
          bridging::getParameterCount(&T::initialize) == 2,
          "Expected initialize(...) to have 2 parameters");

      return bridging::callFromJs<void>(
          rt, &T::initialize, jsInvoker_, instance_, std::move(options));
    }
    jsi::Value getAvailableVoices(jsi::Runtime &rt, jsi::String language) override {
      static_assert(
          bridging::getParameterCount(&T::getAvailableVoices) == 2,
          "Expected getAvailableVoices(...) to have 2 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::getAvailableVoices, jsInvoker_, instance_, std::move(language));
    }
    jsi::Value speakWithOptions(jsi::Runtime &rt, jsi::String text, jsi::Object options) override {
      static_assert(
          bridging::getParameterCount(&T::speakWithOptions) == 3,
          "Expected speakWithOptions(...) to have 3 parameters");

      return bridging::callFromJs<jsi::Value>(
          rt, &T::speakWithOptions, jsInvoker_, instance_, std::move(text), std::move(options));
    }

  private:
    friend class NativeSpeechCxxSpec;
    T *instance_;
  };

  Delegate delegate_;
};

} // namespace facebook::react
