// 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.

import 'dart:async';
import 'dart:collection';

import 'package:camera_platform_interface/camera_platform_interface.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

/// The state of a [CameraController].
class CameraValue {
  /// Creates a new camera controller state.
  const CameraValue({
    required this.isInitialized,
    this.previewSize,
    required this.isRecordingVideo,
    required this.isTakingPicture,
    required this.isStreamingImages,
    required this.isRecordingPaused,
    required this.flashMode,
    required this.exposureMode,
    required this.focusMode,
    required this.deviceOrientation,
    this.lockedCaptureOrientation,
    this.recordingOrientation,
    this.isPreviewPaused = false,
    this.previewPauseOrientation,
  });

  /// Creates a new camera controller state for an uninitialized controller.
  const CameraValue.uninitialized()
      : this(
          isInitialized: false,
          isRecordingVideo: false,
          isTakingPicture: false,
          isStreamingImages: false,
          isRecordingPaused: false,
          flashMode: FlashMode.auto,
          exposureMode: ExposureMode.auto,
          focusMode: FocusMode.auto,
          deviceOrientation: DeviceOrientation.portraitUp,
          isPreviewPaused: false,
        );

  /// True after [CameraController.initialize] has completed successfully.
  final bool isInitialized;

  /// True when a picture capture request has been sent but as not yet returned.
  final bool isTakingPicture;

  /// True when the camera is recording (not the same as previewing).
  final bool isRecordingVideo;

  /// True when images from the camera are being streamed.
  final bool isStreamingImages;

  /// True when video recording is paused.
  final bool isRecordingPaused;

  /// True when the preview widget has been paused manually.
  final bool isPreviewPaused;

  /// Set to the orientation the preview was paused in, if it is currently paused.
  final DeviceOrientation? previewPauseOrientation;

  /// The size of the preview in pixels.
  ///
  /// Is `null` until [isInitialized] is `true`.
  final Size? previewSize;

  /// The flash mode the camera is currently set to.
  final FlashMode flashMode;

  /// The exposure mode the camera is currently set to.
  final ExposureMode exposureMode;

  /// The focus mode the camera is currently set to.
  final FocusMode focusMode;

  /// The current device UI orientation.
  final DeviceOrientation deviceOrientation;

  /// The currently locked capture orientation.
  final DeviceOrientation? lockedCaptureOrientation;

  /// Whether the capture orientation is currently locked.
  bool get isCaptureOrientationLocked => lockedCaptureOrientation != null;

  /// The orientation of the currently running video recording.
  final DeviceOrientation? recordingOrientation;

  /// Creates a modified copy of the object.
  ///
  /// Explicitly specified fields get the specified value, all other fields get
  /// the same value of the current object.
  CameraValue copyWith({
    bool? isInitialized,
    bool? isRecordingVideo,
    bool? isTakingPicture,
    bool? isStreamingImages,
    Size? previewSize,
    bool? isRecordingPaused,
    FlashMode? flashMode,
    ExposureMode? exposureMode,
    FocusMode? focusMode,
    bool? exposurePointSupported,
    bool? focusPointSupported,
    DeviceOrientation? deviceOrientation,
    Optional<DeviceOrientation>? lockedCaptureOrientation,
    Optional<DeviceOrientation>? recordingOrientation,
    bool? isPreviewPaused,
    Optional<DeviceOrientation>? previewPauseOrientation,
  }) {
    return CameraValue(
      isInitialized: isInitialized ?? this.isInitialized,
      previewSize: previewSize ?? this.previewSize,
      isRecordingVideo: isRecordingVideo ?? this.isRecordingVideo,
      isTakingPicture: isTakingPicture ?? this.isTakingPicture,
      isStreamingImages: isStreamingImages ?? this.isStreamingImages,
      isRecordingPaused: isRecordingPaused ?? this.isRecordingPaused,
      flashMode: flashMode ?? this.flashMode,
      exposureMode: exposureMode ?? this.exposureMode,
      focusMode: focusMode ?? this.focusMode,
      deviceOrientation: deviceOrientation ?? this.deviceOrientation,
      lockedCaptureOrientation: lockedCaptureOrientation == null
          ? this.lockedCaptureOrientation
          : lockedCaptureOrientation.orNull,
      recordingOrientation: recordingOrientation == null
          ? this.recordingOrientation
          : recordingOrientation.orNull,
      isPreviewPaused: isPreviewPaused ?? this.isPreviewPaused,
      previewPauseOrientation: previewPauseOrientation == null
          ? this.previewPauseOrientation
          : previewPauseOrientation.orNull,
    );
  }

