// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains a wacky demonstration of creating a custom ScrollPosition
// setup. It's testing that we don't regress the factoring of the
// ScrollPosition/ScrollActivity logic into a state where you can no longer
// implement this, e.g. by oversimplifying it or overfitting it to the features
// built into the framework itself.

import 'dart:collection';
import 'dart:math' as math;

import 'package:flutter/rendering.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

class LinkedScrollController extends ScrollController {
  LinkedScrollController({ this.before, this.after });

  LinkedScrollController before;
  LinkedScrollController after;

  ScrollController _parent;

  void setParent(ScrollController newParent) {
    if (_parent != null) {
      positions.forEach(_parent.detach);
    }
    _parent = newParent;
    if (_parent != null) {
      positions.forEach(_parent.attach);
    }
  }

  @override
  void attach(ScrollPosition position) {
    assert(position is LinkedScrollPosition, 'A LinkedScrollController must only be used with LinkedScrollPositions.');
    final LinkedScrollPosition linkedPosition = position;
    assert(linkedPosition.owner == this, 'A LinkedScrollPosition cannot change controllers once created.');
    super.attach(position);
    _parent?.attach(position);
  }

  @override
  void detach(ScrollPosition position) {
    super.detach(position);
    _parent?.detach(position);
  }

  @override
  void dispose() {
    if (_parent != null) {
      positions.forEach(_parent.detach);
    }
    super.dispose();
  }

  @override
  LinkedScrollPosition createScrollPosition(ScrollPhysics physics, ScrollContext context, ScrollPosition oldPosition) {
    return LinkedScrollPosition(
      this,
      physics: physics,
      context: context,
      initialPixels: initialScrollOffset,
      oldPosition: oldPosition,
    );
  }

  bool get canLinkWithBefore => before != null && before.hasClients;

  bool get canLinkWithAfter => after != null && after.hasClients;

  Iterable<LinkedScrollActivity> linkWithBefore(LinkedScrollPosition driver) {
    assert(canLinkWithBefore);
    return before.link(driver);
  }

  Iterable<LinkedScrollActivity> linkWithAfter(LinkedScrollPosition driver) {
    assert(canLinkWithAfter);
    return after.link(driver);
  }

  Iterable<LinkedScrollActivity> link(LinkedScrollPosition driver) sync* {
    assert(hasClients);
    for (LinkedScrollPosition position in positions)
      yield position.link(driver);
  }

  @override
  void debugFillDescription(List<String> description) {
    super.debugFillDescription(description);
    if (before != null && after != null) {
      description.add('links: ⬌');
    } else if (before != null) {
      description.add('links: ⬅');
    } else if (after != null) {
      description.add('links: ➡');
    } else {
      description.add('links: none');
    }
  }

}

class LinkedScrollPosition extends ScrollPositionWithSingleContext {
  LinkedScrollPosition(
    this.owner, {
    ScrollPhysics physics,
    ScrollContext context,
    double initialPixels,
    ScrollPosition oldPosition,
  }) : assert(owner != null),
       super(
         physics: physics,
         context: context,
         initialPixels: initialPixels,
         oldPosition: oldPosition,
       );

  final LinkedScrollController owner;

  Set<LinkedScrollActivity> _beforeActivities;
  Set<LinkedScrollActivity> _afterActivities;

  @override
  void beginActivity(ScrollActivity newActivity) {
    if (newActivity == null)
      return;
    if (_beforeActivities != null) {
      for (LinkedScrollActivity activity in _beforeActivities)
        activity.unlink(this);
      _beforeActivities.clear();
    }
    if (_afterActivities != null) {
      for (LinkedScrollActivity activity in _afterActivities)
        activity.unlink(this);
      _afterActivities.clear();
    }
    super.beginActivity(newActivity);
  }

  @override
  void applyUserOffset(double delta) {
    updateUserScrollDirection(delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse);
    final double value = pixels - physics.applyPhysicsToUserOffset(this, delta);

    if (value == pixels)
      return;

    double beforeOverscroll = 0.0;
    if (owner.canLinkWithBefore && (value < minScrollExtent)) {
      final double delta = value - minScrollExtent;
      _beforeActivities ??= HashSet<LinkedScrollActivity>();
      _beforeActivities.addAll(owner.linkWithBefore(this));
      for (LinkedScrollActivity activity in _beforeActivities)
        beforeOverscroll = math.min(activity.moveBy(delta), beforeOverscroll);
      assert(beforeOverscroll <= 0.0);
    }

    double afterOverscroll = 0.0;
    if (owner.canLinkWithAfter && (value > maxScrollExtent)) {
      final double delta = value - maxScrollExtent;
      _afterActivities ??= HashSet<LinkedScrollActivity>();
      _afterActivities.addAll(owner.linkWithAfter(this));
      for (LinkedScrollActivity activity in _afterActivities)
        afterOverscroll = math.max(activity.moveBy(delta), afterOverscroll);
      assert(afterOverscroll >= 0.0);
    }

    assert(beforeOverscroll == 0.0 || afterOverscroll == 0.0);

    final double localOverscroll = setPixels(value.clamp(
      owner.canLinkWithBefore ? minScrollExtent : -double.infinity,
      owner.canLinkWithAfter ? maxScrollExtent : double.infinity,
    ));

    assert(localOverscroll == 0.0 || (beforeOverscroll == 0.0 && afterOverscroll == 0.0));
  }

