// Copyright 2017 The Fuchsia 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 'dart:async';

import 'package:lib.mediaplayer.dart/audio_player_controller.dart';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

/// Notifier for animating widgets that reflect player progress. This class
/// can be used with |AnimatedBuilder| to create widgets that animate based on
/// the progress of an |AudioPlayerController| or |MediaPlayerController|.
/// Builders should call either |withResolution| or |withExcursion|, typically
/// when setting |AnimatedBuilder.animation|. Builders that call those methods
/// should run when the controller updates. This is because |ProgressNotifier|
/// doesn't allow for transitions such as play/pause or seeking. It needs the
/// one of the 'with' methods to be called when those transitions occur.
class ProgressNotifier extends ChangeNotifier {
  AudioPlayerController _controller;
  Duration _resolution;
  Timer _timer;
  bool _disposed = false;

  /// Constructs a |ProgressNotifier|.
  ProgressNotifier(this._controller) : assert(_controller != null);

  @override
  void dispose() {
    _disposed = true;
    _controller = null;
    _timer?.cancel();
    _timer = null;
    super.dispose();
  }

  /// Registers a one-time progress callback with the controller.
  void _register() {
    if (!_controller.playing) {
      _timer = null;
      return;
    }

    // TODO(dalesat): Take the rate into account once we support that.

    int resolutionMicroseconds = _resolution.inMicroseconds;
    int delayMicroseconds = resolutionMicroseconds -
        (_controller.progress.inMicroseconds % resolutionMicroseconds);

    _timer = Timer(Duration(microseconds: delayMicroseconds), () {
      _timer = null;

      if (_disposed || !_controller.playing) {
        return;
      }

      notifyListeners();
      _register();
    });
  }

  /// Sets the resolution and returns this |ProgressNotifier|. This method
  /// should be called in a builder that runs when the controller notifies of
  /// a state change.
  // ignore: avoid_returning_this
  ProgressNotifier withResolution(Duration resolution) {
    if (_disposed) {
      return this;
    }

    if (_timer == null || _resolution != resolution) {
      _resolution = resolution;
      _timer?.cancel();
      _register();
    }

    return this;
  }

  /// Sets the excursion and returns this |ProgressNotifier|. This method
  /// should be called in a builder that runs when the controller notifies of
  /// a state change. This method is useful for sliders where |excursion| is
  /// the distance the slider moves. Use |LayoutBuilder| to get the width of
  /// the slider.
  ProgressNotifier withExcursion(double excursion, BuildContext context) {
    double effectiveExcursion =
        excursion * MediaQuery.of(context).devicePixelRatio;
    return withResolution(Duration(
        microseconds:
            (_controller.duration.inMicroseconds / effectiveExcursion).ceil()));
  }
}
