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

import 'keyboard_key.dart';
import 'keyboard_maps.dart';
import 'raw_keyboard.dart';

/// Platform-specific key event data for Linux.
///
/// Different window toolkit implementations can map to different key codes. This class
/// will use the correct mapping depending on the [keyHelper] provided.
///
/// See also:
///
///  * [RawKeyboard], which uses this interface to expose key data.
class RawKeyEventDataLinux extends RawKeyEventData {
  /// Creates a key event data structure specific for Linux.
  ///
  /// The [keyHelper], [scanCode], [unicodeScalarValues], [keyCode], and [modifiers],
  /// arguments must not be null.
  const RawKeyEventDataLinux({
    required this.keyHelper,
    this.unicodeScalarValues = 0,
    this.scanCode = 0,
    this.keyCode = 0,
    this.modifiers = 0,
    required this.isDown,
  }) : assert(scanCode != null),
       assert(unicodeScalarValues != null),
       assert((unicodeScalarValues & ~LogicalKeyboardKey.valueMask) == 0),
       assert(keyCode != null),
       assert(modifiers != null),
       assert(keyHelper != null);

  /// A helper class that abstracts the fetching of the toolkit-specific mappings.
  ///
  /// There is no real concept of a "native" window toolkit on Linux, and each implementation
  /// (GLFW, GTK, QT, etc) may have a different key code mapping.
  final KeyHelper keyHelper;

  /// An int with up to two Unicode scalar values generated by a single keystroke. An assertion
  /// will fire if more than two values are encoded in a single keystroke.
  ///
  /// This is typically the character that [keyCode] would produce without any modifier keys.
  /// For dead keys, it is typically the diacritic it would add to a character. Defaults to 0,
  /// asserted to be not null.
  final int unicodeScalarValues;

  /// The hardware scan code id corresponding to this key event.
  ///
  /// These values are not reliable and vary from device to device, so this
  /// information is mainly useful for debugging.
  final int scanCode;

  /// The hardware key code corresponding to this key event.
  ///
  /// This is the physical key that was pressed, not the Unicode character.
  /// This value may be different depending on the window toolkit used. See [KeyHelper].
  final int keyCode;

  /// A mask of the current modifiers using the values in Modifier Flags.
  /// This value may be different depending on the window toolkit used. See [KeyHelper].
  final int modifiers;

  /// Whether or not this key event is a key down (true) or key up (false).
  final bool isDown;

  @override
  String get keyLabel => unicodeScalarValues == 0 ? '' : String.fromCharCode(unicodeScalarValues);

  @override
  PhysicalKeyboardKey get physicalKey => kLinuxToPhysicalKey[scanCode] ?? PhysicalKeyboardKey(LogicalKeyboardKey.webPlane + scanCode);

  @override
  LogicalKeyboardKey get logicalKey {
    // Look to see if the keyCode is a printable number pad key, so that a
    // difference between regular keys (e.g. "=") and the number pad version
    // (e.g. the "=" on the number pad) can be determined.
    final LogicalKeyboardKey? numPadKey = keyHelper.numpadKey(keyCode);
    if (numPadKey != null) {
      return numPadKey;
    }

    // If it has a non-control-character label, then either return the existing
    // constant, or construct a new Unicode-based key from it. Don't mark it as
    // autogenerated, since the label uniquely identifies an ID from the Unicode
    // plane.
    if (keyLabel.isNotEmpty &&
        !LogicalKeyboardKey.isControlCharacter(keyLabel)) {
      final int keyId = LogicalKeyboardKey.unicodePlane | (unicodeScalarValues & LogicalKeyboardKey.valueMask);
      return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
    }

    // Look to see if the keyCode is one we know about and have a mapping for.
    final LogicalKeyboardKey? newKey = keyHelper.logicalKey(keyCode);
    if (newKey != null) {
      return newKey;
    }

    // This is a non-printable key that we don't know about, so we mint a new
    // code.
    return LogicalKeyboardKey(keyCode | keyHelper.platformPlane);
  }

  @override
  bool isModifierPressed(ModifierKey key, {KeyboardSide side = KeyboardSide.any}) {
    return keyHelper.isModifierPressed(key, modifiers, side: side, keyCode: keyCode, isDown: isDown);
  }

