// 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_maps.g.dart';
import 'raw_keyboard.dart';

export 'package:flutter/foundation.dart' show DiagnosticPropertiesBuilder;

export 'keyboard_key.g.dart' show LogicalKeyboardKey, PhysicalKeyboardKey;

// Virtual key VK_PROCESSKEY in Win32 API.
//
// Key down events related to IME operations use this as keyCode.
const int _vkProcessKey = 0xe5;

/// Platform-specific key event data for Windows.
///
/// This class is DEPRECATED. Platform specific key event data will no longer
/// available. See [KeyEvent] for what is available.
///
/// This object contains information about key events obtained from Windows's
/// win32 API.
///
/// See also:
///
///  * [RawKeyboard], which uses this interface to expose key data.
@Deprecated(
  'Platform specific key event data is no longer available. See KeyEvent for what is available. '
  'This feature was deprecated after v3.18.0-2.0.pre.',
)
class RawKeyEventDataWindows extends RawKeyEventData {
  /// Creates a key event data structure specific for Windows.
  @Deprecated(
    'Platform specific key event data is no longer available. See KeyEvent for what is available. '
    'This feature was deprecated after v3.18.0-2.0.pre.',
  )
  const RawKeyEventDataWindows({
    this.keyCode = 0,
    this.scanCode = 0,
    this.characterCodePoint = 0,
    this.modifiers = 0,
  });

  /// The hardware key code corresponding to this key event.
  ///
  /// This is the physical key that was pressed, not the Unicode character.
  /// See [characterCodePoint] for the Unicode character.
  final int keyCode;

  /// 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 Unicode code point represented by the key event, if any.
  ///
  /// If there is no Unicode code point, this value is zero.
  final int characterCodePoint;

  /// A mask of the current modifiers. The modifier values must be in sync with
  /// the Windows embedder. See:
  /// https://github.com/flutter/engine/blob/7667c8a12ce6bc2d8dd538845add0a4e1a575bfd/shell/platform/windows/keyboard_key_channel_handler.cc#L44
  final int modifiers;

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