  @override
  String toString() {
    return '${objectRuntimeType(this, 'CameraValue')}('
        'isRecordingVideo: $isRecordingVideo, '
        'isInitialized: $isInitialized, '
        'previewSize: $previewSize, '
        'isStreamingImages: $isStreamingImages, '
        'flashMode: $flashMode, '
        'exposureMode: $exposureMode, '
        'focusMode: $focusMode, '
        'deviceOrientation: $deviceOrientation, '
        'lockedCaptureOrientation: $lockedCaptureOrientation, '
        'recordingOrientation: $recordingOrientation, '
        'isPreviewPaused: $isPreviewPaused, '
        'previewPausedOrientation: $previewPauseOrientation)';
  }
}

/// Controls a device camera.
///
/// This is a stripped-down version of the app-facing controller to serve as a
/// utility for the example and integration tests. It wraps only the calls that
/// have state associated with them, to consolidate tracking of camera state
/// outside of the overall example code.
class CameraController extends ValueNotifier<CameraValue> {
  /// Creates a new camera controller in an uninitialized state.
  CameraController(
    this.description,
    this.resolutionPreset, {
    this.enableAudio = true,
    this.imageFormatGroup,
  }) : super(const CameraValue.uninitialized());

  /// The properties of the camera device controlled by this controller.
  final CameraDescription description;

  /// The resolution this controller is targeting.
  ///
  /// This resolution preset is not guaranteed to be available on the device,
  /// if unavailable a lower resolution will be used.
  ///
  /// See also: [ResolutionPreset].
  final ResolutionPreset resolutionPreset;

  /// Whether to include audio when recording a video.
  final bool enableAudio;

  /// The [ImageFormatGroup] describes the output of the raw image format.
  ///
  /// When null the imageFormat will fallback to the platforms default.
  final ImageFormatGroup? imageFormatGroup;

  late int _cameraId;

  bool _isDisposed = false;
  StreamSubscription<CameraImageData>? _imageStreamSubscription;
  FutureOr<bool>? _initCalled;
  StreamSubscription<DeviceOrientationChangedEvent>?
      _deviceOrientationSubscription;

  /// The camera identifier with which the controller is associated.
  int get cameraId => _cameraId;

  /// Initializes the camera on the device.
  Future<void> initialize() async {
    final Completer<CameraInitializedEvent> initializeCompleter =
        Completer<CameraInitializedEvent>();

    _deviceOrientationSubscription = CameraPlatform.instance
        .onDeviceOrientationChanged()
        .listen((DeviceOrientationChangedEvent event) {
      value = value.copyWith(
        deviceOrientation: event.orientation,
      );
    });

    _cameraId = await CameraPlatform.instance.createCamera(
      description,
      resolutionPreset,
      enableAudio: enableAudio,
    );

    CameraPlatform.instance
        .onCameraInitialized(_cameraId)
        .first
        .then((CameraInitializedEvent event) {
      initializeCompleter.complete(event);
    });

    await CameraPlatform.instance.initializeCamera(
      _cameraId,
      imageFormatGroup: imageFormatGroup ?? ImageFormatGroup.unknown,
    );

    value = value.copyWith(
      isInitialized: true,
      previewSize: await initializeCompleter.future
          .then((CameraInitializedEvent event) => Size(
                event.previewWidth,
                event.previewHeight,
              )),
      exposureMode: await initializeCompleter.future
          .then((CameraInitializedEvent event) => event.exposureMode),
      focusMode: await initializeCompleter.future
          .then((CameraInitializedEvent event) => event.focusMode),
      exposurePointSupported: await initializeCompleter.future
          .then((CameraInitializedEvent event) => event.exposurePointSupported),
      focusPointSupported: await initializeCompleter.future
          .then((CameraInitializedEvent event) => event.focusPointSupported),
    );

    _initCalled = true;
  }

  /// Prepare the capture session for video recording.
  Future<void> prepareForVideoRecording() async {
    await CameraPlatform.instance.prepareForVideoRecording();
  }

  /// Pauses the current camera preview
  Future<void> pausePreview() async {
    await CameraPlatform.instance.pausePreview(_cameraId);
    value = value.copyWith(
        isPreviewPaused: true,
        previewPauseOrientation: Optional<DeviceOrientation>.of(
            value.lockedCaptureOrientation ?? value.deviceOrientation));
  }

  /// Resumes the current camera preview
  Future<void> resumePreview() async {
    await CameraPlatform.instance.resumePreview(_cameraId);
    value = value.copyWith(
        isPreviewPaused: false,
        previewPauseOrientation: const Optional<DeviceOrientation>.absent());
  }

