// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: unused_import, unused_shown_name
// ignore_for_file: type=lint

import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List;

import 'package:flutter/services.dart';
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;

Object? _extractReplyValueOrThrow(
  List<Object?>? replyList,
  String channelName, {
  required bool isNullValid,
}) {
  if (replyList == null) {
    throw PlatformException(
      code: 'channel-error',
      message: 'Unable to establish connection on channel: "$channelName".',
    );
  } else if (replyList.length > 1) {
    throw PlatformException(
      code: replyList[0]! as String,
      message: replyList[1] as String?,
      details: replyList[2],
    );
  } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) {
    throw PlatformException(
      code: 'null-error',
      message: 'Host platform returned null value for non-null return value.',
    );
  }
  return replyList.firstOrNull;
}

bool _deepEquals(Object? a, Object? b) {
  if (identical(a, b)) {
    return true;
  }
  if (a is double && b is double) {
    if (a.isNaN && b.isNaN) {
      return true;
    }
    return a == b;
  }
  if (a is List && b is List) {
    return a.length == b.length &&
        a.indexed.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
  }
  if (a is Map && b is Map) {
    if (a.length != b.length) {
      return false;
    }
    for (final MapEntry<Object?, Object?> entryA in a.entries) {
      bool found = false;
      for (final MapEntry<Object?, Object?> entryB in b.entries) {
        if (_deepEquals(entryA.key, entryB.key)) {
          if (_deepEquals(entryA.value, entryB.value)) {
            found = true;
            break;
          } else {
            return false;
          }
        }
      }
      if (!found) {
        return false;
      }
    }
    return true;
  }
  return a == b;
}

int _deepHash(Object? value) {
  if (value is List) {
    return Object.hashAll(value.map(_deepHash));
  }
  if (value is Map) {
    int result = 0;
    for (final MapEntry<Object?, Object?> entry in value.entries) {
      result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
    }
    return result;
  }
  if (value is double && value.isNaN) {
    // Normalize NaN to a consistent hash.
    return 0x7FF8000000000000.hashCode;
  }
  if (value is double && value == 0.0) {
    // Normalize -0.0 to 0.0 so they have the same hash code.
    return 0.0.hashCode;
  }
  return value.hashCode;
}

/// Raw audio track data from AVMediaSelectionOption (for HLS streams).
class MediaSelectionAudioTrackData {
  MediaSelectionAudioTrackData({
    required this.index,
    this.displayName,
    this.languageCode,
    required this.isSelected,
    this.commonMetadataTitle,
  });

  int index;

  String? displayName;

  String? languageCode;

  bool isSelected;

  String? commonMetadataTitle;

  List<Object?> _toList() {
    return <Object?>[index, displayName, languageCode, isSelected, commonMetadataTitle];
  }

  Object encode() {
    return _toList();
  }