  @override
  KeyboardSide getModifierSide(ModifierKey key) {
    return keyHelper.getModifierSide(key);
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<String>('toolkit', keyHelper.debugToolkit));
    properties.add(DiagnosticsProperty<int>('unicodeScalarValues', unicodeScalarValues));
    properties.add(DiagnosticsProperty<int>('scanCode', scanCode));
    properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
    properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
    properties.add(DiagnosticsProperty<bool>('isDown', isDown));
  }

  @override
  bool operator==(Object other) {
    if (identical(this, other))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
    return other is RawKeyEventDataLinux
        && other.keyHelper.runtimeType == keyHelper.runtimeType
        && other.unicodeScalarValues == unicodeScalarValues
        && other.scanCode == scanCode
        && other.keyCode == keyCode
        && other.modifiers == modifiers
        && other.isDown == isDown;
  }

  @override
  int get hashCode => Object.hash(
    keyHelper.runtimeType,
    unicodeScalarValues,
    scanCode,
    keyCode,
    modifiers,
    isDown,
  );
}

/// Abstract class for window-specific key mappings.
///
/// Given that there might be multiple window toolkit implementations (GLFW,
/// GTK, QT, etc), this creates a common interface for each of the
/// different toolkits.
abstract class KeyHelper {
  /// Create a KeyHelper implementation depending on the given toolkit.
  factory KeyHelper(String toolkit) {
    if (toolkit == 'glfw') {
      return GLFWKeyHelper();
    } else if (toolkit == 'gtk') {
      return GtkKeyHelper();
    } else {
      throw FlutterError('Window toolkit not recognized: $toolkit');
    }
  }

  /// Returns the name for the toolkit.
  ///
  /// This is used in debug mode to generate readable string.
  String get debugToolkit;

  /// Returns a [KeyboardSide] enum value that describes which side or sides of
  /// the given keyboard modifier key were pressed at the time of this event.
  KeyboardSide getModifierSide(ModifierKey key);

  /// Returns true if the given [ModifierKey] was pressed at the time of this
  /// event.
  bool isModifierPressed(ModifierKey key, int modifiers, {KeyboardSide side = KeyboardSide.any, required int keyCode, required bool isDown});

  /// The numpad key from the specific key code mapping.
  LogicalKeyboardKey? numpadKey(int keyCode);

  /// The logical key from the specific key code mapping.
  LogicalKeyboardKey? logicalKey(int keyCode);

  /// The platform plane mask value of this platform.
  int get platformPlane;
}

/// Helper class that uses GLFW-specific key mappings.
class GLFWKeyHelper implements KeyHelper {
  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether the CAPS LOCK modifier key is on.
  ///
  /// {@template flutter.services.GLFWKeyHelper.modifierCapsLock}
  /// Use this value if you need to decode the [RawKeyEventDataLinux.modifiers]
  /// field yourself, but it's much easier to use [isModifierPressed] if you
  /// just want to know if a modifier is pressed. This is especially true on
  /// GLFW, since its modifiers don't include the effects of the current key
  /// event.
  /// {@endtemplate}
  static const int modifierCapsLock = 0x0010;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the SHIFT modifier keys is pressed.
  ///
  /// {@macro flutter.services.GLFWKeyHelper.modifierCapsLock}
  static const int modifierShift = 0x0001;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the CTRL modifier keys is pressed.
  ///
  /// {@macro flutter.services.GLFWKeyHelper.modifierCapsLock}
  static const int modifierControl = 0x0002;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the ALT modifier keys is pressed.
  ///
  /// {@macro flutter.services.GLFWKeyHelper.modifierCapsLock}
  static const int modifierAlt = 0x0004;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the Meta(SUPER) modifier keys is pressed.
  ///
  /// {@macro flutter.services.GLFWKeyHelper.modifierCapsLock}
  static const int modifierMeta = 0x0008;


  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether any key in the numeric keypad is pressed.
  ///
  /// {@macro flutter.services.GLFWKeyHelper.modifierCapsLock}
  static const int modifierNumericPad = 0x0020;

  @override
  String get debugToolkit => 'GLFW';

