// Copyright 2014 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 'package:flutter/foundation.dart';

// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by dev/tools/gen_keycodes/bin/gen_keycodes.dart and
// should not be edited directly.
//
// Edit the template dev/tools/gen_keycodes/data/keyboard_key.tmpl instead.
// See dev/tools/gen_keycodes/README.md for more information.

/// A base class for all keyboard key types.
///
/// See also:
///
///  * [PhysicalKeyboardKey], a class with static values that describe the keys
///    that are returned from [RawKeyEvent.physicalKey].
///  * [LogicalKeyboardKey], a class with static values that describe the keys
///    that are returned from [RawKeyEvent.logicalKey].
abstract class KeyboardKey with Diagnosticable {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const KeyboardKey();
}

/// A class with static values that describe the keys that are returned from
/// [RawKeyEvent.logicalKey].
///
/// These represent *logical* keys, which are keys which are interpreted in the
/// context of any modifiers, modes, or keyboard layouts which may be in effect.
///
/// This is contrast to [PhysicalKeyboardKey], which represents a physical key
/// in a particular location on the keyboard, without regard for the modifier
/// state, mode, or keyboard layout.
///
/// As an example, if you wanted to implement an app where the "Q" key "quit"
/// something, you'd want to look at the logical key to detect this, since you
/// would like to have it match the key with "Q" on it, instead of always
/// looking for "the key next to the TAB key", since on a French keyboard,
/// the key next to the TAB key has an "A" on it.
///
/// Conversely, if you wanted a game where the key next to the CAPS LOCK (the
/// "A" key on a QWERTY keyboard) moved the player to the left, you'd want to
/// look at the physical key to make sure that regardless of the character the
/// key produces, you got the key that is in that location on the keyboard.
///
/// {@tool dartpad --template=stateful_widget_scaffold}
/// This example shows how to detect if the user has selected the logical "Q"
/// key.
///
/// ```dart imports
/// import 'package:flutter/foundation.dart';
/// import 'package:flutter/services.dart';
/// ```
///
/// ```dart
/// // The node used to request the keyboard focus.
/// final FocusNode _focusNode = FocusNode();
/// // The message to display.
/// String? _message;
///
/// // Focus nodes need to be disposed.
/// @override
/// void dispose() {
///   _focusNode.dispose();
///   super.dispose();
/// }
///
/// // Handles the key events from the RawKeyboardListener and update the
/// // _message.
/// void _handleKeyEvent(RawKeyEvent event) {
///   setState(() {
///     if (event.logicalKey == LogicalKeyboardKey.keyQ) {
///       _message = 'Pressed the "Q" key!';
///     } else {
///       if (kReleaseMode) {
///         _message = 'Not a Q: Pressed 0x${event.logicalKey.keyId.toRadixString(16)}';
///       } else {
///         // The debugName will only print useful information in debug mode.
///         _message = 'Not a Q: Pressed ${event.logicalKey.debugName}';
///       }
///     }
///   });
/// }
///
/// @override
/// Widget build(BuildContext context) {
///   final TextTheme textTheme = Theme.of(context).textTheme;
///   return Container(
///     color: Colors.white,
///     alignment: Alignment.center,
///     child: DefaultTextStyle(
///       style: textTheme.headline4!,
///       child: RawKeyboardListener(
///         focusNode: _focusNode,
///         onKey: _handleKeyEvent,
///         child: AnimatedBuilder(
///           animation: _focusNode,
///           builder: (BuildContext context, Widget? child) {
///             if (!_focusNode.hasFocus) {
///               return GestureDetector(
///                 onTap: () {
///                   FocusScope.of(context).requestFocus(_focusNode);
///                 },
///                 child: const Text('Tap to focus'),
///               );
///             }
///             return Text(_message ?? 'Press a key');
///           },
///         ),
///       ),
///     ),
///   );
/// }
/// ```
/// {@end-tool}
/// See also:
///
///  * [RawKeyEvent], the keyboard event object received by widgets that listen
///    to keyboard events.
///  * [RawKeyboardListener], a widget used to listen to and supply handlers for
///    keyboard events.
@immutable
class LogicalKeyboardKey extends KeyboardKey {
  /// Creates a new LogicalKeyboardKey object for a key ID.
  const LogicalKeyboardKey(this.keyId);

