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

#pragma once

#if __has_include(<NitroModules/HybridObject.hpp>)
#include <NitroModules/HybridObject.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif

// Forward declaration of `PermissionStatus` to properly resolve imports.
namespace margelo::nitro::camera { enum class PermissionStatus; }
// Forward declaration of `HybridCameraSessionSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraSessionSpec; }
// Forward declaration of `HybridCameraSessionConfigSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraSessionConfigSpec; }
// Forward declaration of `HybridCameraDeviceSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraDeviceSpec; }
// Forward declaration of `CameraOutputConfiguration` to properly resolve imports.
namespace margelo::nitro::camera { struct CameraOutputConfiguration; }
// Forward declaration of `FPSConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct FPSConstraint; }
// Forward declaration of `VideoStabilizationModeConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct VideoStabilizationModeConstraint; }
// Forward declaration of `PreviewStabilizationModeConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct PreviewStabilizationModeConstraint; }
// Forward declaration of `ResolutionBiasConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct ResolutionBiasConstraint; }
// Forward declaration of `VideoDynamicRangeConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct VideoDynamicRangeConstraint; }
// Forward declaration of `PhotoHDRConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct PhotoHDRConstraint; }
// Forward declaration of `PixelFormatConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct PixelFormatConstraint; }
// Forward declaration of `BinnedConstraint` to properly resolve imports.
namespace margelo::nitro::camera { struct BinnedConstraint; }
// Forward declaration of `HybridCameraDeviceFactorySpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraDeviceFactorySpec; }
// Forward declaration of `HybridCameraPhotoOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraPhotoOutputSpec; }
// Forward declaration of `PhotoOutputOptions` to properly resolve imports.
namespace margelo::nitro::camera { struct PhotoOutputOptions; }
// Forward declaration of `HybridCameraVideoOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraVideoOutputSpec; }
// Forward declaration of `VideoOutputOptions` to properly resolve imports.
namespace margelo::nitro::camera { struct VideoOutputOptions; }
// Forward declaration of `HybridCameraFrameOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraFrameOutputSpec; }
// Forward declaration of `FrameOutputOptions` to properly resolve imports.
namespace margelo::nitro::camera { struct FrameOutputOptions; }
// Forward declaration of `HybridCameraDepthFrameOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraDepthFrameOutputSpec; }
// Forward declaration of `DepthFrameOutputOptions` to properly resolve imports.
namespace margelo::nitro::camera { struct DepthFrameOutputOptions; }
// Forward declaration of `HybridCameraPreviewOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraPreviewOutputSpec; }
// Forward declaration of `HybridCameraObjectOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraObjectOutputSpec; }
// Forward declaration of `ObjectOutputOptions` to properly resolve imports.
namespace margelo::nitro::camera { struct ObjectOutputOptions; }
// Forward declaration of `HybridCameraOutputSynchronizerSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraOutputSynchronizerSpec; }
// Forward declaration of `HybridCameraOutputSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridCameraOutputSpec; }
// Forward declaration of `HybridZoomGestureControllerSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridZoomGestureControllerSpec; }
// Forward declaration of `HybridTapToFocusGestureControllerSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridTapToFocusGestureControllerSpec; }
// Forward declaration of `HybridOrientationManagerSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridOrientationManagerSpec; }
// Forward declaration of `OrientationSource` to properly resolve imports.
namespace margelo::nitro::camera { enum class OrientationSource; }
// Forward declaration of `HybridFrameRendererSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridFrameRendererSpec; }
// Forward declaration of `HybridMeteringPointSpec` to properly resolve imports.
namespace margelo::nitro::camera { class HybridMeteringPointSpec; }

#include "PermissionStatus.hpp"
#include <NitroModules/Promise.hpp>
#include <memory>
#include "HybridCameraSessionSpec.hpp"
#include "HybridCameraSessionConfigSpec.hpp"
#include "HybridCameraDeviceSpec.hpp"
#include "CameraOutputConfiguration.hpp"
#include <vector>
#include "FPSConstraint.hpp"
#include "VideoStabilizationModeConstraint.hpp"
#include "PreviewStabilizationModeConstraint.hpp"
#include "ResolutionBiasConstraint.hpp"
#include "VideoDynamicRangeConstraint.hpp"
#include "PhotoHDRConstraint.hpp"
#include "PixelFormatConstraint.hpp"
#include "BinnedConstraint.hpp"
#include <variant>
#include <optional>
#include "HybridCameraDeviceFactorySpec.hpp"
#include "HybridCameraPhotoOutputSpec.hpp"
#include "PhotoOutputOptions.hpp"
#include "HybridCameraVideoOutputSpec.hpp"
#include "VideoOutputOptions.hpp"
#include "HybridCameraFrameOutputSpec.hpp"
#include "FrameOutputOptions.hpp"
#include "HybridCameraDepthFrameOutputSpec.hpp"
#include "DepthFrameOutputOptions.hpp"
#include "HybridCameraPreviewOutputSpec.hpp"
#include "HybridCameraObjectOutputSpec.hpp"
#include "ObjectOutputOptions.hpp"
#include "HybridCameraOutputSynchronizerSpec.hpp"
#include "HybridCameraOutputSpec.hpp"
#include "HybridZoomGestureControllerSpec.hpp"
#include "HybridTapToFocusGestureControllerSpec.hpp"
#include "HybridOrientationManagerSpec.hpp"
#include "OrientationSource.hpp"
#include "HybridFrameRendererSpec.hpp"
#include "HybridMeteringPointSpec.hpp"

