// Copyright 2013 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 'dart:ui';

import 'package:scenario_app/src/channel_util.dart';

import 'platform_echo_mixin.dart';
import 'scenario.dart';

/// A blank page with a button that pops the page when tapped.
class PoppableScreenScenario extends Scenario with PlatformEchoMixin {
  /// Creates the PoppableScreenScenario.
  ///
  /// The [dispatcher] parameter must not be null.
  PoppableScreenScenario(PlatformDispatcher dispatcher)
      : assert(dispatcher != null),
        super(dispatcher);

  // Rect for the pop button. Only defined once onMetricsChanged is called.
  Rect? _buttonRect;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);

    canvas.drawPaint(Paint()..color = const Color.fromARGB(255, 255, 255, 255));

    if (_buttonRect != null) {
      canvas.drawRect(
        _buttonRect!,
        Paint()..color = const Color.fromARGB(255, 255, 0, 0),
      );
    }
    final Picture picture = recorder.endRecording();

    builder.pushOffset(0, 0);
    builder.addPicture(Offset.zero, picture);
    final Scene scene = builder.build();
    window.render(scene);
    scene.dispose();
  }

  @override
  void onDrawFrame() {
    // Just draw once since the content never changes.
  }

  @override
  void onMetricsChanged() {
    _buttonRect = Rect.fromLTRB(
      window.physicalSize.width / 4,
      window.physicalSize.height * 2 / 5,
      window.physicalSize.width * 3 / 4,
      window.physicalSize.height * 3 / 5,
    );
    window.scheduleFrame();
  }

  @override
  void onPointerDataPacket(PointerDataPacket packet) {
    for (final PointerData data in packet.data) {
      if (data.change == PointerChange.up &&
          _buttonRect?.contains(Offset(data.physicalX, data.physicalY)) == true
      ) {
        _pop();
      }
    }
  }

  void _pop() {
    sendJsonMethodCall(
      dispatcher: dispatcher,
      // 'flutter/platform' is the hardcoded name of the 'platform'
      // `SystemChannel` from the `SystemNavigator` API.
      // https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/system_navigator.dart.
      channel: 'flutter/platform',
      method: 'SystemNavigator.pop',
      // Don't care about the response. If it doesn't go through, the test
      // will fail.
    );
  }
}