  /// A unique code representing this key.
  ///
  /// This is an opaque code. It should not be unpacked to derive information
  /// from it, as the representation of the code could change at any time.
  final int keyId;

  // Returns the bits that are not included in [valueMask], shifted to the
  // right.
  //
  // For example, if the input is 0x12abcdabcd, then the result is 0x12.
  //
  // This is mostly equivalent to a right shift, resolving the problem that
  // JavaScript only support 32-bit bitwise operation and needs to use division
  // instead.
  static int _nonValueBits(int n) {
    // `n >> valueMaskWidth` is equivalent to `n / divisorForValueMask`.
    const int divisorForValueMask = valueMask + 1;
    const int valueMaskWidth = 32;

    // Equivalent to assert(divisorForValueMask == (1 << valueMaskWidth)).
    const int _firstDivisorWidth = 28;
    assert(divisorForValueMask ==
      (1 << _firstDivisorWidth) * (1 << (valueMaskWidth - _firstDivisorWidth)));

    // JS only supports up to 2^53 - 1, therefore non-value bits can only
    // contain (maxSafeIntegerWidth - valueMaskWidth) bits.
    const int maxSafeIntegerWidth = 52;
    const int nonValueMask = (1 << (maxSafeIntegerWidth - valueMaskWidth)) - 1;

    if (kIsWeb) {
      return (n / divisorForValueMask).floor() & nonValueMask;
    } else {
      return (n >> valueMaskWidth) & nonValueMask;
    }
  }

  static String? _unicodeKeyLabel(int keyId) {
    if (_nonValueBits(keyId) == 0) {
      return String.fromCharCode(keyId).toUpperCase();
    }
    return null;
  }

  /// A description representing the character produced by a [RawKeyEvent].
  ///
  /// This value is useful for providing readable strings for keys or keyboard
  /// shortcuts. Do not use this value to compare equality of keys; compare
  /// [keyId] instead.
  ///
  /// For printable keys, this is usually the printable character in upper case
  /// ignoring modifiers or combining keys, such as 'A', '1', or '/'. This
  /// might also return accented letters (such as 'Ù') for keys labeled as so,
  /// but not if such character is a result from preceding combining keys ('`̀'
  /// followed by key U).
  ///
  /// For other keys, [keyLabel] looks up the full key name from a predefined
  /// map, such as 'F1', 'Shift Left', or 'Media Down'. This value is an empty
  /// string if there's no key label data for a key.
  ///
  /// For the printable representation that takes into consideration the
  /// modifiers and combining keys, see [RawKeyEvent.character].
  ///
  /// {@macro flutter.services.RawKeyEventData.keyLabel}
  String get keyLabel {
    return _unicodeKeyLabel(keyId)
        ?? _keyLabels[keyId]
        ?? '';
  }

  /// The debug string to print for this keyboard key, which will be null in
  /// release mode.
  ///
  /// For printable keys, this is usually a more descriptive name related to
  /// [keyLabel], such as 'Key A', 'Digit 1', 'Backslash'. This might
  /// also return accented letters (such as 'Key Ù') for keys labeled as so.
  ///
  /// For other keys, this looks up the full key name from a predefined map (the
  /// same value as [keyLabel]), such as 'F1', 'Shift Left', or 'Media Down'. If
  /// there's no key label data for a key, this returns a name that explains the
  /// ID (such as 'Key with ID 0x00100012345').
  String? get debugName {
    String? result;
    assert(() {
      result = _keyLabels[keyId];
      if (result == null) {
        final String? unicodeKeyLabel = _unicodeKeyLabel(keyId);
        if (unicodeKeyLabel != null) {
          result = 'Key $unicodeKeyLabel';
        } else {
          result = 'Key with ID 0x${keyId.toRadixString(16).padLeft(11, '0')}';
        }
      }
      return true;
    }());
    return result;
  }