  static MediaSelectionAudioTrackData decode(Object result) {
    result as List<Object?>;
    return MediaSelectionAudioTrackData(
      index: result[0]! as int,
      displayName: result[1] as String?,
      languageCode: result[2] as String?,
      isSelected: result[3]! as bool,
      commonMetadataTitle: result[4] as String?,
    );
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  bool operator ==(Object other) {
    if (other is! MediaSelectionAudioTrackData || other.runtimeType != runtimeType) {
      return false;
    }
    if (identical(this, other)) {
      return true;
    }
    return _deepEquals(index, other.index) &&
        _deepEquals(displayName, other.displayName) &&
        _deepEquals(languageCode, other.languageCode) &&
        _deepEquals(isSelected, other.isSelected) &&
        _deepEquals(commonMetadataTitle, other.commonMetadataTitle);
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}

/// Video track data from AVAssetVariant (HLS variants) for iOS 15+.
class MediaSelectionVideoTrackData {
  MediaSelectionVideoTrackData({
    required this.variantIndex,
    this.label,
    this.bitrate,
    this.width,
    this.height,
    this.frameRate,
    this.codec,
    required this.isSelected,
  });

  int variantIndex;

  String? label;

  int? bitrate;

  int? width;

  int? height;

  double? frameRate;

  String? codec;

  bool isSelected;

  List<Object?> _toList() {
    return <Object?>[variantIndex, label, bitrate, width, height, frameRate, codec, isSelected];
  }

  Object encode() {
    return _toList();
  }

  static MediaSelectionVideoTrackData decode(Object result) {
    result as List<Object?>;
    return MediaSelectionVideoTrackData(
      variantIndex: result[0]! as int,
      label: result[1] as String?,
      bitrate: result[2] as int?,
      width: result[3] as int?,
      height: result[4] as int?,
      frameRate: result[5] as double?,
      codec: result[6] as String?,
      isSelected: result[7]! as bool,
    );
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  bool operator ==(Object other) {
    if (other is! MediaSelectionVideoTrackData || other.runtimeType != runtimeType) {
      return false;
    }
    if (identical(this, other)) {
      return true;
    }
    return _deepEquals(variantIndex, other.variantIndex) &&
        _deepEquals(label, other.label) &&
        _deepEquals(bitrate, other.bitrate) &&
        _deepEquals(width, other.width) &&
        _deepEquals(height, other.height) &&
        _deepEquals(frameRate, other.frameRate) &&
        _deepEquals(codec, other.codec) &&
        _deepEquals(isSelected, other.isSelected);
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}

/// Video track data from AVAssetTrack (regular videos).
class AssetVideoTrackData {
  AssetVideoTrackData({
    required this.trackId,
    this.label,
    this.width,
    this.height,
    this.frameRate,
    this.codec,
    required this.isSelected,
  });

  int trackId;

  String? label;

  int? width;

  int? height;

  double? frameRate;

  String? codec;

  bool isSelected;

  List<Object?> _toList() {
    return <Object?>[trackId, label, width, height, frameRate, codec, isSelected];
  }

  Object encode() {
    return _toList();
  }

  static AssetVideoTrackData decode(Object result) {
    result as List<Object?>;
    return AssetVideoTrackData(
      trackId: result[0]! as int,
      label: result[1] as String?,
      width: result[2] as int?,
      height: result[3] as int?,
      frameRate: result[4] as double?,
      codec: result[5] as String?,
      isSelected: result[6]! as bool,
    );
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  bool operator ==(Object other) {
    if (other is! AssetVideoTrackData || other.runtimeType != runtimeType) {
      return false;
    }
    if (identical(this, other)) {
      return true;
    }
    return _deepEquals(trackId, other.trackId) &&
        _deepEquals(label, other.label) &&
        _deepEquals(width, other.width) &&
        _deepEquals(height, other.height) &&
        _deepEquals(frameRate, other.frameRate) &&
        _deepEquals(codec, other.codec) &&
        _deepEquals(isSelected, other.isSelected);
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}

/// Container for video track data from iOS.
class NativeVideoTrackData {
  NativeVideoTrackData({this.assetTracks, this.mediaSelectionTracks});

  /// Asset-based tracks (for regular videos)
  List<AssetVideoTrackData>? assetTracks;

  /// Media selection tracks (for HLS variants on iOS 15+)
  List<MediaSelectionVideoTrackData>? mediaSelectionTracks;

  List<Object?> _toList() {
    return <Object?>[assetTracks, mediaSelectionTracks];
  }

  Object encode() {
    return _toList();
  }

  static NativeVideoTrackData decode(Object result) {
    result as List<Object?>;
    return NativeVideoTrackData(
      assetTracks: (result[0] as List<Object?>?)?.cast<AssetVideoTrackData>(),
      mediaSelectionTracks: (result[1] as List<Object?>?)?.cast<MediaSelectionVideoTrackData>(),
    );
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  bool operator ==(Object other) {
    if (other is! NativeVideoTrackData || other.runtimeType != runtimeType) {
      return false;
    }
    if (identical(this, other)) {
      return true;
    }
    return _deepEquals(assetTracks, other.assetTracks) &&
        _deepEquals(mediaSelectionTracks, other.mediaSelectionTracks);
  }

  @override
  // ignore: avoid_equals_and_hash_code_on_mutable_classes
  int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
}

class _PigeonCodec extends StandardMessageCodec {
  const _PigeonCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is int) {
      buffer.putUint8(4);
      buffer.putInt64(value);
    } else if (value is MediaSelectionAudioTrackData) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else if (value is MediaSelectionVideoTrackData) {
      buffer.putUint8(130);
      writeValue(buffer, value.encode());
    } else if (value is AssetVideoTrackData) {
      buffer.putUint8(131);
      writeValue(buffer, value.encode());
    } else if (value is NativeVideoTrackData) {
      buffer.putUint8(132);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 129:
        return MediaSelectionAudioTrackData.decode(readValue(buffer)!);
      case 130:
        return MediaSelectionVideoTrackData.decode(readValue(buffer)!);
      case 131:
        return AssetVideoTrackData.decode(readValue(buffer)!);
      case 132:
        return NativeVideoTrackData.decode(readValue(buffer)!);
      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

class VideoPlayerInstanceApi {
  /// Constructor for [VideoPlayerInstanceApi].  The [binaryMessenger] named argument is
  /// available for dependency injection.  If it is left null, the default
  /// BinaryMessenger will be used which routes to the host platform.
  VideoPlayerInstanceApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
    : pigeonVar_binaryMessenger = binaryMessenger,
      pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty
          ? '.$messageChannelSuffix'
          : '';
  final BinaryMessenger? pigeonVar_binaryMessenger;

  static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();

  final String pigeonVar_messageChannelSuffix;

  Future<void> setLooping(bool looping) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setLooping$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[looping]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<void> setVolume(double volume) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setVolume$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[volume]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<void> setPlaybackSpeed(double speed) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPlaybackSpeed$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[speed]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<void> play() async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.play$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<int> getPosition() async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getPosition$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
      pigeonVar_replyList,
      pigeonVar_channelName,
      isNullValid: false,
    );
    return pigeonVar_replyValue! as int;
  }

  Future<void> seekTo(int position) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.seekTo$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[position]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<void> pause() async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.pause$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<void> dispose() async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.dispose$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<List<MediaSelectionAudioTrackData>> getAudioTracks() async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getAudioTracks$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
      pigeonVar_replyList,
      pigeonVar_channelName,
      isNullValid: false,
    );
    return (pigeonVar_replyValue! as List<Object?>).cast<MediaSelectionAudioTrackData>();
  }

  Future<void> selectAudioTrack(int trackIndex) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.selectAudioTrack$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[trackIndex]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  /// Gets the available video tracks for the video.
  Future<NativeVideoTrackData> getVideoTracks() async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getVideoTracks$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
      pigeonVar_replyList,
      pigeonVar_channelName,
      isNullValid: false,
    );
    return pigeonVar_replyValue! as NativeVideoTrackData;
  }

  /// Selects a video track by setting preferredPeakBitRate.
  /// Pass 0 to enable auto quality selection.
  Future<void> selectVideoTrack(int bitrate) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.selectVideoTrack$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[bitrate]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }

  Future<void> setPreventsDisplaySleepDuringVideoPlayback(
    bool preventsDisplaySleepDuringVideoPlayback,
  ) async {
    final pigeonVar_channelName =
        'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPreventsDisplaySleepDuringVideoPlayback$pigeonVar_messageChannelSuffix';
    final pigeonVar_channel = BasicMessageChannel<Object?>(
      pigeonVar_channelName,
      pigeonChannelCodec,
      binaryMessenger: pigeonVar_binaryMessenger,
    );
    final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[
      preventsDisplaySleepDuringVideoPlayback,
    ]);
    final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;

    _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
  }
}
