// 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/foundation.dart';

import 'animation.dart';

export 'dart:ui' show VoidCallback;

export 'animation.dart' show AnimationStatus, AnimationStatusListener;

/// A mixin that helps listen to another object only when this object has registered listeners.
///
/// This mixin provides implementations of [didRegisterListener] and [didUnregisterListener],
/// and therefore can be used in conjunction with mixins that require these methods,
/// [AnimationLocalListenersMixin] and [AnimationLocalStatusListenersMixin].
mixin AnimationLazyListenerMixin {
  int _listenerCounter = 0;

  /// Calls [didStartListening] every time a registration of a listener causes
  /// an empty list of listeners to become non-empty.
  ///
  /// See also:
  ///
  ///  * [didUnregisterListener], which may cause the listener list to
  ///    become empty again, and in turn cause this method to call
  ///    [didStartListening] again.
  @protected
  void didRegisterListener() {
    assert(_listenerCounter >= 0);
    if (_listenerCounter == 0) {
      didStartListening();
    }
    _listenerCounter += 1;
  }

  /// Calls [didStopListening] when an only remaining listener is unregistered,
  /// thus making the list empty.
  ///
  /// See also:
  ///
  ///  * [didRegisterListener], which causes the listener list to become non-empty.
  @protected
  void didUnregisterListener() {
    assert(_listenerCounter >= 1);
    _listenerCounter -= 1;
    if (_listenerCounter == 0) {
      didStopListening();
    }
  }

  /// Called when the number of listeners changes from zero to one.
  @protected
  void didStartListening();

  /// Called when the number of listeners changes from one to zero.
  @protected
  void didStopListening();

  /// Whether there are any listeners.
  bool get isListening => _listenerCounter > 0;
}

/// A mixin that replaces the [didRegisterListener]/[didUnregisterListener] contract
/// with a dispose contract.
///
/// This mixin provides implementations of [didRegisterListener] and [didUnregisterListener],
/// and therefore can be used in conjunction with mixins that require these methods,
/// [AnimationLocalListenersMixin] and [AnimationLocalStatusListenersMixin].
mixin AnimationEagerListenerMixin {
  /// This implementation ignores listener registrations.
  @protected
  void didRegisterListener() { }

  /// This implementation ignores listener registrations.
  @protected
  void didUnregisterListener() { }

  /// Release the resources used by this object. The object is no longer usable
  /// after this method is called.
  @mustCallSuper
  void dispose() { }
}

/// A mixin that implements the [addListener]/[removeListener] protocol and notifies
/// all the registered listeners when [notifyListeners] is called.
///
/// This mixin requires that the mixing class provide methods [didRegisterListener]
/// and [didUnregisterListener]. Implementations of these methods can be obtained
/// by mixing in another mixin from this library, such as [AnimationLazyListenerMixin].
mixin AnimationLocalListenersMixin {
  final ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();

  /// Called immediately before a listener is added via [addListener].
  ///
  /// At the time this method is called the registered listener is not yet
  /// notified by [notifyListeners].
  @protected
  void didRegisterListener();

  /// Called immediately after a listener is removed via [removeListener].
  ///
  /// At the time this method is called the removed listener is no longer
  /// notified by [notifyListeners].
  @protected
  void didUnregisterListener();

  /// Calls the listener every time the value of the animation changes.
  ///
  /// Listeners can be removed with [removeListener].
  void addListener(VoidCallback listener) {
    didRegisterListener();
    _listeners.add(listener);
  }

  /// Stop calling the listener every time the value of the animation changes.
  ///
  /// Listeners can be added with [addListener].
  void removeListener(VoidCallback listener) {
    final bool removed = _listeners.remove(listener);
    if (removed) {
      didUnregisterListener();
    }
  }

  /// Removes all listeners added with [addListener].
  ///
  /// This method is typically called from the `dispose` method of the class
  /// using this mixin if the class also uses the [AnimationEagerListenerMixin].
  ///
  /// Calling this method will not trigger [didUnregisterListener].
  @protected
  void clearListeners() {
    _listeners.clear();
  }

  /// Calls all the listeners.
  ///
  /// If listeners are added or removed during this function, the modifications
  /// will not change which listeners are called during this iteration.
  @protected
  @pragma('vm:notify-debugger-on-exception')
  void notifyListeners() {
    final List<VoidCallback> localListeners = _listeners.toList(growable: false);
    for (final VoidCallback listener in localListeners) {
      InformationCollector? collector;
      assert(() {
        collector = () => <DiagnosticsNode>[
          DiagnosticsProperty<AnimationLocalListenersMixin>(
            'The $runtimeType notifying listeners was',
            this,
            style: DiagnosticsTreeStyle.errorProperty,
          ),
        ];
        return true;
      }());
      try {
        if (_listeners.contains(listener)) {
          listener();
        }
      } catch (exception, stack) {
        FlutterError.reportError(FlutterErrorDetails(
          exception: exception,
          stack: stack,
          library: 'animation library',
          context: ErrorDescription('while notifying listeners for $runtimeType'),
          informationCollector: collector,
        ));
      }
    }
  }
}

