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

/// @docImport 'package:flutter/material.dart';
///
/// @docImport 'monodrag.dart';
/// @docImport 'recognizer.dart';
/// @docImport 'tap.dart';
library;

import 'arena.dart';
import 'binding.dart';

export 'arena.dart' show GestureArenaEntry, GestureArenaMember;

class _CombiningGestureArenaEntry implements GestureArenaEntry {
  _CombiningGestureArenaEntry(this._combiner, this._member);

  final _CombiningGestureArenaMember _combiner;
  final GestureArenaMember _member;

  @override
  void resolve(GestureDisposition disposition) {
    _combiner._resolve(_member, disposition);
  }
}

class _CombiningGestureArenaMember extends GestureArenaMember {
  _CombiningGestureArenaMember(this._owner, this._pointer);

  final GestureArenaTeam _owner;
  final List<GestureArenaMember> _members = <GestureArenaMember>[];
  final int _pointer;

  bool _resolved = false;
  GestureArenaMember? _winner;
  GestureArenaEntry? _entry;

  @override
  void acceptGesture(int pointer) {
    assert(_pointer == pointer);
    assert(_winner != null || _members.isNotEmpty);
    _close();
    _winner ??= _owner.captain ?? _members[0];
    for (final GestureArenaMember member in _members) {
      if (member != _winner) {
        member.rejectGesture(pointer);
      }
    }
    _winner!.acceptGesture(pointer);
  }

  @override
  void rejectGesture(int pointer) {
    assert(_pointer == pointer);
    _close();
    for (final GestureArenaMember member in _members) {
      member.rejectGesture(pointer);
    }
  }

  void _close() {
    assert(!_resolved);
    _resolved = true;
    final _CombiningGestureArenaMember? combiner = _owner._combiners.remove(_pointer);
    assert(combiner == this);
  }

  GestureArenaEntry _add(int pointer, GestureArenaMember member) {
    assert(!_resolved);
    assert(_pointer == pointer);
    _members.add(member);
    _entry ??= GestureBinding.instance.gestureArena.add(pointer, this);
    return _CombiningGestureArenaEntry(this, member);
  }

  void _resolve(GestureArenaMember member, GestureDisposition disposition) {
    if (_resolved) {
      return;
    }
    switch (disposition) {
      case GestureDisposition.accepted:
        _winner ??= _owner.captain ?? member;
        _entry!.resolve(disposition);
      case GestureDisposition.rejected:
        _members.remove(member);
        member.rejectGesture(_pointer);
        if (_members.isEmpty) {
          _entry!.resolve(disposition);
        }
    }
  }
}

/// A group of [GestureArenaMember] objects that are competing as a unit in the
/// [GestureArenaManager].
///
/// Normally, a recognizer competes directly in the [GestureArenaManager] to
/// recognize a sequence of pointer events as a gesture. With a
/// [GestureArenaTeam], recognizers can compete in the arena in a group with
/// other recognizers. Arena teams may have a captain which wins the arena on
/// behalf of its team.
///
/// When gesture recognizers are in a team together without a captain, then once
/// there are no other competing gestures in the arena, the first gesture to
/// have been added to the team automatically wins, instead of the gestures
/// continuing to compete against each other.
///
/// When gesture recognizers are in a team with a captain, then once one of the
/// team members claims victory or there are no other competing gestures in the
/// arena, the captain wins the arena, and all other team members lose.
///
/// For example, [Slider] uses a team without a captain to support both a
/// [HorizontalDragGestureRecognizer] and a [TapGestureRecognizer], but without
/// the drag recognizer having to wait until the user has dragged outside the
/// slop region of the tap gesture before triggering. Since they compete as a
/// team, as soon as any other recognizers are out of the arena, the drag
/// recognizer wins, even if the user has not actually dragged yet. On the other
/// hand, if the tap can win outright, before the other recognizers are taken
/// out of the arena (e.g. if the slider is in a vertical scrolling list and the
/// user places their finger on the touch surface then lifts it, so that neither
/// the horizontal nor vertical drag recognizers can claim victory) the tap
/// recognizer still actually wins, despite being in the team.
///
/// [AndroidView] uses a team with a captain to decide which gestures are
/// forwarded to the native view. For example if we want to forward taps and
/// vertical scrolls to a native Android view, [TapGestureRecognizer]s and
/// [VerticalDragGestureRecognizer] are added to a team with a captain (the
/// captain is set to be a gesture recognizer that never explicitly claims the
/// gesture).
///
/// The captain allows [AndroidView] to know when any gestures in the team has
/// been recognized (or all other arena members are out), once the captain wins
/// the gesture is forwarded to the Android view.
///
/// To assign a gesture recognizer to a team, set
/// [OneSequenceGestureRecognizer.team] to an instance of [GestureArenaTeam].
class GestureArenaTeam {
  final Map<int, _CombiningGestureArenaMember> _combiners = <int, _CombiningGestureArenaMember>{};

  /// A member that wins on behalf of the entire team.
  ///
  /// If not null, when any one of the [GestureArenaTeam] members claims victory
  /// the captain accepts the gesture.
  /// If null, the member that claims a victory accepts the gesture.
  GestureArenaMember? captain;

  /// Adds a new member to the arena on behalf of this team.
  ///
  /// Used by [GestureRecognizer] subclasses that wish to compete in the arena
  /// using this team.
  ///
  /// To assign a gesture recognizer to a team, see
  /// [OneSequenceGestureRecognizer.team].
  GestureArenaEntry add(int pointer, GestureArenaMember member) {
    final _CombiningGestureArenaMember combiner = _combiners.putIfAbsent(
      pointer,
      () => _CombiningGestureArenaMember(this, pointer),
    );
    return combiner._add(pointer, member);
  }
}
