// 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 {
  // The _start and _stop fields capture the time when [start] and [stop]
  // are called respectively.
  // If _start is null, then the [Stopwatch] has not been started yet.
  // If _stop is null, then the [Stopwatch] has not been stopped yet,
  // or is running.
  int _start;
  int _stop;

  /**
   * Creates a [Stopwatch] in stopped state with a zero elapsed count.
   *
   * The following example shows how to start a [Stopwatch]
   * right after allocation.
   *
   *     Stopwatch stopwatch = new Stopwatch()..start();
   */
  Stopwatch() : _start = null, _stop = null {}

  /**
   * 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 (isRunning) return;
    if (_start == null) {
      // This stopwatch has never been started.
      _start = _now();
    } else {
      // Restart this stopwatch. Prepend the elapsed time to the current
      // start time.
      _start = _now() - (_stop - _start);
      _stop = null;
    }
  }

  /**
   * Stops the [Stopwatch]. The [elapsed] count stops increasing.
   * If the [Stopwatch] is currently not running, then calling stop does
   * nothing.
   */
  void stop() {
    if (!isRunning) return;
    _stop = _now();
  }

  /**
   * Resets the [elapsed] count to zero. This method does not stop or start
   * the [Stopwatch].
   */
  void reset() {
    if (_start == null) return;
    // If [_start] is not null, then the stopwatch had already been started. It
    // may running right now.
    _start = _now();
    if (_stop != null) {
      // The watch is not running. So simply set the [_stop] to [_start] thus
      // having an elapsed time of 0.
      _stop = _start;
    }
  }

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

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

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

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

  /**
   * Returns wether the [StopWatch] is currently running.
   */
  bool get isRunning => _start != null && _stop == null;

  external static int _frequency();
  external static int _now();
}
