// 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.

// @dart = 2.6
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.
    );
  }
}
