// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.core;

/**
 * A simple stopwatch interface to measure elapsed time.
 */
class Stopwatch {
  /**
   * Cached frequency of the system. Must be initialized in [_initTicker];
   */
  static int _frequency;

  // The _start and _stop fields capture the time when [start] and [stop]
  // are called respectively.
  // If _stop is null, the stopwatched is running.
  int _start = 0;
  int _stop = 0;

  /**
   * Creates a [Stopwatch] in stopped state with a zero elapsed count.
   *
   * The following example shows how to start a [Stopwatch]
   * immediately after allocation.
   * ```
   * var stopwatch = new Stopwatch()..start();
   * ```
   */
  Stopwatch() {
    if (_frequency == null) _initTicker();
  }

  /**
   * Frequency of the elapsed counter in Hz.
   */
  int get frequency => _frequency;

  /**
   * Starts the [Stopwatch].
   *
   * The [elapsed] count is increasing monotonically. If the [Stopwatch] has
   * been stopped, then calling start again restarts it without resetting the
   * [elapsed] count.
   *
   * If the [Stopwatch] is currently running, then calling start does nothing.
   */
  void start() {
    if (_stop != null) {
      // (Re)start this stopwatch.
      // Don't count the time while the stopwatch has been stopped.
      _start += _now() - _stop;
      _stop = null;
    }
  }

  /**
   * Stops the [Stopwatch].
   *
   * The [elapsedTicks] count stops increasing after this call. If the
   * [Stopwatch] is currently not running, then calling this method has no
   * effect.
   */
  void stop() {
    _stop ??= _now();
  }

  /**
   * Resets the [elapsed] count to zero.
   *
   * This method does not stop or start the [Stopwatch].
   */
  void reset() {
    _start = _stop ?? _now();
  }

  /**
   * The elapsed number of clock ticks since calling [start] while the
   * [Stopwatch] is running.
   *
   * This is the elapsed number of clock ticks between calling [start] and
   * calling [stop].
   *
   * Is 0 if the [Stopwatch] has never been started.
   *
   * The elapsed number of clock ticks increases by [frequency] every second.
   */
  int get elapsedTicks {
    return (_stop ?? _now()) - _start;
  }

  /**
   * The [elapsedTicks] counter converted to a [Duration].
   */
  Duration get elapsed {
    return new Duration(microseconds: elapsedMicroseconds);
  }

  /**
   * The [elapsedTicks] counter converted to microseconds.
   */
  int get elapsedMicroseconds {
    return (elapsedTicks * 1000000) ~/ frequency;
  }

  /**
   * The [elapsedTicks] counter converted to milliseconds.
   */
  int get elapsedMilliseconds {
    return (elapsedTicks * 1000) ~/ frequency;
  }


  /**
   * Whether the [StopWatch] is currently running.
   */
  bool get isRunning => _stop == null;

  /**
   * Initializes the time-measuring system. *Must* initialize the [_frequency]
   * variable.
   */
  external static void _initTicker();
  external static int _now();
}
