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

// 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));
  });
}