  @override
  int get hashCode => keyId.hashCode;

  @override
  bool operator ==(Object other) {
    if (identical(this, other))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
    return other is LogicalKeyboardKey
        && other.keyId == keyId;
  }

  /// Returns the [LogicalKeyboardKey] constant that matches the given ID, or
  /// null, if not found.
  static LogicalKeyboardKey? findKeyByKeyId(int keyId) => _knownLogicalKeys[keyId];

  /// Returns true if the given label represents a Unicode control character.
  ///
  /// Examples of control characters are characters like "U+000A LINE FEED (LF)"
  /// or "U+001B ESCAPE (ESC)".
  ///
  /// See <https://en.wikipedia.org/wiki/Unicode_control_characters> for more
  /// information.
  ///
  /// Used by [RawKeyEvent] subclasses to help construct IDs.
  static bool isControlCharacter(String label) {
    if (label.length != 1) {
      return false;
    }
    final int codeUnit = label.codeUnitAt(0);
    return (codeUnit <= 0x1f && codeUnit >= 0x00) || (codeUnit >= 0x7f && codeUnit <= 0x9f);
  }

  /// Returns true if the [keyId] of this object is one that is auto-generated by
  /// Flutter.
  ///
  /// Auto-generated key IDs are generated in response to platform key codes
  /// which Flutter doesn't recognize, and their IDs shouldn't be used in a
  /// persistent way.
  ///
  /// Auto-generated IDs should be a rare occurrence: Flutter supports most keys.
  ///
  /// Keys that generate Unicode characters (even if unknown to Flutter) will
  /// not return true for `isAutogenerated`, since they will be assigned a
  /// Unicode-based code that will remain stable.
  ///
  /// If Flutter adds support for a previously unsupported key code, the ID it
  /// reports will change, but the ID will remain stable on the platform it is
  /// produced on until Flutter adds support for recognizing it.
  ///
  /// So, hypothetically, if Android added a new key code of 0xffff,
  /// representing a new "do what I mean" key, then the auto-generated code
  /// would be 0x1020000ffff, but once Flutter added the "doWhatIMean" key to
  /// the definitions below, the new code would be 0x0020000ffff for all
  /// platforms that had a "do what I mean" key from then on.
  bool get isAutogenerated => (keyId & autogeneratedMask) != 0;

  /// Returns a set of pseudo-key synonyms for the given `key`.
  ///
  /// This allows finding the pseudo-keys that also represents a concrete
  /// `key` so that a class with a key map can match pseudo-keys as well as the
  /// actual generated keys.
  ///
  /// The pseudo-keys returned in the set are typically used to represent keys
  /// which appear in multiple places on the keyboard, such as the [shift],
  /// [alt], [control], and [meta] keys. The keys in the returned set won't ever
  /// be generated directly, but if a more specific key event is received, then
  /// this set can be used to find the more general pseudo-key. For example, if
  /// this is a [shiftLeft] key, this accessor will return the set
  /// `<LogicalKeyboardKey>{ shift }`.
  Set<LogicalKeyboardKey> get synonyms {
    final LogicalKeyboardKey? result = _synonyms[this];
    return result == null ? <LogicalKeyboardKey>{} : <LogicalKeyboardKey>{result};
  }