  /// Captures an image and returns the file where it was saved.
  ///
  /// Throws a [CameraException] if the capture fails.
  Future<XFile> takePicture() async {
    value = value.copyWith(isTakingPicture: true);
    final XFile file = await CameraPlatform.instance.takePicture(_cameraId);
    value = value.copyWith(isTakingPicture: false);
    return file;
  }

  /// Start streaming images from platform camera.
  Future<void> startImageStream(
      Function(CameraImageData image) onAvailable) async {
    _imageStreamSubscription = CameraPlatform.instance
        .onStreamedFrameAvailable(_cameraId)
        .listen((CameraImageData imageData) {
      onAvailable(imageData);
    });
    value = value.copyWith(isStreamingImages: true);
  }

  /// Stop streaming images from platform camera.
  Future<void> stopImageStream() async {
    value = value.copyWith(isStreamingImages: false);
    await _imageStreamSubscription?.cancel();
    _imageStreamSubscription = null;
  }

  /// Start a video recording.
  ///
  /// The video is returned as a [XFile] after calling [stopVideoRecording].
  /// Throws a [CameraException] if the capture fails.
  Future<void> startVideoRecording(
      {Function(CameraImageData image)? streamCallback}) async {
    await CameraPlatform.instance.startVideoCapturing(
        VideoCaptureOptions(_cameraId, streamCallback: streamCallback));
    value = value.copyWith(
        isRecordingVideo: true,
        isRecordingPaused: false,
        isStreamingImages: streamCallback != null,
        recordingOrientation: Optional<DeviceOrientation>.of(
            value.lockedCaptureOrientation ?? value.deviceOrientation));
  }

  /// Stops the video recording and returns the file where it was saved.
  ///
  /// Throws a [CameraException] if the capture failed.
  Future<XFile> stopVideoRecording() async {
    if (value.isStreamingImages) {
      await stopImageStream();
    }

    final XFile file =
        await CameraPlatform.instance.stopVideoRecording(_cameraId);
    value = value.copyWith(
      isRecordingVideo: false,
      recordingOrientation: const Optional<DeviceOrientation>.absent(),
    );
    return file;
  }

  /// Pause video recording.
  ///
  /// This feature is only available on iOS and Android sdk 24+.
  Future<void> pauseVideoRecording() async {
    await CameraPlatform.instance.pauseVideoRecording(_cameraId);
    value = value.copyWith(isRecordingPaused: true);
  }

  /// Resume video recording after pausing.
  ///
  /// This feature is only available on iOS and Android sdk 24+.
  Future<void> resumeVideoRecording() async {
    await CameraPlatform.instance.resumeVideoRecording(_cameraId);
    value = value.copyWith(isRecordingPaused: false);
  }

  /// Returns a widget showing a live camera preview.
  Widget buildPreview() {
    return CameraPlatform.instance.buildPreview(_cameraId);
  }

  /// Sets the flash mode for taking pictures.
  Future<void> setFlashMode(FlashMode mode) async {
    await CameraPlatform.instance.setFlashMode(_cameraId, mode);
    value = value.copyWith(flashMode: mode);
  }

  /// Sets the exposure mode for taking pictures.
  Future<void> setExposureMode(ExposureMode mode) async {
    await CameraPlatform.instance.setExposureMode(_cameraId, mode);
    value = value.copyWith(exposureMode: mode);
  }

  /// Sets the exposure offset for the selected camera.
  Future<double> setExposureOffset(double offset) async {
    // Check if offset is in range
    final List<double> range = await Future.wait(<Future<double>>[
      CameraPlatform.instance.getMinExposureOffset(_cameraId),
      CameraPlatform.instance.getMaxExposureOffset(_cameraId)
    ]);

    // Round to the closest step if needed
    final double stepSize =
        await CameraPlatform.instance.getExposureOffsetStepSize(_cameraId);
    if (stepSize > 0) {
      final double inv = 1.0 / stepSize;
      double roundedOffset = (offset * inv).roundToDouble() / inv;
      if (roundedOffset > range[1]) {
        roundedOffset = (offset * inv).floorToDouble() / inv;
      } else if (roundedOffset < range[0]) {
        roundedOffset = (offset * inv).ceilToDouble() / inv;
      }
      offset = roundedOffset;
    }

    return CameraPlatform.instance.setExposureOffset(_cameraId, offset);
  }

