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

// Android sets the 0x80000000 bit on a character to indicate that it is a
// combining character, so we use this mask to remove that bit to make it a
// valid Unicode character again.
const int _kCombiningCharacterMask = 0x7fffffff;

/// Platform-specific key event data for Android.
///
/// This object contains information about key events obtained from Android's
/// `KeyEvent` interface.
///
/// See also:
///
///  * [RawKeyboard], which uses this interface to expose key data.
class RawKeyEventDataAndroid extends RawKeyEventData {
  /// Creates a key event data structure specific for Android.
  ///
  /// The [flags], [codePoint], [keyCode], [scanCode], and [metaState] arguments
  /// must not be null.
  const RawKeyEventDataAndroid({
    this.flags = 0,
    this.codePoint = 0,
    this.plainCodePoint = 0,
    this.keyCode = 0,
    this.scanCode = 0,
    this.metaState = 0,
    this.eventSource = 0,
    this.vendorId = 0,
    this.productId = 0,
    this.deviceId = 0,
    this.repeatCount = 0,
  }) : assert(flags != null),
       assert(codePoint != null),
       assert(keyCode != null),
       assert(scanCode != null),
       assert(metaState != null);

  /// The current set of additional flags for this event.
  ///
  /// Flags indicate things like repeat state, etc.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getFlags()>
  /// for more information.
  final int flags;

  /// The Unicode code point represented by the key event, if any.
  ///
  /// If there is no Unicode code point, this value is zero.
  ///
  /// Dead keys are represented as Unicode combining characters.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getUnicodeChar()>
  /// for more information.
  final int codePoint;

  /// The Unicode code point represented by the key event, if any, without
  /// regard to any modifier keys which are currently pressed.
  ///
  /// If there is no Unicode code point, this value is zero.
  ///
  /// Dead keys are represented as Unicode combining characters.
  ///
  /// This is the result of calling KeyEvent.getUnicodeChar(0) on Android.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getUnicodeChar(int)>
  /// for more information.
  final int plainCodePoint;

  /// The hardware key code corresponding to this key event.
  ///
  /// This is the physical key that was pressed, not the Unicode character.
  /// See [codePoint] for the Unicode character.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getKeyCode()>
  /// for more information.
  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.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getScanCode()>
  /// for more information.
  final int scanCode;

  /// The modifiers that were present when the key event occurred.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getMetaState()>
  /// for the numerical values of the `metaState`. Many of these constants are
  /// also replicated as static constants in this class.
  ///
  /// See also:
  ///
  ///  * [modifiersPressed], which returns a Map of currently pressed modifiers
  ///    and their keyboard side.
  ///  * [isModifierPressed], to see if a specific modifier is pressed.
  ///  * [isControlPressed], to see if a CTRL key is pressed.
  ///  * [isShiftPressed], to see if a SHIFT key is pressed.
  ///  * [isAltPressed], to see if an ALT key is pressed.
  ///  * [isMetaPressed], to see if a META key is pressed.
  final int metaState;

  /// The source of the event.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent.html#getSource()>
  /// for the numerical values of the `source`. Many of these constants are also
  /// replicated as static constants in this class.
  final int eventSource;

  /// The vendor ID of the device that produced the event.
  ///
  /// See <https://developer.android.com/reference/android/view/InputDevice.html#getVendorId()>
  /// for the numerical values of the `vendorId`.
  final int vendorId;

  /// The product ID of the device that produced the event.
  ///
  /// See <https://developer.android.com/reference/android/view/InputDevice.html#getProductId()>
  /// for the numerical values of the `productId`.
  final int productId;

  /// The ID of the device that produced the event.
  ///
  /// See https://developer.android.com/reference/android/view/InputDevice.html#getId()
  final int deviceId;

  /// The repeat count of the event.
  ///
  /// See <https://developer.android.com/reference/android/view/KeyEvent#getRepeatCount()>
  /// for more information.
  final int repeatCount;

  // The source code that indicates that an event came from a joystick.
  // from https://developer.android.com/reference/android/view/InputDevice.html#SOURCE_JOYSTICK
  static const int _sourceJoystick = 0x01000010;

  // Android only reports a single code point for the key label.
  @override
  String get keyLabel => plainCodePoint == 0 ? '' : String.fromCharCode(plainCodePoint & _kCombiningCharacterMask);