  void _userMoved(ScrollDirection direction) {
    updateUserScrollDirection(direction);
  }

  LinkedScrollActivity link(LinkedScrollPosition driver) {
    if (this.activity is! LinkedScrollActivity)
      beginActivity(LinkedScrollActivity(this));
    final LinkedScrollActivity activity = this.activity;
    activity.link(driver);
    return activity;
  }

  void unlink(LinkedScrollActivity activity) {
    if (_beforeActivities != null)
      _beforeActivities.remove(activity);
    if (_afterActivities != null)
      _afterActivities.remove(activity);
  }

  @override
  void debugFillDescription(List<String> description) {
    super.debugFillDescription(description);
    description.add('owner: $owner');
  }
}

class LinkedScrollActivity extends ScrollActivity {
  LinkedScrollActivity(
    LinkedScrollPosition delegate,
  ) : super(delegate);

  @override
  LinkedScrollPosition get delegate => super.delegate;

  final Set<LinkedScrollPosition> drivers = HashSet<LinkedScrollPosition>();

  void link(LinkedScrollPosition driver) {
    drivers.add(driver);
  }

  void unlink(LinkedScrollPosition driver) {
    drivers.remove(driver);
    if (drivers.isEmpty)
      delegate?.goIdle();
  }

  @override
  bool get shouldIgnorePointer => true;

  @override
  bool get isScrolling => true;

  // LinkedScrollActivity is not self-driven but moved by calls to the [moveBy]
  // method.
  @override
  double get velocity => 0.0;

  double moveBy(double delta) {
    assert(drivers.isNotEmpty);
    ScrollDirection commonDirection;
    for (LinkedScrollPosition driver in drivers) {
      commonDirection ??= driver.userScrollDirection;
      if (driver.userScrollDirection != commonDirection)
        commonDirection = ScrollDirection.idle;
    }
    delegate._userMoved(commonDirection);
    return delegate.setPixels(delegate.pixels + delta);
  }

  @override
  void dispose() {
    for (LinkedScrollPosition driver in drivers)
      driver.unlink(this);
    super.dispose();
  }
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  LinkedScrollController _beforeController;
  LinkedScrollController _afterController;

  @override
  void initState() {
    super.initState();
    _beforeController = LinkedScrollController();
    _afterController = LinkedScrollController(before: _beforeController);
    _beforeController.after = _afterController;
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _beforeController.setParent(PrimaryScrollController.of(context));
    _afterController.setParent(PrimaryScrollController.of(context));
  }

  @override
  void dispose() {
    _beforeController.dispose();
    _afterController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: Column(
        children: <Widget>[
          Expanded(
            child: ListView(
              controller: _beforeController,
              children: <Widget>[
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello A')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello B')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello C')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF90F090),
                  child: const Center(child: Text('Hello D')),
                ),
              ],
            ),
          ),
          const Divider(),
          Expanded(
            child: ListView(
              controller: _afterController,
              children: <Widget>[
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 1')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 2')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 3')),
                ),
                Container(
                  margin: const EdgeInsets.all(8.0),
                  padding: const EdgeInsets.all(8.0),
                  height: 250.0,
                  color: const Color(0xFF9090F0),
                  child: const Center(child: Text('Hello 4')),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  testWidgets('LinkedScrollController - 1', (WidgetTester tester) async {
    await tester.pumpWidget(Test());
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.fling(find.text('Hello A'), const Offset(0.0, -50.0), 10000.0);
    await tester.pumpAndSettle();
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello D'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello D'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 4'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello D'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello A'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello A'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 4'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 1'), const Offset(0.0, 10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 2));
    await tester.drag(find.text('Hello 1'), const Offset(0.0, -10000.0));
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 4'), findsOneWidget);
  });
  testWidgets('LinkedScrollController - 2', (WidgetTester tester) async {
    await tester.pumpWidget(Test());
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    final TestGesture gestureTop = await tester.startGesture(const Offset(200.0, 150.0));
    final TestGesture gestureBottom = await tester.startGesture(const Offset(600.0, 450.0));
    await tester.pump(const Duration(seconds: 1));
    await gestureTop.moveBy(const Offset(0.0, -270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, -270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsOneWidget);
    expect(find.text('Hello 4'), findsNothing);
    await gestureTop.moveBy(const Offset(0.0, -270.0));
    await gestureBottom.moveBy(const Offset(0.0, -270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsNothing);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsOneWidget);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello 2'), findsNothing);
    expect(find.text('Hello 3'), findsOneWidget);
    expect(find.text('Hello 4'), findsOneWidget);
    await gestureTop.moveBy(const Offset(0.0, 270.0));
    await gestureBottom.moveBy(const Offset(0.0, 270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsNothing);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsOneWidget);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 270.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsNothing);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsOneWidget);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureBottom.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await gestureTop.moveBy(const Offset(0.0, -270.0));
    expect(find.text('Hello A'), findsOneWidget);
    expect(find.text('Hello B'), findsOneWidget);
    expect(find.text('Hello C'), findsNothing);
    expect(find.text('Hello D'), findsNothing);
    expect(find.text('Hello 1'), findsOneWidget);
    expect(find.text('Hello 2'), findsOneWidget);
    expect(find.text('Hello 3'), findsNothing);
    expect(find.text('Hello 4'), findsNothing);
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 60));
  });
}
