// 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 Windows.
///
/// This object contains information about key events obtained from Windows's
/// win32 API.
///
/// See also:
///
///  * [RawKeyboard], which uses this interface to expose key data.
class RawKeyEventDataWindows extends RawKeyEventData {
  /// Creates a key event data structure specific for Windows.
  ///
  /// The [keyCode], [scanCode], [characterCodePoint], and [modifiers], arguments
  /// must not be null.
  const RawKeyEventDataWindows({
    this.keyCode = 0,
    this.scanCode = 0,
    this.characterCodePoint = 0,
    this.modifiers = 0,
  }) : assert(keyCode != null),
       assert(scanCode != null),
       assert(characterCodePoint != null),
       assert(modifiers != null);

  /// 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 ones defined in https://github.com/flutter/engine/blob/master/shell/platform/windows/key_event_handler.cc
  final int modifiers;

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

  @override
  PhysicalKeyboardKey get physicalKey => kWindowsToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;

 @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 != null && keyLabel.isNotEmpty && !LogicalKeyboardKey.isControlCharacter(keyLabel)) {
      final int keyId = LogicalKeyboardKey.unicodePlane | (characterCodePoint & LogicalKeyboardKey.valueMask);
      return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
        keyId,
        keyLabel: keyLabel,
        debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
      );
    }
    // Look to see if the keyCode is one we know about and have a mapping for.
    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 with the autogenerated bit set.
    const int windowsKeyIdPlane = 0x00700000000;
    newKey ??= LogicalKeyboardKey(
      windowsKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
      debugName: kReleaseMode ? null : 'Unknown Windows key code $keyCode',
    );
    return newKey;
  }

  bool _isLeftRightModifierPressed(KeyboardSide side, int anyMask, int leftMask, int rightMask) {
    if (modifiers & anyMask == 0 &&
        modifiers & leftMask == 0 &&
        modifiers & rightMask == 0) {
      return false;
    }
    // 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).
    final bool anyOnly = modifiers & (leftMask | rightMask | anyMask) == anyMask;
    switch (side) {
      case KeyboardSide.any:
        return true;
      case KeyboardSide.all:
        return modifiers & leftMask != 0 && modifiers & rightMask != 0 || anyOnly;
      case KeyboardSide.left:
        return modifiers & leftMask != 0 || anyOnly;
      case KeyboardSide.right:
        return modifiers & rightMask != 0 || anyOnly;
    }
    return false;
  }

  @override
  bool isModifierPressed(ModifierKey key, {KeyboardSide side = KeyboardSide.any}) {
    bool result;
    switch (key) {
      case ModifierKey.controlModifier:
        result = _isLeftRightModifierPressed(side, modifierControl, modifierLeftControl, modifierRightControl);
        break;
      case ModifierKey.shiftModifier:
        result = _isLeftRightModifierPressed(side, modifierShift, modifierLeftShift, modifierRightShift);
        break;
      case ModifierKey.altModifier:
        result = _isLeftRightModifierPressed(side, modifierAlt, modifierLeftAlt, modifierRightAlt);
        break;
      case ModifierKey.metaModifier:
        // Windows does not provide an "any" key for win key press.
        result = _isLeftRightModifierPressed(side, modifierLeftMeta | modifierRightMeta , modifierLeftMeta, modifierRightMeta);
        break;
      case ModifierKey.capsLockModifier:
        result = modifiers & modifierCaps != 0;
        break;
      case ModifierKey.scrollLockModifier:
        result = modifiers & modifierScrollLock != 0;
        break;
      case ModifierKey.numLockModifier:
        result = modifiers & modifierNumLock != 0;
        break;
      // 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;
        break;
    }
    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) {
        return KeyboardSide.all;
      } else if (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.any;
      }
      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;
    }

    assert(false, 'Not handling $key type properly.');
    return null;
  }

  // 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/master/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.
  ///
  /// {@macro flutter.services.rawKeyEventDataWindows.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  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.modifiers}
  static const int modifierScrollLock = 1 << 13;
}
