// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_
#define PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_

#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>

#include <functional>

#include "capture_controller.h"

namespace camera_windows {

using flutter::EncodableMap;
using flutter::MethodChannel;
using flutter::MethodResult;

// A set of result types that are stored
// for processing asynchronous commands.
enum class PendingResultType {
  kCreateCamera,
  kInitialize,
  kTakePicture,
  kStartRecord,
  kStopRecord,
  kPausePreview,
  kResumePreview,
};

// Interface implemented by cameras.
//
// Access is provided to an associated |CaptureController|, which can be used
// to capture video or photo from the camera.
class Camera : public CaptureControllerListener {
 public:
  explicit Camera(const std::string& device_id) {}
  virtual ~Camera() = default;

  // Disallow copy and move.
  Camera(const Camera&) = delete;
  Camera& operator=(const Camera&) = delete;

  // Tests if this camera has the specified device ID.
  virtual bool HasDeviceId(std::string& device_id) const = 0;

  // Tests if this camera has the specified camera ID.
  virtual bool HasCameraId(int64_t camera_id) const = 0;

  // Adds a pending result.
  //
  // Returns an error result if the result has already been added.
  virtual bool AddPendingResult(PendingResultType type,
                                std::unique_ptr<MethodResult<>> result) = 0;

  // Checks if a pending result of the specified type already exists.
  virtual bool HasPendingResultByType(PendingResultType type) const = 0;

  // Returns a |CaptureController| that allows capturing video or still photos
  // from this camera.
  virtual camera_windows::CaptureController* GetCaptureController() = 0;

  // Initializes this camera and its associated capture controller.
  //
  // Returns false if initialization fails.
  virtual bool InitCamera(flutter::TextureRegistrar* texture_registrar,
                          flutter::BinaryMessenger* messenger,
                          bool record_audio,
                          ResolutionPreset resolution_preset) = 0;
};

// Concrete implementation of the |Camera| interface.
//
// This implementation is responsible for initializing the capture controller,
// listening for camera events, processing pending results, and notifying
// application code of processed events via the method channel.
class CameraImpl : public Camera {
 public:
  explicit CameraImpl(const std::string& device_id);
  virtual ~CameraImpl();

  // Disallow copy and move.
  CameraImpl(const CameraImpl&) = delete;
  CameraImpl& operator=(const CameraImpl&) = delete;

  // CaptureControllerListener
  void OnCreateCaptureEngineSucceeded(int64_t texture_id) override;
  void OnCreateCaptureEngineFailed(const std::string& error) override;
  void OnStartPreviewSucceeded(int32_t width, int32_t height) override;
  void OnStartPreviewFailed(const std::string& error) override;
  void OnPausePreviewSucceeded() override;
  void OnPausePreviewFailed(const std::string& error) override;
  void OnResumePreviewSucceeded() override;
  void OnResumePreviewFailed(const std::string& error) override;
  void OnStartRecordSucceeded() override;
  void OnStartRecordFailed(const std::string& error) override;
  void OnStopRecordSucceeded(const std::string& file_path) override;
  void OnStopRecordFailed(const std::string& error) override;
  void OnTakePictureSucceeded(const std::string& file_path) override;
  void OnTakePictureFailed(const std::string& error) override;
  void OnVideoRecordSucceeded(const std::string& file_path,
                              int64_t video_duration) override;
  void OnVideoRecordFailed(const std::string& error) override;
  void OnCaptureError(const std::string& error) override;

  // Camera
  bool HasDeviceId(std::string& device_id) const override {
    return device_id_ == device_id;
  }
  bool HasCameraId(int64_t camera_id) const override {
    return camera_id_ == camera_id;
  }
  bool AddPendingResult(PendingResultType type,
                        std::unique_ptr<MethodResult<>> result) override;
  bool HasPendingResultByType(PendingResultType type) const override;
  camera_windows::CaptureController* GetCaptureController() override {
    return capture_controller_.get();
  }
  bool InitCamera(flutter::TextureRegistrar* texture_registrar,
                  flutter::BinaryMessenger* messenger, bool record_audio,
                  ResolutionPreset resolution_preset) override;

  // Initializes the camera and its associated capture controller.
  //
  // This is a convenience method called by |InitCamera| but also used in
  // tests.
  //
  // Returns false if initialization fails.
  bool InitCamera(
      std::unique_ptr<CaptureControllerFactory> capture_controller_factory,
      flutter::TextureRegistrar* texture_registrar,
      flutter::BinaryMessenger* messenger, bool record_audio,
      ResolutionPreset resolution_preset);

 private:
  // Loops through all pending results and calls their error handler with given
  // error ID and description. Pending results are cleared in the process.
  //
  // error_code: A string error code describing the error.
  // error_message: A user-readable error message (optional).
  void SendErrorForPendingResults(const std::string& error_code,
                                  const std::string& descripion);

  // Called when camera is disposed.
  // Sends camera closing message to the cameras method channel.
  void OnCameraClosing();

  // Initializes method channel instance and returns pointer it.
  MethodChannel<>* GetMethodChannel();

  // Finds pending result by type.
  // Returns nullptr if type is not present.
  std::unique_ptr<MethodResult<>> GetPendingResultByType(
      PendingResultType type);

  std::map<PendingResultType, std::unique_ptr<MethodResult<>>> pending_results_;
  std::unique_ptr<CaptureController> capture_controller_;
  std::unique_ptr<MethodChannel<>> camera_channel_;
  flutter::BinaryMessenger* messenger_ = nullptr;
  int64_t camera_id_ = -1;
  std::string device_id_;
};

// Factory class for creating |Camera| instances from a specified device ID.
class CameraFactory {
 public:
  CameraFactory() {}
  virtual ~CameraFactory() = default;

  // Disallow copy and move.
  CameraFactory(const CameraFactory&) = delete;
  CameraFactory& operator=(const CameraFactory&) = delete;

  // Creates camera for given device id.
  virtual std::unique_ptr<Camera> CreateCamera(
      const std::string& device_id) = 0;
};

// Concrete implementation of |CameraFactory|.
class CameraFactoryImpl : public CameraFactory {
 public:
  CameraFactoryImpl() {}
  virtual ~CameraFactoryImpl() = default;

  // Disallow copy and move.
  CameraFactoryImpl(const CameraFactoryImpl&) = delete;
  CameraFactoryImpl& operator=(const CameraFactoryImpl&) = delete;

  std::unique_ptr<Camera> CreateCamera(const std::string& device_id) override {
    return std::make_unique<CameraImpl>(device_id);
  }
};

}  // namespace camera_windows

#endif  // PACKAGES_CAMERA_CAMERA_WINDOWS_WINDOWS_CAMERA_H_
