// 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 {
  /// A const constructor so that subclasses may be const.
  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 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: Key label is "${event.logicalKey.keyLabel ?? '<none>'}"';
///       } else {
///         // This 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 LogicalKeyboardKey object with an optional key label and debug
  /// name.
  ///
  /// [keyId] must not be null.
  ///
  /// {@tool snippet}
  /// To save executable size, it is recommended that the [debugName] be null in
  /// release mode. You can do this by using the [kReleaseMode] constant.
  ///
  /// ```dart
  /// const LogicalKeyboardKey(0x0010000000a, debugName: kReleaseMode ? null : 'Special Key')
  /// ```
  /// {@end-tool}
  const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel = ''})
      : assert(keyId != null);

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

  /// The debug string to print for this keyboard key, which will be null in
  /// release mode.
  final String? debugName;

  /// The Unicode string representing the character produced by a [RawKeyEvent].
  ///
  /// This value is useful for describing or matching mnemonic keyboard
  /// shortcuts.
  ///
  /// This value is an empty string if there's no key label data for a key.
  ///
  /// On most platforms this is a single code point, but it could contain any
  /// Unicode string. The `keyLabel` differs from [RawKeyEvent.character]
  /// because `keyLabel` only takes into account the key being pressed, not any
  /// combining keys pressed before it, so, for example, an “o” that follows a
  /// combining dieresis (“¨”, COMBINING DIAERESIS (U+0308)) would just return
  /// “o” for [keyLabel], but would return “ö” for [RawKeyEvent.character].
  ///
  /// {@macro flutter.services.RawKeyEventData.keyLabel}
  final String keyLabel;

  @override
  int get hashCode => keyId.hashCode;

  @override
  bool operator ==(Object other) {
    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@@@  };
}

/// 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 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: 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 PhysicalKeyboardKey object with an optional debug name.
  ///
  /// The [usbHidUsage] must not be null.
  ///
  /// {@tool snippet}
  /// To save executable size, it is recommended that the [debugName] be null in
  /// release mode. You can do this using the [kReleaseMode] constant.
  ///
  /// ```dart
  /// const PhysicalKeyboardKey(0x0000ffff, debugName: kReleaseMode ? null : 'Special Key')
  /// ```
  /// {@end-tool}
  const PhysicalKeyboardKey(this.usbHidUsage, {this.debugName})
      : assert(usbHidUsage != null);

  /// 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.
  final String? debugName;

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

  @override
  int get hashCode => usbHidUsage.hashCode;

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

  @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@@@
  };
}
