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

import 'package:flutter/rendering.dart';

import 'framework.dart';

/// A container that handles [SelectionEvent]s for the [Selectable]s in
/// the subtree.
///
/// This widget is useful when one wants to customize selection behaviors for
/// a group of [Selectable]s
///
/// The state of this container is a single selectable and will register
/// itself to the [registrar] if provided. Otherwise, it will register to the
/// [SelectionRegistrar] from the context. Consider using a [SelectionArea]
/// widget to provide a root registrar.
///
/// The containers handle the [SelectionEvent]s from the registered
/// [SelectionRegistrar] and delegate the events to the [delegate].
///
/// This widget uses [SelectionRegistrarScope] to host the [delegate] as the
/// [SelectionRegistrar] for the subtree to collect the [Selectable]s, and
/// [SelectionEvent]s received by this container are sent to the [delegate] using
/// the [SelectionHandler] API of the delegate.
///
/// {@tool dartpad}
/// This sample demonstrates how to create a [SelectionContainer] that only
/// allows selecting everything or nothing with no partial selection.
///
/// ** See code in examples/api/lib/material/selection_container/selection_container.0.dart **
/// {@end-tool}
///
/// See also:
///  * [SelectableRegion], which provides an overview of the selection system.
///  * [SelectionContainer.disabled], which disable selection for a
///    subtree.
class SelectionContainer extends StatefulWidget {
  /// Creates a selection container to collect the [Selectable]s in the subtree.
  ///
  /// If [registrar] is not provided, this selection container gets the
  /// [SelectionRegistrar] from the context instead.
  ///
  /// The [delegate] and [child] must not be null.
  const SelectionContainer({
    super.key,
    this.registrar,
    required SelectionContainerDelegate this.delegate,
    required this.child,
  }) : assert(delegate != null),
       assert(child != null);

  /// Creates a selection container that disables selection for the
  /// subtree.
  ///
  /// {@tool dartpad}
  /// This sample demonstrates how to disable selection for a Text under a
  /// SelectionArea.
  ///
  /// ** See code in examples/api/lib/material/selection_container/selection_container_disabled.0.dart **
  /// {@end-tool}
  ///
  /// The [child] must not be null.
  const SelectionContainer.disabled({
    super.key,
    required this.child,
  }) : registrar = null,
       delegate = null;

  /// The [SelectionRegistrar] this container is registered to.
  ///
  /// If null, this widget gets the [SelectionRegistrar] from the current
  /// context.
  final SelectionRegistrar? registrar;

  /// {@macro flutter.widgets.ProxyWidget.child}
  final Widget child;

  /// The delegate for [SelectionEvent]s sent to this selection container.
  ///
  /// The [Selectable]s in the subtree are added or removed from this delegate
  /// using [SelectionRegistrar] API.
  ///
  /// This delegate is responsible for updating the selections for the selectables
  /// under this widget.
  final SelectionContainerDelegate? delegate;

  /// Gets the immediate ancestor [SelectionRegistrar] of the [BuildContext].
  ///
  /// If this returns null, either there is no [SelectionContainer] above
  /// the [BuildContext] or the immediate [SelectionContainer] is not
  /// enabled.
  static SelectionRegistrar? maybeOf(BuildContext context) {
    final SelectionRegistrarScope? scope = context.dependOnInheritedWidgetOfExactType<SelectionRegistrarScope>();
    return scope?.registrar;
  }

  bool get _disabled => delegate == null;

  @override
  State<SelectionContainer> createState() => _SelectionContainerState();
}

class _SelectionContainerState extends State<SelectionContainer> with Selectable, SelectionRegistrant {
  final Set<VoidCallback> _listeners = <VoidCallback>{};

  static const SelectionGeometry _disabledGeometry = SelectionGeometry(
    status: SelectionStatus.none,
    hasContent: true,
  );

  @override
  void initState() {
    super.initState();
    if (!widget._disabled) {
      widget.delegate!._selectionContainerContext = context;
      if (widget.registrar != null) {
        registrar = widget.registrar;
      }
    }
  }