  /// Takes a set of keys, and returns the same set, but with any keys that have
  /// synonyms replaced.
  ///
  /// It is used, for example, to make sets of keys with members like
  /// [controlRight] and [controlLeft] and convert that set to contain just
  /// [control], so that the question "is any control key down?" can be asked.
  static Set<LogicalKeyboardKey> collapseSynonyms(Set<LogicalKeyboardKey> input) {
    final Set<LogicalKeyboardKey> result = <LogicalKeyboardKey>{};
    for (final LogicalKeyboardKey key in input) {
      final LogicalKeyboardKey? synonym = _synonyms[key];
      result.add(synonym ?? key);
    }
    return result;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(StringProperty('keyId', '0x${keyId.toRadixString(16).padLeft(8, '0')}', showName: true));
    properties.add(StringProperty('keyLabel', keyLabel, showName: true));
    properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null));
  }

  /// Mask for the 32-bit value portion of the key code.
  ///
  /// This is used by platform-specific code to generate Flutter key codes.
  static const int valueMask = 0x000FFFFFFFF;

  /// Mask for the platform prefix portion of the key code.
  ///
  /// This is used by platform-specific code to generate Flutter key codes.
  static const int platformMask = 0x0FF00000000;

  /// Mask for the auto-generated bit portion of the key code.
  ///
  /// This is used by platform-specific code to generate new Flutter key codes
  /// for keys which are not recognized.
  static const int autogeneratedMask = 0x10000000000;

  /// Mask for the synonym pseudo-keys generated for keys which appear in more
  /// than one place on the keyboard.
  ///
  /// IDs in this range are used to represent keys which appear in multiple
  /// places on the keyboard, such as the SHIFT, ALT, CTRL, and numeric keypad
  /// keys. These key codes will never be generated by the key event system, but
  /// may be used in key maps to represent the union of all the keys of each
  /// type in order to match them.
  ///
  /// To look up the synonyms that are defined, look in the [synonyms] map.
  static const int synonymMask = 0x20000000000;

  /// The code prefix for keys which have a Unicode representation.
  ///
  /// This is used by platform-specific code to generate Flutter key codes.
  static const int unicodePlane = 0x00000000000;

  /// The code prefix for keys which do not have a Unicode representation.
  ///
  /// This is used by platform-specific code to generate Flutter key codes using
  /// HID Usage codes.
  static const int hidPlane = 0x00100000000;
@@@LOGICAL_KEY_DEFINITIONS@@@
  // A list of all predefined constant LogicalKeyboardKeys so they can be
  // searched.
  static const Map<int, LogicalKeyboardKey> _knownLogicalKeys = <int, LogicalKeyboardKey>{
@@@LOGICAL_KEY_MAP@@@
  };

  // A map of keys to the pseudo-key synonym for that key. Used by getSynonyms.
  static final Map<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = <LogicalKeyboardKey, LogicalKeyboardKey>{
@@@LOGICAL_KEY_SYNONYMS@@@  };

  static const Map<int, String> _keyLabels = <int, String>{
@@@LOGICAL_KEY_KEY_LABELS@@@    };
}