/// A mixin that implements the addStatusListener/removeStatusListener protocol
/// and notifies all the registered listeners when notifyStatusListeners is
/// called.
///
/// This mixin requires that the mixing class provide methods [didRegisterListener]
/// and [didUnregisterListener]. Implementations of these methods can be obtained
/// by mixing in another mixin from this library, such as [AnimationLazyListenerMixin].
mixin AnimationLocalStatusListenersMixin {
  final ObserverList<AnimationStatusListener> _statusListeners = ObserverList<AnimationStatusListener>();

  /// Called immediately before a status listener is added via [addStatusListener].
  ///
  /// At the time this method is called the registered listener is not yet
  /// notified by [notifyStatusListeners].
  @protected
  void didRegisterListener();

  /// Called immediately after a status listener is removed via [removeStatusListener].
  ///
  /// At the time this method is called the removed listener is no longer
  /// notified by [notifyStatusListeners].
  @protected
  void didUnregisterListener();

  /// Calls listener every time the status of the animation changes.
  ///
  /// Listeners can be removed with [removeStatusListener].
  void addStatusListener(AnimationStatusListener listener) {
    didRegisterListener();
    _statusListeners.add(listener);
  }

  /// Stops calling the listener every time the status of the animation changes.
  ///
  /// Listeners can be added with [addStatusListener].
  void removeStatusListener(AnimationStatusListener listener) {
    final bool removed = _statusListeners.remove(listener);
    if (removed) {
      didUnregisterListener();
    }
  }

  /// Removes all listeners added with [addStatusListener].
  ///
  /// This method is typically called from the `dispose` method of the class
  /// using this mixin if the class also uses the [AnimationEagerListenerMixin].
  ///
  /// Calling this method will not trigger [didUnregisterListener].
  @protected
  void clearStatusListeners() {
    _statusListeners.clear();
  }

  /// Calls all the status listeners.
  ///
  /// If listeners are added or removed during this function, the modifications
  /// will not change which listeners are called during this iteration.
  @protected
  @pragma('vm:notify-debugger-on-exception')
  void notifyStatusListeners(AnimationStatus status) {
    final List<AnimationStatusListener> localListeners = _statusListeners.toList(growable: false);
    for (final AnimationStatusListener listener in localListeners) {
      try {
        if (_statusListeners.contains(listener)) {
          listener(status);
        }
      } catch (exception, stack) {
        InformationCollector? collector;
        assert(() {
          collector = () => <DiagnosticsNode>[
            DiagnosticsProperty<AnimationLocalStatusListenersMixin>(
              'The $runtimeType notifying status listeners was',
              this,
              style: DiagnosticsTreeStyle.errorProperty,
            ),
          ];
          return true;
        }());
        FlutterError.reportError(FlutterErrorDetails(
          exception: exception,
          stack: stack,
          library: 'animation library',
          context: ErrorDescription('while notifying status listeners for $runtimeType'),
          informationCollector: collector,
        ));
      }
    }
  }
}
