///
/// JMotionReading.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///

#pragma once

#include <fbjni/fbjni.h>
#include "MotionReading.hpp"

#include "JMotionSensor.hpp"
#include "JMotionVector.hpp"
#include "MotionSensor.hpp"
#include "MotionVector.hpp"
#include <optional>

namespace margelo::nitro::one {

  using namespace facebook;

  /**
   * The C++ JNI bridge between the C++ struct "MotionReading" and the Kotlin data class "MotionReading".
   */
  struct JMotionReading final: public jni::JavaClass<JMotionReading> {
  public:
    static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/one/MotionReading;";

  public:
    /**
     * Convert this Java/Kotlin-based struct to the C++ struct MotionReading by copying all values to C++.
     */
    [[maybe_unused]]
    [[nodiscard]]
    MotionReading toCpp() const {
      static const auto clazz = javaClassStatic();
      static const auto fieldSensor = clazz->getField<JMotionSensor>("sensor");
      jni::local_ref<JMotionSensor> sensor = this->getFieldValue(fieldSensor);
      static const auto fieldTimestampMs = clazz->getField<double>("timestampMs");
      double timestampMs = this->getFieldValue(fieldTimestampMs);
      static const auto fieldValue = clazz->getField<JMotionVector>("value");
      jni::local_ref<JMotionVector> value = this->getFieldValue(fieldValue);
      static const auto fieldGravity = clazz->getField<JMotionVector>("gravity");
      jni::local_ref<JMotionVector> gravity = this->getFieldValue(fieldGravity);
      static const auto fieldUserAcceleration = clazz->getField<JMotionVector>("userAcceleration");
      jni::local_ref<JMotionVector> userAcceleration = this->getFieldValue(fieldUserAcceleration);
      static const auto fieldRotationRate = clazz->getField<JMotionVector>("rotationRate");
      jni::local_ref<JMotionVector> rotationRate = this->getFieldValue(fieldRotationRate);
      static const auto fieldAttitude = clazz->getField<JMotionVector>("attitude");
      jni::local_ref<JMotionVector> attitude = this->getFieldValue(fieldAttitude);
      return MotionReading(
        sensor->toCpp(),
        timestampMs,
        value->toCpp(),
        gravity != nullptr ? std::make_optional(gravity->toCpp()) : std::nullopt,
        userAcceleration != nullptr ? std::make_optional(userAcceleration->toCpp()) : std::nullopt,
        rotationRate != nullptr ? std::make_optional(rotationRate->toCpp()) : std::nullopt,
        attitude != nullptr ? std::make_optional(attitude->toCpp()) : std::nullopt
      );
    }

  public:
    /**
     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
     */
    [[maybe_unused]]
    static jni::local_ref<JMotionReading::javaobject> fromCpp(const MotionReading& value) {
      using JSignature = JMotionReading(jni::alias_ref<JMotionSensor>, double, jni::alias_ref<JMotionVector>, jni::alias_ref<JMotionVector>, jni::alias_ref<JMotionVector>, jni::alias_ref<JMotionVector>, jni::alias_ref<JMotionVector>);
      static const auto clazz = javaClassStatic();
      static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
      return create(
        clazz,
        JMotionSensor::fromCpp(value.sensor),
        value.timestampMs,
        JMotionVector::fromCpp(value.value),
        value.gravity.has_value() ? JMotionVector::fromCpp(value.gravity.value()) : nullptr,
        value.userAcceleration.has_value() ? JMotionVector::fromCpp(value.userAcceleration.value()) : nullptr,
        value.rotationRate.has_value() ? JMotionVector::fromCpp(value.rotationRate.value()) : nullptr,
        value.attitude.has_value() ? JMotionVector::fromCpp(value.attitude.value()) : nullptr
      );
    }
  };

} // namespace margelo::nitro::one