/// A class with static values that describe the keys that are returned from
/// [RawKeyEvent.physicalKey].
///
/// These represent *physical* keys, which are keys which represent a particular
/// key location on a QWERTY keyboard. It ignores any modifiers, modes, or
/// keyboard layouts which may be in effect. This is contrast to
/// [LogicalKeyboardKey], which represents a logical key interpreted in the
/// context of modifiers, modes, and/or keyboard layouts.
///
/// As an example, if you wanted a game where the key next to the CAPS LOCK (the
/// "A" key on a QWERTY keyboard) moved the player to the left, you'd want to
/// look at the physical key to make sure that regardless of the character the
/// key produces, you got the key that is in that location on the keyboard.
///
/// Conversely, if you wanted to implement an app where the "Q" key "quit"
/// something, you'd want to look at the logical key to detect this, since you
/// would like to have it match the key with "Q" on it, instead of always
/// looking for "the key next to the TAB key", since on a French keyboard,
/// the key next to the TAB key has an "A" on it.
///
/// {@tool dartpad --template=stateful_widget_scaffold}
/// This example shows how to detect if the user has selected the physical key
/// to the right of the CAPS LOCK key.
///
/// ```dart imports
/// import 'package:flutter/services.dart';
/// ```
///
/// ```dart
/// // The node used to request the keyboard focus.
/// final FocusNode _focusNode = FocusNode();
/// // The message to display.
/// String? _message;
///
/// // Focus nodes need to be disposed.
/// @override
/// void dispose() {
///   _focusNode.dispose();
///   super.dispose();
/// }
///
/// // Handles the key events from the RawKeyboardListener and update the
/// // _message.
/// void _handleKeyEvent(RawKeyEvent event) {
///   setState(() {
///     if (event.physicalKey == PhysicalKeyboardKey.keyA) {
///       _message = 'Pressed the key next to CAPS LOCK!';
///     } else {
///       _message = 'Wrong key.';
///     }
///   });
/// }
///
/// @override
/// Widget build(BuildContext context) {
///   final TextTheme textTheme = Theme.of(context).textTheme;
///   return Container(
///     color: Colors.white,
///     alignment: Alignment.center,
///     child: DefaultTextStyle(
///       style: textTheme.headline4!,
///       child: RawKeyboardListener(
///         focusNode: _focusNode,
///         onKey: _handleKeyEvent,
///         child: AnimatedBuilder(
///           animation: _focusNode,
///           builder: (BuildContext context, Widget? child) {
///             if (!_focusNode.hasFocus) {
///               return GestureDetector(
///                 onTap: () {
///                   FocusScope.of(context).requestFocus(_focusNode);
///                 },
///                 child: const Text('Tap to focus'),
///               );
///             }
///             return Text(_message ?? 'Press a key');
///           },
///         ),
///       ),
///     ),
///   );
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
///  * [RawKeyEvent], the keyboard event object received by widgets that listen
///    to keyboard events.
///  * [RawKeyboardListener], a widget used to listen to and supply handlers for
///    keyboard events.
@immutable
class PhysicalKeyboardKey extends KeyboardKey {
  /// Creates a new PhysicalKeyboardKey object for a USB HID usage.
  const PhysicalKeyboardKey(this.usbHidUsage);

  /// The unique USB HID usage ID of this physical key on the keyboard.
  ///
  /// Due to the variations in platform APIs, this may not be the actual HID
  /// usage code from the hardware, but a value derived from available
  /// information on the platform.
  ///
  /// See <https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf>
  /// for the HID usage values and their meanings.
  final int usbHidUsage;

  /// The debug string to print for this keyboard key, which will be null in
  /// release mode.
  String? get debugName {
    String? result;
    assert(() {
      result = _debugNames[usbHidUsage] ??
        'Key with ID 0x${usbHidUsage.toRadixString(16).padLeft(8, '0')}';
      return true;
    }());
    return result;
  }

  @override
  int get hashCode => usbHidUsage.hashCode;

  @override
  bool operator ==(Object other) {
    if (identical(this, other))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
    return other is PhysicalKeyboardKey
        && other.usbHidUsage == usbHidUsage;
  }

  /// Finds a known [PhysicalKeyboardKey] that matches the given USB HID usage
  /// code.
  static PhysicalKeyboardKey? findKeyByCode(int usageCode) => _knownPhysicalKeys[usageCode];

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(StringProperty('usbHidUsage', '0x${usbHidUsage.toRadixString(16).padLeft(8, '0')}', showName: true));
    properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null));
  }

  // Key constants for all keyboard keys in the USB HID specification at the
  // time Flutter was built.
@@@PHYSICAL_KEY_DEFINITIONS@@@
  // A list of all the predefined constant PhysicalKeyboardKeys so that they
  // can be searched.
  static const Map<int, PhysicalKeyboardKey> _knownPhysicalKeys = <int, PhysicalKeyboardKey>{
@@@PHYSICAL_KEY_MAP@@@
  };

  static const Map<int, String> _debugNames = kReleaseMode ?
    <int, String>{} :
    <int, String>{
@@@PHYSICAL_KEY_DEBUG_NAMES@@@    };
}