  int _mergeModifiers({required int modifiers, required int keyCode, required bool isDown}) {
    // GLFW Key codes for modifier keys.
    const int shiftLeftKeyCode = 340;
    const int shiftRightKeyCode = 344;
    const int controlLeftKeyCode = 341;
    const int controlRightKeyCode = 345;
    const int altLeftKeyCode = 342;
    const int altRightKeyCode = 346;
    const int metaLeftKeyCode = 343;
    const int metaRightKeyCode = 347;
    const int capsLockKeyCode = 280;
    const int numLockKeyCode = 282;

    // On GLFW, the "modifiers" bitfield is the state as it is BEFORE this event
    // happened, not AFTER, like every other platform. Consequently, if this is
    // a key down, then we need to add the correct modifier bits, and if it's a
    // key up, we need to remove them.

    int modifierChange = 0;
    switch (keyCode) {
      case shiftLeftKeyCode:
      case shiftRightKeyCode:
        modifierChange = modifierShift;
        break;
      case controlLeftKeyCode:
      case controlRightKeyCode:
        modifierChange = modifierControl;
        break;
      case altLeftKeyCode:
      case altRightKeyCode:
        modifierChange = modifierAlt;
        break;
      case metaLeftKeyCode:
      case metaRightKeyCode:
        modifierChange = modifierMeta;
        break;
      case capsLockKeyCode:
        modifierChange = modifierCapsLock;
        break;
      case numLockKeyCode:
        modifierChange = modifierNumericPad;
        break;
      default:
        break;
    }

    return isDown ? modifiers | modifierChange : modifiers & ~modifierChange;
  }

  @override
  bool isModifierPressed(ModifierKey key, int modifiers, {KeyboardSide side = KeyboardSide.any, required int keyCode, required bool isDown}) {
    modifiers = _mergeModifiers(modifiers: modifiers, keyCode: keyCode, isDown: isDown);
    switch (key) {
      case ModifierKey.controlModifier:
        return modifiers & modifierControl != 0;
      case ModifierKey.shiftModifier:
        return modifiers & modifierShift != 0;
      case ModifierKey.altModifier:
        return modifiers & modifierAlt != 0;
      case ModifierKey.metaModifier:
        return modifiers & modifierMeta != 0;
      case ModifierKey.capsLockModifier:
        return modifiers & modifierCapsLock != 0;
      case ModifierKey.numLockModifier:
        return modifiers & modifierNumericPad != 0;
      case ModifierKey.functionModifier:
      case ModifierKey.symbolModifier:
      case ModifierKey.scrollLockModifier:
        // These are not used in GLFW keyboards.
        return false;
    }
  }

  @override
  KeyboardSide getModifierSide(ModifierKey key) {
    // Neither GLFW nor X11 provide a distinction between left and right
    // modifiers, so defaults to KeyboardSide.all.
    // https://code.woboq.org/qt5/include/X11/X.h.html#_M/ShiftMask
    return KeyboardSide.all;
  }

  @override
  LogicalKeyboardKey? numpadKey(int keyCode) {
    return kGlfwNumpadMap[keyCode];
  }

  @override
  LogicalKeyboardKey? logicalKey(int keyCode) {
    return kGlfwToLogicalKey[keyCode];
  }

  @override
  int get platformPlane => LogicalKeyboardKey.glfwPlane;
}

