// 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/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(
    MaterialApp(
      title: 'Hardware Key Demo',
      home: Scaffold(
        appBar: AppBar(title: const Text('Hardware Key Demo')),
        body: const Center(child: HardwareKeyboardDemo()),
      ),
    ),
  );
}

class HardwareKeyboardDemo extends StatefulWidget {
  const HardwareKeyboardDemo({super.key});

  @override
  State<HardwareKeyboardDemo> createState() => _HardwareKeyboardDemoState();
}

class _HardwareKeyboardDemoState extends State<HardwareKeyboardDemo> {
  final FocusNode _focusNode = FocusNode();
  KeyEvent? _event;

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) {
    setState(() {
      _event = event;
    });
    return KeyEventResult.ignored;
  }

  @override
  Widget build(BuildContext context) {
    final TextTheme textTheme = Theme.of(context).textTheme;
    return Focus(
      focusNode: _focusNode,
      onKeyEvent: _handleKeyEvent,
      autofocus: true,
      child: AnimatedBuilder(
        animation: _focusNode,
        builder: (BuildContext context, Widget? child) {
          if (!_focusNode.hasFocus) {
            return GestureDetector(
              onTap: () {
                _focusNode.requestFocus();
              },
              child: Text('Tap to focus', style: textTheme.headlineMedium),
            );
          }

          if (_event == null) {
            return Text('Press a key', style: textTheme.headlineMedium);
          }

          final dataText = <Widget>[
            Text('${_event.runtimeType}'),
            if (_event?.character?.isNotEmpty ?? false)
              Text('character produced: "${_event?.character}"'),
          ];
          dataText.add(Text('logical: ${_event?.logicalKey}'));
          dataText.add(Text('physical: ${_event?.physicalKey}'));
          if (_event?.character != null) {
            dataText.add(Text('character: ${_event?.character}'));
          }
          final pressed = <String>['Pressed:'];
          for (final LogicalKeyboardKey key in HardwareKeyboard.instance.logicalKeysPressed) {
            pressed.add(key.debugName!);
          }
          dataText.add(Text(pressed.join(' ')));
          return DefaultTextStyle(
            style: textTheme.titleMedium!,
            child: Column(mainAxisAlignment: MainAxisAlignment.center, children: dataText),
          );
        },
      ),
    );
  }
}
