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

/**
 * Deprecated class. Please use [DateTime] instead.
 */
@deprecated
abstract class Date implements Comparable {
  // Weekday constants that are returned by [weekday] method:
  static const int MON = 1;
  static const int TUE = 2;
  static const int WED = 3;
  static const int THU = 4;
  static const int FRI = 5;
  static const int SAT = 6;
  static const int SUN = 7;
  static const int DAYS_IN_WEEK = 7;

  // Month constants that are returned by the [month] getter.
  static const int JAN = 1;
  static const int FEB = 2;
  static const int MAR = 3;
  static const int APR = 4;
  static const int MAY = 5;
  static const int JUN = 6;
  static const int JUL = 7;
  static const int AUG = 8;
  static const int SEP = 9;
  static const int OCT = 10;
  static const int NOV = 11;
  static const int DEC = 12;

  factory Date(int year,
               [int month = 1,
                int day = 1,
                int hour = 0,
                int minute = 0,
                int second = 0,
                int millisecond = 0]) {
    return new DateTime(year, month, day, hour, minute, second, millisecond);
  }

  factory Date.utc(int year,
                   [int month = 1,
                    int day = 1,
                    int hour = 0,
                    int minute = 0,
                    int second = 0,
                    int millisecond = 0]) {
    return
        new DateTime.utc(year, month, day, hour, minute, second, millisecond);
  }

  factory Date.now() => new DateTime.now();

  factory Date.fromString(String formattedString)
      => DateTime.parse(formattedString);

  factory Date.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
                                          {bool isUtc: false}) {
    return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
                                                   isUtc: isUtc);
  }

  bool operator ==(DateTime other);
  bool operator <(DateTime other);
  bool operator <=(DateTime other);
  bool operator >(DateTime other);
  bool operator >=(DateTime other);


  DateTime toLocal();
  DateTime toUtc();

  String get timeZoneName;
  Duration get timeZoneOffset;

  int get year;
  int get month;
  int get day;
  int get hour;
  int get minute;
  int get second;
  int get millisecond;

  int get weekday;

  int get millisecondsSinceEpoch;

  bool get isUtc;

  String toString();

  DateTime add(Duration duration);
  DateTime subtract(Duration duration);
  Duration difference(DateTime other);
}

/**
 * A DateTime object represents a point in time.
 *
 * It can represent time values that are at a distance of at most
 * 8,640,000,000,000,000ms (100,000,000 days) from epoch (1970-01-01 UTC). In
 * other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
 *
 * Also see [Stopwatch] for means to measure time-spans.
 */
class DateTime implements Date {
  // Weekday constants that are returned by [weekday] method:
  static const int MON = 1;
  static const int TUE = 2;
  static const int WED = 3;
  static const int THU = 4;
  static const int FRI = 5;
  static const int SAT = 6;
  static const int SUN = 7;
  static const int DAYS_IN_WEEK = 7;

  // Month constants that are returned by the [month] getter.
  static const int JAN = 1;
  static const int FEB = 2;
  static const int MAR = 3;
  static const int APR = 4;
  static const int MAY = 5;
  static const int JUN = 6;
  static const int JUL = 7;
  static const int AUG = 8;
  static const int SEP = 9;
  static const int OCT = 10;
  static const int NOV = 11;
  static const int DEC = 12;

  /**
   * The milliseconds since 1970-01-01T00:00:00Z (UTC). This value is
   * independent of the time zone.
   *
   * See [Stopwatch] for means to measure time-spans.
   */
  final int millisecondsSinceEpoch;

  /**
   * True if this [DateTime] is set to UTC time.
   */
  final bool isUtc;

  /**
   * Constructs a [DateTime] instance based on the individual parts. The date is
   * in the local time zone.
   *
   * [month] and [day] are one-based. For example
   * [:new DateTime(1938, 1, 10):] represents the 10th of January 1938.
   */
  // TODO(8042): This should be a redirecting constructor and not a factory.
  factory DateTime(int year,
           [int month = 1,
            int day = 1,
            int hour = 0,
            int minute = 0,
            int second = 0,
            int millisecond = 0]) {
    return new DateTime._internal(
          year, month, day, hour, minute, second, millisecond, false);
  }

  /**
   * Constructs a [DateTime] instance based on the individual parts. The date is
   * in the UTC time zone.
   *
   * [month] and [day] are one-based. For example
   * [:new DateTime.utc(1938, 1, 10):] represents the 10th of January 1938 in
   * Coordinated Universal Time.
   */
  // TODO(8042): This should be a redirecting constructor and not a factory.
  factory DateTime.utc(int year,
                       [int month = 1,
                        int day = 1,
                        int hour = 0,
                        int minute = 0,
                        int second = 0,
                        int millisecond = 0]) {
    return new DateTime._internal(
          year, month, day, hour, minute, second, millisecond, true);
  }