  @override
  void didUpdateWidget(SelectionContainer oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.delegate != widget.delegate) {
      if (!oldWidget._disabled) {
        oldWidget.delegate!._selectionContainerContext = null;
        _listeners.forEach(oldWidget.delegate!.removeListener);
      }
      if (!widget._disabled) {
        widget.delegate!._selectionContainerContext = context;
        _listeners.forEach(widget.delegate!.addListener);
      }
      if (oldWidget.delegate?.value != widget.delegate?.value) {
        for (final VoidCallback listener in _listeners) {
          listener();
        }
      }
    }
    if (widget._disabled) {
      registrar = null;
    } else if (widget.registrar != null) {
      registrar = widget.registrar;
    }
    assert(!widget._disabled || registrar == null);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (widget.registrar == null && !widget._disabled) {
      registrar = SelectionContainer.maybeOf(context);
    }
    assert(!widget._disabled || registrar == null);
  }

  @override
  void addListener(VoidCallback listener) {
    assert(!widget._disabled);
    widget.delegate!.addListener(listener);
    _listeners.add(listener);
  }

  @override
  void removeListener(VoidCallback listener) {
    widget.delegate?.removeListener(listener);
    _listeners.remove(listener);
  }

  @override
  void pushHandleLayers(LayerLink? startHandle, LayerLink? endHandle) {
    assert(!widget._disabled);
    widget.delegate!.pushHandleLayers(startHandle, endHandle);
  }

  @override
  SelectedContent? getSelectedContent() {
    assert(!widget._disabled);
    return widget.delegate!.getSelectedContent();
  }

  @override
  SelectionResult dispatchSelectionEvent(SelectionEvent event) {
    assert(!widget._disabled);
    return widget.delegate!.dispatchSelectionEvent(event);
  }

  @override
  SelectionGeometry get value {
    if (widget._disabled) {
      return _disabledGeometry;
    }
    return widget.delegate!.value;
  }

  @override
  Matrix4 getTransformTo(RenderObject? ancestor) {
    assert(!widget._disabled);
    return context.findRenderObject()!.getTransformTo(ancestor);
  }

  @override
  Size get size => (context.findRenderObject()! as RenderBox).size;

  @override
  void dispose() {
    if (!widget._disabled) {
      widget.delegate!._selectionContainerContext = null;
      _listeners.forEach(widget.delegate!.removeListener);
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (widget._disabled) {
      return SelectionRegistrarScope._disabled(child: widget.child);
    }
    return SelectionRegistrarScope(
      registrar: widget.delegate!,
      child: widget.child,
    );
  }
}

/// An inherited widget to host a [SelectionRegistrar] for the subtree.
///
/// Use [SelectionContainer.maybeOf] to get the SelectionRegistrar from
/// a context.
///
/// This widget is automatically created as part of [SelectionContainer] and
/// is generally not used directly, except for disabling selection for a part
/// of subtree. In that case, one can wrap the subtree with
/// [SelectionContainer.disabled].
class SelectionRegistrarScope extends InheritedWidget {
  /// Creates a selection registrar scope that host the [registrar].
  const SelectionRegistrarScope({
    super.key,
    required SelectionRegistrar this.registrar,
    required super.child,
  }) : assert(registrar != null);

  /// Creates a selection registrar scope that disables selection for the
  /// subtree.
  const SelectionRegistrarScope._disabled({
    required super.child,
  }) : registrar = null;

  /// The [SelectionRegistrar] hosted by this widget.
  final SelectionRegistrar? registrar;

  @override
  bool updateShouldNotify(SelectionRegistrarScope oldWidget) {
    return oldWidget.registrar != registrar;
  }
}

/// A delegate to handle [SelectionEvent]s for a [SelectionContainer].
///
/// This delegate needs to implement [SelectionRegistrar] to register
/// [Selectable]s in the [SelectionContainer] subtree.
abstract class SelectionContainerDelegate implements SelectionHandler, SelectionRegistrar {
  BuildContext? _selectionContainerContext;

  /// Gets the paint transform from the [Selectable] child to
  /// [SelectionContainer] of this delegate.
  ///
  /// Returns a matrix that maps the [Selectable] paint coordinate system to the
  /// coordinate system of [SelectionContainer].
  ///
  /// Can only be called after [SelectionContainer] is laid out.
  Matrix4 getTransformFrom(Selectable child) {
    assert(
      _selectionContainerContext?.findRenderObject() != null,
      'getTransformFrom cannot be called before SelectionContainer is laid out.',
    );
    return child.getTransformTo(_selectionContainerContext!.findRenderObject()! as RenderBox);
  }

  /// Gets the paint transform from the [SelectionContainer] of this delegate to
  /// the `ancestor`.
  ///
  /// Returns a matrix that maps the [SelectionContainer] paint coordinate
  /// system to the coordinate system of `ancestor`.
  ///
  /// If `ancestor` is null, this method returns a matrix that maps from the
  /// local paint coordinate system to the coordinate system of the
  /// [PipelineOwner.rootNode].
  ///
  /// Can only be called after [SelectionContainer] is laid out.
  Matrix4 getTransformTo(RenderObject? ancestor) {
    assert(
      _selectionContainerContext?.findRenderObject() != null,
      'getTransformTo cannot be called before SelectionContainer is laid out.',
    );
    final RenderBox box = _selectionContainerContext!.findRenderObject()! as RenderBox;
    return box.getTransformTo(ancestor);
  }

  /// Gets the size of the [SelectionContainer] of this delegate.
  ///
  /// Can only be called after [SelectionContainer] is laid out.
  Size get containerSize {
    assert(
      _selectionContainerContext?.findRenderObject() != null,
      'containerSize cannot be called before SelectionContainer is laid out.',
    );
    final RenderBox box = _selectionContainerContext!.findRenderObject()! as RenderBox;
    return box.size;
  }
}