/// Helper class that uses GTK-specific key mappings.
class GtkKeyHelper implements KeyHelper {
  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the SHIFT modifier keys is pressed.
  ///
  /// {@template flutter.services.GtkKeyHelper.modifierShift}
  /// Use this value if you need to decode the [RawKeyEventDataLinux.modifiers] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if a
  /// modifier is pressed. This is especially true on GTK, since its modifiers
  /// don't include the effects of the current key event.
  /// {@endtemplate}
  static const int modifierShift = 1 << 0;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether the CAPS LOCK modifier key is on.
  ///
  /// {@macro flutter.services.GtkKeyHelper.modifierShift}
  static const int modifierCapsLock = 1 << 1;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the CTRL modifier keys is pressed.
  ///
  /// {@macro flutter.services.GtkKeyHelper.modifierShift}
  static const int modifierControl = 1 << 2;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether the first modifier key is pressed (usually mapped to alt).
  ///
  /// {@macro flutter.services.GtkKeyHelper.modifierShift}
  static const int modifierMod1 = 1 << 3;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether the second modifier key is pressed (assumed to be mapped to
  /// num lock).
  ///
  /// {@macro flutter.services.GtkKeyHelper.modifierShift}
  static const int modifierMod2 = 1 << 4;

  /// This mask is used to check the [RawKeyEventDataLinux.modifiers] field to
  /// test whether one of the Meta(SUPER) modifier keys is pressed.
  ///
  /// {@macro flutter.services.GtkKeyHelper.modifierShift}
  static const int modifierMeta = 1 << 26;

  @override
  String get debugToolkit => 'GTK';

  int _mergeModifiers({required int modifiers, required int keyCode, required bool isDown}) {
    // GTK Key codes for modifier keys.
    const int shiftLeftKeyCode = 0xffe1;
    const int shiftRightKeyCode = 0xffe2;
    const int controlLeftKeyCode = 0xffe3;
    const int controlRightKeyCode = 0xffe4;
    const int capsLockKeyCode = 0xffe5;
    const int shiftLockKeyCode = 0xffe6;
    const int altLeftKeyCode = 0xffe9;
    const int altRightKeyCode = 0xffea;
    const int metaLeftKeyCode = 0xffeb;
    const int metaRightKeyCode = 0xffec;
    const int numLockKeyCode = 0xff7f;

    // On GTK, the "modifiers" bitfield is the state as it is BEFORE this event
    // happened, not AFTER, like every other platform. Consequently, if this is
    // a key down, then we need to add the correct modifier bits, and if it's a
    // key up, we need to remove them.

    int modifierChange = 0;
    switch (keyCode) {
      case shiftLeftKeyCode:
      case shiftRightKeyCode:
        modifierChange = modifierShift;
        break;
      case controlLeftKeyCode:
      case controlRightKeyCode:
        modifierChange = modifierControl;
        break;
      case altLeftKeyCode:
      case altRightKeyCode:
        modifierChange = modifierMod1;
        break;
      case metaLeftKeyCode:
      case metaRightKeyCode:
        modifierChange = modifierMeta;
        break;
      case capsLockKeyCode:
      case shiftLockKeyCode:
        modifierChange = modifierCapsLock;
        break;
      case numLockKeyCode:
        modifierChange = modifierMod2;
        break;
      default:
        break;
    }

    return isDown ? modifiers | modifierChange : modifiers & ~modifierChange;
  }

  @override
  bool isModifierPressed(ModifierKey key, int modifiers, {KeyboardSide side = KeyboardSide.any, required int keyCode, required bool isDown}) {
    modifiers = _mergeModifiers(modifiers: modifiers, keyCode: keyCode, isDown: isDown);
    switch (key) {
      case ModifierKey.controlModifier:
        return modifiers & modifierControl != 0;
      case ModifierKey.shiftModifier:
        return modifiers & modifierShift != 0;
      case ModifierKey.altModifier:
        return modifiers & modifierMod1 != 0;
      case ModifierKey.metaModifier:
        return modifiers & modifierMeta != 0;
      case ModifierKey.capsLockModifier:
        return modifiers & modifierCapsLock != 0;
      case ModifierKey.numLockModifier:
        return modifiers & modifierMod2 != 0;
      case ModifierKey.functionModifier:
      case ModifierKey.symbolModifier:
      case ModifierKey.scrollLockModifier:
        // These are not used in GTK keyboards.
        return false;
    }
  }

  @override
  KeyboardSide getModifierSide(ModifierKey key) {
    // Neither GTK nor X11 provide a distinction between left and right
    // modifiers, so defaults to KeyboardSide.all.
    // https://code.woboq.org/qt5/include/X11/X.h.html#_M/ShiftMask
    return KeyboardSide.all;
  }

  @override
  LogicalKeyboardKey? numpadKey(int keyCode) {
    return kGtkNumpadMap[keyCode];
  }

  @override
  LogicalKeyboardKey? logicalKey(int keyCode) {
    return kGtkToLogicalKey[keyCode];
  }

  @override
  int get platformPlane => LogicalKeyboardKey.gtkPlane;
}