namespace margelo::nitro::camera {

  using namespace margelo::nitro;

  /**
   * An abstract base class for `CameraFactory`
   * Inherit this class to create instances of `HybridCameraFactorySpec` in C++.
   * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
   * @example
   * ```cpp
   * class HybridCameraFactory: public HybridCameraFactorySpec {
   * public:
   *   HybridCameraFactory(...): HybridObject(TAG) { ... }
   *   // ...
   * };
   * ```
   */
  class HybridCameraFactorySpec: public virtual HybridObject {
    public:
      // Constructor
      explicit HybridCameraFactorySpec(): HybridObject(TAG) { }

      // Destructor
      ~HybridCameraFactorySpec() override = default;

    public:
      // Properties
      virtual PermissionStatus getCameraPermissionStatus() = 0;
      virtual PermissionStatus getMicrophonePermissionStatus() = 0;
      virtual bool getSupportsMultiCamSessions() = 0;

    public:
      // Methods
      virtual std::shared_ptr<Promise<bool>> requestCameraPermission() = 0;
      virtual std::shared_ptr<Promise<bool>> requestMicrophonePermission() = 0;
      virtual std::shared_ptr<Promise<std::shared_ptr<HybridCameraSessionSpec>>> createCameraSession(bool enableMultiCam) = 0;
      virtual std::shared_ptr<Promise<std::shared_ptr<HybridCameraSessionConfigSpec>>> resolveConstraints(const std::shared_ptr<HybridCameraDeviceSpec>& device, const std::vector<CameraOutputConfiguration>& outputConfigurations, const std::vector<std::variant<FPSConstraint, VideoStabilizationModeConstraint, PreviewStabilizationModeConstraint, ResolutionBiasConstraint, VideoDynamicRangeConstraint, PhotoHDRConstraint, PixelFormatConstraint, BinnedConstraint>>& constraints, std::optional<bool> requiresMultiCam) = 0;
      virtual std::shared_ptr<Promise<std::shared_ptr<HybridCameraDeviceFactorySpec>>> createDeviceFactory() = 0;
      virtual std::shared_ptr<HybridCameraPhotoOutputSpec> createPhotoOutput(const PhotoOutputOptions& options) = 0;
      virtual std::shared_ptr<HybridCameraVideoOutputSpec> createVideoOutput(const VideoOutputOptions& options) = 0;
      virtual std::shared_ptr<HybridCameraFrameOutputSpec> createFrameOutput(const FrameOutputOptions& options) = 0;
      virtual std::shared_ptr<HybridCameraDepthFrameOutputSpec> createDepthFrameOutput(const DepthFrameOutputOptions& options) = 0;
      virtual std::shared_ptr<HybridCameraPreviewOutputSpec> createPreviewOutput() = 0;
      virtual std::shared_ptr<HybridCameraObjectOutputSpec> createObjectOutput(const ObjectOutputOptions& options) = 0;
      virtual std::shared_ptr<HybridCameraOutputSynchronizerSpec> createOutputSynchronizer(const std::vector<std::shared_ptr<HybridCameraOutputSpec>>& outputs) = 0;
      virtual std::shared_ptr<HybridZoomGestureControllerSpec> createZoomGestureController() = 0;
      virtual std::shared_ptr<HybridTapToFocusGestureControllerSpec> createTapToFocusGestureController() = 0;
      virtual std::shared_ptr<HybridOrientationManagerSpec> createOrientationManager(OrientationSource orientationSource) = 0;
      virtual std::shared_ptr<HybridFrameRendererSpec> createFrameRenderer() = 0;
      virtual std::shared_ptr<HybridMeteringPointSpec> createNormalizedMeteringPoint(double x, double y, std::optional<double> size) = 0;

    protected:
      // Hybrid Setup
      void loadHybridMethods() override;

    protected:
      // Tag for logging
      static constexpr auto TAG = "CameraFactory";
  };

} // namespace margelo::nitro::camera