  @override
  PhysicalKeyboardKey get physicalKey {
    if (kAndroidToPhysicalKey.containsKey(scanCode)) {
      return kAndroidToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
    }

    // Android sends DPAD_UP, etc. as the keyCode for joystick DPAD events, but
    // it doesn't set the scanCode for those, so we have to detect this, and set
    // our own DPAD physical keys. The logical key will still match "arrowUp",
    // etc.
    if (eventSource & _sourceJoystick == _sourceJoystick) {
      final LogicalKeyboardKey? foundKey = kAndroidToLogicalKey[keyCode];
      if (foundKey == LogicalKeyboardKey.arrowUp) {
        return PhysicalKeyboardKey.arrowUp;
      }
      if (foundKey == LogicalKeyboardKey.arrowDown) {
        return PhysicalKeyboardKey.arrowDown;
      }
      if (foundKey == LogicalKeyboardKey.arrowLeft) {
        return PhysicalKeyboardKey.arrowLeft;
      }
      if (foundKey == LogicalKeyboardKey.arrowRight) {
        return PhysicalKeyboardKey.arrowRight;
      }
    }
    return 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 = kAndroidNumPadMap[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 combinedCodePoint = plainCodePoint & _kCombiningCharacterMask;
      final int keyId = LogicalKeyboardKey.unicodePlane | (combinedCodePoint & 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 = kAndroidToLogicalKey[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 androidKeyIdPlane = 0x00200000000;
    newKey ??= LogicalKeyboardKey(
      androidKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
      debugName: kReleaseMode ? null : 'Unknown Android key code $keyCode',
    );
    return newKey;
  }

  bool _isLeftRightModifierPressed(KeyboardSide side, int anyMask, int leftMask, int rightMask) {
    if (metaState & anyMask == 0) {
      return false;
    }
    switch (side) {
      case KeyboardSide.any:
        return true;
      case KeyboardSide.all:
        return metaState & leftMask != 0 && metaState & rightMask != 0;
      case KeyboardSide.left:
        return metaState & leftMask != 0;
      case KeyboardSide.right:
        return metaState & rightMask != 0;
    }
  }

  @override
  bool isModifierPressed(ModifierKey key, { KeyboardSide side = KeyboardSide.any }) {
    assert(side != null);
    switch (key) {
      case ModifierKey.controlModifier:
        return _isLeftRightModifierPressed(side, modifierControl, modifierLeftControl, modifierRightControl);
      case ModifierKey.shiftModifier:
        return _isLeftRightModifierPressed(side, modifierShift, modifierLeftShift, modifierRightShift);
      case ModifierKey.altModifier:
        return _isLeftRightModifierPressed(side, modifierAlt, modifierLeftAlt, modifierRightAlt);
      case ModifierKey.metaModifier:
        return _isLeftRightModifierPressed(side, modifierMeta, modifierLeftMeta, modifierRightMeta);
      case ModifierKey.capsLockModifier:
        return metaState & modifierCapsLock != 0;
      case ModifierKey.numLockModifier:
        return metaState & modifierNumLock != 0;
      case ModifierKey.scrollLockModifier:
        return metaState & modifierScrollLock != 0;
      case ModifierKey.functionModifier:
        return metaState & modifierFunction != 0;
      case ModifierKey.symbolModifier:
        return metaState & modifierSym != 0;
    }
  }

  @override
  KeyboardSide? getModifierSide(ModifierKey key) {
    KeyboardSide? findSide(int anyMask, int leftMask, int rightMask) {
      final int combinedMask = leftMask | rightMask;
      final int combined = metaState & combinedMask;
      if (combined == leftMask) {
        return KeyboardSide.left;
      } else if (combined == rightMask) {
        return KeyboardSide.right;
      } else if (combined == combinedMask) {
        return KeyboardSide.all;
      }
      // If the platform code sets the "any" modifier, but not a specific side,
      // then we return "all", assuming that there is only one of that modifier
      // key on the keyboard.
      if (metaState & anyMask != 0) {
        return KeyboardSide.all;
      }
      return null;
    }

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

  // Modifier key masks.

  /// No modifier keys are pressed in the [metaState] field.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierNone = 0;

  /// This mask is used to check the [metaState] field to test whether one of
  /// the ALT modifier keys is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierAlt = 0x02;

  /// This mask is used to check the [metaState] field to test whether the left
  /// ALT modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierLeftAlt = 0x10;

  /// This mask is used to check the [metaState] field to test whether the right
  /// ALT modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierRightAlt = 0x20;

  /// This mask is used to check the [metaState] field to test whether one of
  /// the SHIFT modifier keys is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierShift = 0x01;

  /// This mask is used to check the [metaState] field to test whether the left
  /// SHIFT modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierLeftShift = 0x40;

  /// This mask is used to check the [metaState] field to test whether the right
  /// SHIFT modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierRightShift = 0x80;

  /// This mask is used to check the [metaState] field to test whether the SYM
  /// modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierSym = 0x04;

  /// This mask is used to check the [metaState] field to test whether the
  /// Function modifier key (Fn) is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierFunction = 0x08;

  /// This mask is used to check the [metaState] field to test whether one of
  /// the CTRL modifier keys is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierControl = 0x1000;

  /// This mask is used to check the [metaState] field to test whether the left
  /// CTRL modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierLeftControl = 0x2000;

  /// This mask is used to check the [metaState] field to test whether the right
  /// CTRL modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierRightControl = 0x4000;

  /// This mask is used to check the [metaState] field to test whether one of
  /// the META modifier keys is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierMeta = 0x10000;

  /// This mask is used to check the [metaState] field to test whether the left
  /// META modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierLeftMeta = 0x20000;

  /// This mask is used to check the [metaState] field to test whether the right
  /// META modifier key is pressed.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierRightMeta = 0x40000;

  /// This mask is used to check the [metaState] field to test whether the CAPS
  /// LOCK modifier key is on.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierCapsLock = 0x100000;

  /// This mask is used to check the [metaState] field to test whether the NUM
  /// LOCK modifier key is on.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierNumLock = 0x200000;

  /// This mask is used to check the [metaState] field to test whether the
  /// SCROLL LOCK modifier key is on.
  ///
  /// Use this value if you need to decode the [metaState] field yourself, but
  /// it's much easier to use [isModifierPressed] if you just want to know if
  /// a modifier is pressed.
  static const int modifierScrollLock = 0x400000;

  @override
  String toString() {
    return '${objectRuntimeType(this, 'RawKeyEventDataAndroid')}(keyLabel: $keyLabel flags: $flags, codePoint: $codePoint, '
      'keyCode: $keyCode, scanCode: $scanCode, metaState: $metaState, '
      'modifiers down: $modifiersPressed)';
  }
}