  /// Locks the capture orientation.
  ///
  /// If [orientation] is omitted, the current device orientation is used.
  Future<void> lockCaptureOrientation() async {
    await CameraPlatform.instance
        .lockCaptureOrientation(_cameraId, value.deviceOrientation);
    value = value.copyWith(
        lockedCaptureOrientation:
            Optional<DeviceOrientation>.of(value.deviceOrientation));
  }

  /// Unlocks the capture orientation.
  Future<void> unlockCaptureOrientation() async {
    await CameraPlatform.instance.unlockCaptureOrientation(_cameraId);
    value = value.copyWith(
        lockedCaptureOrientation: const Optional<DeviceOrientation>.absent());
  }

  /// Sets the focus mode for taking pictures.
  Future<void> setFocusMode(FocusMode mode) async {
    await CameraPlatform.instance.setFocusMode(_cameraId, mode);
    value = value.copyWith(focusMode: mode);
  }

  /// Releases the resources of this camera.
  @override
  Future<void> dispose() async {
    if (_isDisposed) {
      return;
    }
    _deviceOrientationSubscription?.cancel();
    _isDisposed = true;
    super.dispose();
    if (_initCalled != null) {
      await _initCalled;
      await CameraPlatform.instance.dispose(_cameraId);
    }
  }

  @override
  void removeListener(VoidCallback listener) {
    // Prevent ValueListenableBuilder in CameraPreview widget from causing an
    // exception to be thrown by attempting to remove its own listener after
    // the controller has already been disposed.
    if (!_isDisposed) {
      super.removeListener(listener);
    }
  }
}

/// A value that might be absent.
///
/// Used to represent [DeviceOrientation]s that are optional but also able
/// to be cleared.
@immutable
class Optional<T> extends IterableBase<T> {
  /// Constructs an empty Optional.
  const Optional.absent() : _value = null;

  /// Constructs an Optional of the given [value].
  ///
  /// Throws [ArgumentError] if [value] is null.
  Optional.of(T value) : _value = value {
    // TODO(cbracken): Delete and make this ctor const once mixed-mode
    // execution is no longer around.
    ArgumentError.checkNotNull(value);
  }

  /// Constructs an Optional of the given [value].
  ///
  /// If [value] is null, returns [absent()].
  const Optional.fromNullable(T? value) : _value = value;

  final T? _value;

  /// True when this optional contains a value.
  bool get isPresent => _value != null;

  /// True when this optional contains no value.
  bool get isNotPresent => _value == null;

  /// Gets the Optional value.
  ///
  /// Throws [StateError] if [value] is null.
  T get value {
    if (_value == null) {
      throw StateError('value called on absent Optional.');
    }
    return _value!;
  }

  /// Executes a function if the Optional value is present.
  void ifPresent(void Function(T value) ifPresent) {
    if (isPresent) {
      ifPresent(_value as T);
    }
  }

  /// Execution a function if the Optional value is absent.
  void ifAbsent(void Function() ifAbsent) {
    if (!isPresent) {
      ifAbsent();
    }
  }

  /// Gets the Optional value with a default.
  ///
  /// The default is returned if the Optional is [absent()].
  ///
  /// Throws [ArgumentError] if [defaultValue] is null.
  T or(T defaultValue) {
    return _value ?? defaultValue;
  }

  /// Gets the Optional value, or `null` if there is none.
  T? get orNull => _value;

  /// Transforms the Optional value.
  ///
  /// If the Optional is [absent()], returns [absent()] without applying the transformer.
  ///
  /// The transformer must not return `null`. If it does, an [ArgumentError] is thrown.
  Optional<S> transform<S>(S Function(T value) transformer) {
    return _value == null
        ? Optional<S>.absent()
        : Optional<S>.of(transformer(_value as T));
  }

  /// Transforms the Optional value.
  ///
  /// If the Optional is [absent()], returns [absent()] without applying the transformer.
  ///
  /// Returns [absent()] if the transformer returns `null`.
  Optional<S> transformNullable<S>(S? Function(T value) transformer) {
    return _value == null
        ? Optional<S>.absent()
        : Optional<S>.fromNullable(transformer(_value as T));
  }

  @override
  Iterator<T> get iterator =>
      isPresent ? <T>[_value as T].iterator : Iterable<T>.empty().iterator;

  /// Delegates to the underlying [value] hashCode.
  @override
  int get hashCode => _value.hashCode;

  /// Delegates to the underlying [value] operator==.
  @override
  bool operator ==(Object o) => o is Optional<T> && o._value == _value;

  @override
  String toString() {
    return _value == null
        ? 'Optional { absent }'
        : 'Optional { value: $_value }';
  }
}
