// 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 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}"';
///       } 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@@@
  };
}
