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

#include "JHybridFrameSpec.hpp"

// Forward declaration of `PixelFormat` to properly resolve imports.
namespace margelo::nitro::camera { enum class PixelFormat; }
// Forward declaration of `CameraOrientation` to properly resolve imports.
namespace margelo::nitro::camera { enum class CameraOrientation; }
// Forward declaration of `HybridFramePlaneSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridFramePlaneSpec; }
// Forward declaration of `NativeBuffer` to properly resolve imports.
namespace margelo::nitro::camera { struct NativeBuffer; }
// Forward declaration of `Point` to properly resolve imports.
namespace margelo::nitro::camera { struct Point; }

#include "PixelFormat.hpp"
#include "JPixelFormat.hpp"
#include "CameraOrientation.hpp"
#include "JCameraOrientation.hpp"
#include <vector>
#include <optional>
#include <memory>
#include "HybridFramePlaneSpec.hpp"
#include "JHybridFramePlaneSpec.hpp"
#include <NitroModules/ArrayBuffer.hpp>
#include <NitroModules/JArrayBuffer.hpp>
#include "NativeBuffer.hpp"
#include "JNativeBuffer.hpp"
#include <functional>
#include "JFunc_void.hpp"
#include <NitroModules/JNICallable.hpp>
#include "Point.hpp"
#include "JPoint.hpp"

namespace margelo::nitro::camera {

  std::shared_ptr<JHybridFrameSpec> JHybridFrameSpec::JavaPart::getJHybridFrameSpec() {
    auto hybridObject = JHybridObject::JavaPart::getJHybridObject();
    auto castHybridObject = std::dynamic_pointer_cast<JHybridFrameSpec>(hybridObject);
    if (castHybridObject == nullptr) [[unlikely]] {
      throw std::runtime_error("Failed to downcast JHybridObject to JHybridFrameSpec!");
    }
    return castHybridObject;
  }

  jni::local_ref<JHybridFrameSpec::CxxPart::jhybriddata> JHybridFrameSpec::CxxPart::initHybrid(jni::alias_ref<jhybridobject> jThis) {
    return makeCxxInstance(jThis);
  }

  std::shared_ptr<JHybridObject> JHybridFrameSpec::CxxPart::createHybridObject(const jni::local_ref<JHybridObject::JavaPart>& javaPart) {
    auto castJavaPart = jni::dynamic_ref_cast<JHybridFrameSpec::JavaPart>(javaPart);
    if (castJavaPart == nullptr) [[unlikely]] {
      throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridFrameSpec::JavaPart!");
    }
    return std::make_shared<JHybridFrameSpec>(castJavaPart);
  }

  void JHybridFrameSpec::CxxPart::registerNatives() {
    registerHybrid({
      makeNativeMethod("initHybrid", JHybridFrameSpec::CxxPart::initHybrid),
    });
  }

  // Properties
  double JHybridFrameSpec::getTimestamp() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double()>("getTimestamp");
    auto __result = method(_javaPart);
    return __result;
  }
  bool JHybridFrameSpec::getIsValid() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isValid");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  double JHybridFrameSpec::getWidth() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double()>("getWidth");
    auto __result = method(_javaPart);
    return __result;
  }
  double JHybridFrameSpec::getHeight() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double()>("getHeight");
    auto __result = method(_javaPart);
    return __result;
  }
  double JHybridFrameSpec::getBytesPerRow() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double()>("getBytesPerRow");
    auto __result = method(_javaPart);
    return __result;
  }
  PixelFormat JHybridFrameSpec::getPixelFormat() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPixelFormat>()>("getPixelFormat");
    auto __result = method(_javaPart);
    return __result->toCpp();
  }
  CameraOrientation JHybridFrameSpec::getOrientation() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JCameraOrientation>()>("getOrientation");
    auto __result = method(_javaPart);
    return __result->toCpp();
  }
  bool JHybridFrameSpec::getIsMirrored() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isMirrored");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  bool JHybridFrameSpec::getIsPlanar() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isPlanar");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  bool JHybridFrameSpec::getHasPixelBuffer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("getHasPixelBuffer");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  bool JHybridFrameSpec::getHasNativeBuffer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("getHasNativeBuffer");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  std::optional<std::vector<double>> JHybridFrameSpec::getCameraIntrinsicMatrix() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayDouble>()>("getCameraIntrinsicMatrix");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional([&]() {
      size_t __size = __result->size();
      std::vector<double> __vector(__size);
      __result->getRegion(0, __size, __vector.data());
      return __vector;
    }()) : std::nullopt;
  }

  // Methods
  std::vector<std::shared_ptr<HybridFramePlaneSpec>> JHybridFrameSpec::getPlanes() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JHybridFramePlaneSpec::JavaPart>>()>("getPlanes");
    auto __result = method(_javaPart);
    return [&](auto&& __input) {
      size_t __size = __input->size();
      std::vector<std::shared_ptr<HybridFramePlaneSpec>> __vector;
      __vector.reserve(__size);
      for (size_t __i = 0; __i < __size; __i++) {
        auto __element = __input->getElement(__i);
        __vector.push_back(__element->getJHybridFramePlaneSpec());
      }
      return __vector;
    }(__result);
  }
  std::shared_ptr<ArrayBuffer> JHybridFrameSpec::getPixelBuffer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JArrayBuffer::javaobject>()>("getPixelBuffer");
    auto __result = method(_javaPart);
    return __result->cthis()->getArrayBuffer();
  }
  NativeBuffer JHybridFrameSpec::getNativeBuffer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JNativeBuffer>()>("getNativeBuffer");
    auto __result = method(_javaPart);
    return __result->toCpp();
  }
  Point JHybridFrameSpec::convertCameraPointToFramePoint(const Point& cameraPoint) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPoint>(jni::alias_ref<JPoint> /* cameraPoint */)>("convertCameraPointToFramePoint");
    auto __result = method(_javaPart, JPoint::fromCpp(cameraPoint));
    return __result->toCpp();
  }
  Point JHybridFrameSpec::convertFramePointToCameraPoint(const Point& framePoint) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPoint>(jni::alias_ref<JPoint> /* framePoint */)>("convertFramePointToCameraPoint");
    auto __result = method(_javaPart, JPoint::fromCpp(framePoint));
    return __result->toCpp();
  }

} // namespace margelo::nitro::camera