  /**
   * Constructs a new [DateTime] instance with current date time value in the
   * local time zone.
   */
  // TODO(8042): This should be a redirecting constructor and not a factory.
  factory DateTime.now() { return new DateTime._now(); }

  /**
   * Constructs a new [DateTime] instance based on [formattedString].
   *
   * The function parses a subset of ISO 8601. Examples of accepted strings:
   *
   * * `"2012-02-27 13:27:00"`
   * * `"2012-02-27 13:27:00.123456z"`
   * * `"20120227 13:27:00"`
   * * `"20120227T132700"`
   * * `"20120227"`
   * * `"+20120227"`
   * * `"2012-02-27T14Z"`
   * * `"-123450101 00:00:00 Z"`: in the year -12345.
   */
  // TODO(floitsch): specify grammar.
  static DateTime parse(String formattedString) {
    final RegExp re = new RegExp(
        r'^([+-]?\d?\d\d\d\d)-?(\d\d)-?(\d\d)'  // The day part.
        r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(.\d{1,6})?)?)? ?([zZ])?)?$');
    Match match = re.firstMatch(formattedString);
    if (match != null) {
      int parseIntOrZero(String matched) {
        if (matched == null) return 0;
        return int.parse(matched);
      }

      double parseDoubleOrZero(String matched) {
        if (matched == null) return 0.0;
        return double.parse(matched);
      }

      int years = int.parse(match[1]);
      int month = int.parse(match[2]);
      int day = int.parse(match[3]);
      int hour = parseIntOrZero(match[4]);
      int minute = parseIntOrZero(match[5]);
      int second = parseIntOrZero(match[6]);
      bool addOneMillisecond = false;
      int millisecond = (parseDoubleOrZero(match[7]) * 1000).round().toInt();
      if (millisecond == 1000) {
        addOneMillisecond = true;
        millisecond = 999;
      }
      // TODO(floitsch): we should not need to test against the empty string.
      bool isUtc = (match[8] != null) && (match[8] != "");
      int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
          years, month, day, hour, minute, second, millisecond, isUtc);
      if (millisecondsSinceEpoch == null) {
        throw new ArgumentError(formattedString);
      }
      if (addOneMillisecond) millisecondsSinceEpoch++;
      return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
                                                     isUtc: isUtc);
    } else {
      throw new ArgumentError(formattedString);
    }
  }

  static const int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;

  /**
   * Constructs a new [DateTime] instance with the given [millisecondsSinceEpoch].
   * If [isUtc] is false then the date is in the local time zone.
   *
   * The constructed [DateTime] represents
   * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch]ms in the given
   * time zone (local or UTC).
   */
  // TODO(lrn): Have two constructors instead of taking an optional bool.
  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
                                      {bool isUtc: false})
      : this.millisecondsSinceEpoch = millisecondsSinceEpoch,
        this.isUtc = isUtc {
    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
      throw new ArgumentError(millisecondsSinceEpoch);
    }
    if (isUtc == null) throw new ArgumentError(isUtc);
  }

  /**
   * Returns true if [other] is a [DateTime] at the same moment and in the
   * same timezone (UTC or local).
   *
   * See [isAtSameMomentAs] for a comparison that ignores the timezone.
   */
  bool operator ==(other) {
    if (!(other is DateTime)) return false;
    return (millisecondsSinceEpoch == other.millisecondsSinceEpoch &&
            isUtc == other.isUtc);
  }

  /**
   * Returns true if [this] occurs before [other]. The comparison is independent
   * of whether the time is in UTC or in the local time zone.
   *
   * *Deprecated* Use [isBefore] instead.
   */
  @deprecated
  bool operator <(DateTime other)
      => millisecondsSinceEpoch < other.millisecondsSinceEpoch;

  /**
   * Returns true if [this] occurs at the same time or before [other]. The
   * comparison is independent of whether the time is in UTC or in the local
   * time zone.
   *
   * *Deprecated* Use [isAfter] instead ([:!isAfter:]).
   */
  @deprecated
  bool operator <=(DateTime other)
      => millisecondsSinceEpoch <= other.millisecondsSinceEpoch;

  /**
   * Returns true if [this] occurs after [other]. The comparison is independent
   * of whether the time is in UTC or in the local time zone.
   *
   * *Deprecated* Use [isAfter] instead.
   */
  @deprecated
  bool operator >(DateTime other)
      => millisecondsSinceEpoch > other.millisecondsSinceEpoch;

  /**
   * Returns true if [this] occurs at the same time or after [other]. The
   * comparison is independent of whether the time is in UTC or in the local
   * time zone.
   *
   * *Deprecated* Use [isBefore] instead ([:!isBefore:]).
   */
  @deprecated
  bool operator >=(DateTime other)
      => millisecondsSinceEpoch >= other.millisecondsSinceEpoch;

  /**
   * Returns true if [this] occurs before [other]. The comparison is independent
   * of whether the time is in UTC or in the local time zone.
   */
  bool isBefore(DateTime other) {
    return millisecondsSinceEpoch < other.millisecondsSinceEpoch;
  }

  /**
   * Returns true if [this] occurs after [other]. The comparison is independent
   * of whether the time is in UTC or in the local time zone.
   */
  bool isAfter(DateTime other) {
    return millisecondsSinceEpoch > other.millisecondsSinceEpoch;
  }

  /**
   * Returns true if [this] occurs at the same moment as [other]. The
   * comparison is independent of whether the time is in UTC or in the local
   * time zone.
   */
  bool isAtSameMomentAs(DateTime other) {
    return millisecondsSinceEpoch == other.millisecondsSinceEpoch;
  }

  int compareTo(DateTime other)
      => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);

  int get hashCode => millisecondsSinceEpoch;

  /**
   * Returns [this] in the local time zone. Returns itself if it is already in
   * the local time zone. Otherwise, this method is equivalent to
   *
   *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
   *                                             isUtc: false)
   */
  DateTime toLocal() {
    if (isUtc) {
      return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
                                                     isUtc: false);
    }
    return this;
  }

  /**
   * Returns [this] in UTC. Returns itself if it is already in UTC. Otherwise,
   * this method is equivalent to
   *
   *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
   *                                             isUtc: true)
   */
  DateTime toUtc() {
    if (isUtc) return this;
    return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
                                                   isUtc: true);
  }

  /**
   * Returns a human readable string for this instance.
   * The returned string is constructed for the time zone of this instance.
   */
  String toString() {
    String fourDigits(int n) {
      int absN = n.abs();
      String sign = n < 0 ? "-" : "";
      if (absN >= 1000) return "$n";
      if (absN >= 100) return "${sign}0$absN";
      if (absN >= 10) return "${sign}00$absN";
      return "${sign}000$absN";
    }

    String threeDigits(int n) {
      if (n >= 100) return "${n}";
      if (n >= 10) return "0${n}";
      return "00${n}";
    }

    String twoDigits(int n) {
      if (n >= 10) return "${n}";
      return "0${n}";
    }

    String y = fourDigits(year);
    String m = twoDigits(month);
    String d = twoDigits(day);
    String h = twoDigits(hour);
    String min = twoDigits(minute);
    String sec = twoDigits(second);
    String ms = threeDigits(millisecond);
    if (isUtc) {
      return "$y-$m-$d $h:$min:$sec.${ms}Z";
    } else {
      return "$y-$m-$d $h:$min:$sec.$ms";
    }
  }

  /** Returns a new [DateTime] with the [duration] added to [this]. */
  DateTime add(Duration duration) {
    int ms = millisecondsSinceEpoch;
    return new DateTime.fromMillisecondsSinceEpoch(
        ms + duration.inMilliseconds, isUtc: isUtc);
  }

  /** Returns a new [DateTime] with the [duration] subtracted from [this]. */
  DateTime subtract(Duration duration) {
    int ms = millisecondsSinceEpoch;
    return new DateTime.fromMillisecondsSinceEpoch(
        ms - duration.inMilliseconds, isUtc: isUtc);
  }

  /** Returns a [Duration] with the difference of [this] and [other]. */
  Duration difference(DateTime other) {
    int ms = millisecondsSinceEpoch;
    int otherMs = other.millisecondsSinceEpoch;
    return new Duration(milliseconds: ms - otherMs);
  }

  external DateTime._internal(int year,
                              int month,
                              int day,
                              int hour,
                              int minute,
                              int second,
                              int millisecond,
                              bool isUtc);
  external DateTime._now();
  external static int _brokenDownDateToMillisecondsSinceEpoch(
      int year, int month, int day, int hour, int minute, int second,
      int millisecond, bool isUtc);

  /**
   * Returns the abbreviated time-zone name.
   *
   * Examples: [:"CET":] or [:"CEST":].
   */
  external String get timeZoneName;

  /**
   * The time-zone offset is the difference between local time and UTC. That is,
   * the offset is positive for time zones west of UTC.
   *
   * Note, that JavaScript, Python and C return the difference between UTC and
   * local time. Java, C# and Ruby return the difference between local time and
   * UTC.
   */
  external Duration get timeZoneOffset;

  /**
   * Returns the year.
   */
  external int get year;

  /**
   * Returns the month into the year [1..12].
   */
  external int get month;

  /**
   * Returns the day into the month [1..31].
   */
  external int get day;

  /**
   * Returns the hour into the day [0..23].
   */
  external int get hour;

  /**
   * Returns the minute into the hour [0...59].
   */
  external int get minute;

  /**
   * Returns the second into the minute [0...59].
   */
  external int get second;

  /**
   * Returns the millisecond into the second [0...999].
   */
  external int get millisecond;

  /**
   * Returns the week day [MON..SUN]. In accordance with ISO 8601
   * a week starts with Monday which has the value 1.
   */
  external int get weekday;
}