  @override
  PhysicalKeyboardKey get physicalKey => kWindowsToPhysicalKey[scanCode] ?? PhysicalKeyboardKey(LogicalKeyboardKey.windowsPlane + 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 = kWindowsNumPadMap[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 | (characterCodePoint & 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 = kWindowsToLogicalKey[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 | LogicalKeyboardKey.windowsPlane);
  }

  bool _isLeftRightModifierPressed(KeyboardSide side, int anyMask, int leftMask, int rightMask) {
    if (modifiers & (leftMask | rightMask | anyMask) == 0) {
      return false;
    }
    if (modifiers & (leftMask | rightMask | anyMask) == anyMask) {
      // If only the "anyMask" bit is set, then we respond true for requests of
      // whether either left or right is pressed. Handles the case where Windows
      // supplies just the "either" modifier flag, but not the left/right flag.
      // (e.g. modifierShift but not modifierLeftShift).
      return true;
    }
    return switch (side) {
      KeyboardSide.any   => true,
      KeyboardSide.all   => modifiers & leftMask != 0 && modifiers & rightMask != 0,
      KeyboardSide.left  => modifiers & leftMask != 0,
      KeyboardSide.right => modifiers & rightMask != 0,
    };
  }

  @override
  bool isModifierPressed(ModifierKey key, {KeyboardSide side = KeyboardSide.any}) {
    final bool result;
    switch (key) {
      case ModifierKey.controlModifier:
        result = _isLeftRightModifierPressed(side, modifierControl, modifierLeftControl, modifierRightControl);
      case ModifierKey.shiftModifier:
        result = _isLeftRightModifierPressed(side, modifierShift, modifierLeftShift, modifierRightShift);
      case ModifierKey.altModifier:
        result = _isLeftRightModifierPressed(side, modifierAlt, modifierLeftAlt, modifierRightAlt);
      case ModifierKey.metaModifier:
        // Windows does not provide an "any" key for win key press.
        result = _isLeftRightModifierPressed(side, modifierLeftMeta | modifierRightMeta , modifierLeftMeta, modifierRightMeta);
      case ModifierKey.capsLockModifier:
        result = modifiers & modifierCaps != 0;
      case ModifierKey.scrollLockModifier:
        result = modifiers & modifierScrollLock != 0;
      case ModifierKey.numLockModifier:
        result = modifiers & modifierNumLock != 0;
      // The OS does not expose the Fn key to the drivers, it doesn't generate a key message.
      case ModifierKey.functionModifier:
      case ModifierKey.symbolModifier:
        // These modifier masks are not used in Windows keyboards.
        result = false;
    }
    assert(!result || getModifierSide(key) != null, "$runtimeType thinks that a modifier is pressed, but can't figure out what side it's on.");
    return result;
  }


  @override
  KeyboardSide? getModifierSide(ModifierKey key) {
    KeyboardSide? findSide(int leftMask, int rightMask, int anyMask) {
      final int combinedMask = leftMask | rightMask;
      final int combined = modifiers & combinedMask;
      if (combined == leftMask) {
        return KeyboardSide.left;
      } else if (combined == rightMask) {
        return KeyboardSide.right;
      } else if (combined == combinedMask || modifiers & (combinedMask | anyMask) == anyMask) {
        // Handles the case where Windows supplies just the "either" modifier
        // flag, but not the left/right flag. (e.g. modifierShift but not
        // modifierLeftShift).
        return KeyboardSide.all;
      }
      return null;
    }

    switch (key) {
      case ModifierKey.controlModifier:
        return findSide(modifierLeftControl, modifierRightControl, modifierControl);
      case ModifierKey.shiftModifier:
        return findSide(modifierLeftShift, modifierRightShift, modifierShift);
      case ModifierKey.altModifier:
        return findSide(modifierLeftAlt, modifierRightAlt, modifierAlt);
      case ModifierKey.metaModifier:
        return findSide(modifierLeftMeta, modifierRightMeta, 0);
      case ModifierKey.capsLockModifier:
      case ModifierKey.numLockModifier:
      case ModifierKey.scrollLockModifier:
      case ModifierKey.functionModifier:
      case ModifierKey.symbolModifier:
        return KeyboardSide.all;
    }
  }

  @override
  bool shouldDispatchEvent() {
    // In Win32 API, down events related to IME operations use VK_PROCESSKEY as
    // keyCode. This event, as well as the following key up event (which uses a
    // normal keyCode), should be skipped, because the effect of IME operations
    // will be handled by the text input API.
    return keyCode != _vkProcessKey;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<int>('keyCode', keyCode));
    properties.add(DiagnosticsProperty<int>('scanCode', scanCode));
    properties.add(DiagnosticsProperty<int>('characterCodePoint', characterCodePoint));
    properties.add(DiagnosticsProperty<int>('modifiers', modifiers));
  }

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

  @override
  int get hashCode => Object.hash(
    keyCode,
    scanCode,
    characterCodePoint,
    modifiers,
  );

  // These are not the values defined by the Windows header for each modifier. Since they
  // can't be packaged into a single int, we are re-defining them here to reduce the size
  // of the message from the embedder. Embedders should map these values to the native key codes.
  // Keep this in sync with https://github.com/flutter/engine/blob/main/shell/platform/windows/key_event_handler.cc

  /// This mask is used to check the [modifiers] field to test whether one of the
  /// SHIFT modifier keys is pressed.
  ///
  /// {@template flutter.services.RawKeyEventDataWindows.modifierShift}
  /// Use this value if you need to decode the [modifiers] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  /// {@endtemplate}
  static const int modifierShift = 1 << 0;

  /// This mask is used to check the [modifiers] field to test whether the left
  /// SHIFT modifier key is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierLeftShift = 1 << 1;

  /// This mask is used to check the [modifiers] field to test whether the right
  /// SHIFT modifier key is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierRightShift = 1 << 2;

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

  /// This mask is used to check the [modifiers] field to test whether the left
  /// CTRL modifier key is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierLeftControl = 1 << 4;

  /// This mask is used to check the [modifiers] field to test whether the right
  /// CTRL modifier key is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierRightControl = 1 << 5;

  /// This mask is used to check the [modifiers] field to test whether one of the
  /// ALT modifier keys is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierAlt = 1 << 6;

  /// This mask is used to check the [modifiers] field to test whether the left
  /// ALT modifier key is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierLeftAlt = 1 << 7;

  /// This mask is used to check the [modifiers] field to test whether the right
  /// ALT modifier key is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierRightAlt = 1 << 8;

  /// This mask is used to check the [modifiers] field to test whether the left
  /// WIN modifier keys is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierLeftMeta = 1 << 9;

  /// This mask is used to check the [modifiers] field to test whether the right
  /// WIN modifier keys is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierRightMeta = 1 << 10;

  /// This mask is used to check the [modifiers] field to test whether the CAPS LOCK key
  /// is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierCaps = 1 << 11;

  /// This mask is used to check the [modifiers] field to test whether the NUM LOCK key
  /// is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierNumLock = 1 << 12;

  /// This mask is used to check the [modifiers] field to test whether the SCROLL LOCK key
  /// is pressed.
  ///
  /// {@macro flutter.services.RawKeyEventDataWindows.modifierShift}
  static const int modifierScrollLock = 1 << 13;
}
