// Copyright (c) 2012, 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 intl;

/**
 * This is a private class internal to DateFormat which is used for formatting
 * particular fields in a template. e.g. if the format is hh:mm:ss then the
 * fields would be "hh", ":", "mm", ":", and "ss". Each type of field knows
 * how to format that portion of a date.
 */
abstract class _DateFormatField {
  /** The format string that defines us, e.g. "hh" */
  String pattern;

  /** The DateFormat that we are part of.*/
  DateFormat parent;

  _DateFormatField(this.pattern, this.parent);

  /**
   * Return the width of [pattern]. Different widths represent different
   * formatting options. See the comment for DateFormat for details.
   */
  int get width => pattern.length;

  String fullPattern() => pattern;

  String toString() => pattern;

  /** Format date according to our specification and return the result. */
  String format(DateTime date) {
    // Default implementation in the superclass, works for both types of
    // literal patterns, and is overridden by _DateFormatPatternField.
    return pattern;
  }

  /** Abstract method for subclasses to implementing parsing for their format.*/
  void parse(_Stream input, _DateBuilder dateFields);

  /**
   * Abstract method for subclasses to implementing 'loose' parsing for
   * their format, accepting input case-insensitively, and allowing some
   * delimiters to be skipped.
   */
  void parseLoose(_Stream input, _DateBuilder dateFields);

  /** Parse a literal field. We just look for the exact input. */
  void parseLiteral(_Stream input) {
    var found = input.read(width);
    if (found != pattern) {
      throwFormatException(input);
    }
  }

  /**
   * Parse a literal field. We accept either an exact match, or an arbitrary
   * amount of whitespace.
   */
  void parseLiteralLoose(_Stream input) {
    var found = input.peek(width);
    if (found == pattern) {
      input.read(width);
    }
    while (!input.atEnd() && input.peek().trim().isEmpty) {
      input.read();
    }
  }

  /** Throw a format exception with an error message indicating the position.*/
  void throwFormatException(_Stream stream) {
    throw new FormatException("Trying to read $this from ${stream.contents} "
        "at position ${stream.index}");
  }
}

/**
 * Represents a literal field - a sequence of characters that doesn't
 * change according to the date's data. As such, the implementation
 * is extremely simple.
 */
class _DateFormatLiteralField extends _DateFormatField {

  _DateFormatLiteralField(pattern, parent): super(pattern, parent);

  parse(_Stream input, _DateBuilder dateFields) {
    parseLiteral(input);
  }

  parseLoose(_Stream input, _DateBuilder dateFields) =>
    parseLiteralLoose(input);
}

/**
 * Represents a literal field with quoted characters in it. This is
 * only slightly more complex than a _DateFormatLiteralField.
 */
class _DateFormatQuotedField extends _DateFormatField {

  String _fullPattern;

  String fullPattern() => _fullPattern;

  _DateFormatQuotedField(pattern, parent): super(pattern, parent) {
    _fullPattern = pattern;
    patchQuotes();
  }

  parse(_Stream input, _DateBuilder dateFields) {
    parseLiteral(input);
  }

  parseLoose(_Stream input, _DateBuilder dateFields) =>
    parseLiteralLoose(input);

  void patchQuotes() {
    if (pattern == "''") {
      pattern = "'";
    } else {
      pattern = pattern.substring(1, pattern.length - 1);
      var twoEscapedQuotes = new RegExp(r"''");
      pattern = pattern.replaceAll(twoEscapedQuotes, "'");
    }
  }
}

/**
 * A field that parses "loosely", meaning that we'll accept input that is
 * missing delimiters, has upper/lower case mixed up, and might not strictly
 * conform to the pattern, e.g. the pattern calls for Sep we might accept
 * sep, september, sEPTember. Doesn't affect numeric fields.
 */
class _LoosePatternField extends _DateFormatPatternField {
  _LoosePatternField(String pattern, parent) : super(pattern, parent);

   /**
    * Parse from a list of possibilities, but case-insensitively.
    * Assumes that input is lower case.
    */
   int parseEnumeratedString(_Stream input, List possibilities) {
     var lowercasePossibilities = possibilities
         .map((x) => x.toLowerCase())
         .toList();
     try {
       return super.parseEnumeratedString(input, lowercasePossibilities);
     } on FormatException {
       return -1;
     }
   }

  /**
   * Parse a month name, case-insensitively, and set it in [dateFields].
   * Assumes that [input] is lower case.
   */
  void parseMonth(input, dateFields) {
    if (width <= 2) {
      handleNumericField(input, dateFields.setMonth);
      return;
    }
    var possibilities =
        [symbols.MONTHS, symbols.SHORTMONTHS];
    for (var monthNames in possibilities) {
      var month = parseEnumeratedString(input, monthNames);
      if (month != -1) {
        dateFields.month = month + 1;
        return;
      }
    }
  }

  /**
   * Parse a standalone day name, case-insensitively.
   * Assumes that input is lower case. Doesn't do anything
   */
  void parseStandaloneDay(input) {
    // This is ignored, but we still have to skip over it the correct amount.
    if (width <= 2) {
      handleNumericField(input, (x) => x);
      return;
    }
    var possibilities =
        [symbols.STANDALONEWEEKDAYS, symbols.STANDALONESHORTWEEKDAYS];
    for (var dayNames in possibilities) {
       var day = parseEnumeratedString(input, dayNames);
       if (day != -1) {
         return;
       }
     }
  }

  /**
   * Parse a standalone month name, case-insensitively.
   * Assumes that input is lower case. Doesn't do anything
   */
  void parseStandaloneMonth(input, dateFields) {
    if (width <= 2) {
      handleNumericField(input, (x) => x);
      return;
    }
    var possibilities =
        [symbols.STANDALONEMONTHS, symbols.STANDALONESHORTMONTHS];
    for (var monthNames in possibilities) {
      var month = parseEnumeratedString(input, monthNames);
      if (month != -1) {
        dateFields.month = month + 1;
        return;
      }
    }
  }

  /**
   * Parse a day of the week name, case-insensitively.
   * Assumes that input is lower case. Doesn't do anything
   */
  void parseDayOfWeek(_Stream input) {
    // This is IGNORED, but we still have to skip over it the correct amount.
    if (width <= 2) {
      handleNumericField(input, (x) => x);
      return;
    }
    var possibilities = [symbols.WEEKDAYS, symbols.SHORTWEEKDAYS];
    for (var dayNames in possibilities) {
       var day = parseEnumeratedString(input, dayNames);
       if (day != -1) {
         return;
       }
     }
  }
}

/*
 * Represents a field in the pattern that formats some aspect of the
 * date. Consists primarily of a switch on the particular pattern characters
 * to determine what to do.
 */
class _DateFormatPatternField extends _DateFormatField {

  _DateFormatPatternField(pattern, parent): super(pattern,  parent);

  /** Format date according to our specification and return the result. */
  String format(DateTime date) {
    return formatField(date);
  }

  /**
   * Parse the date according to our specification and put the result
   * into the correct place in dateFields.
   */
  void parse(_Stream input, _DateBuilder dateFields) {
    parseField(input, dateFields);
  }


  /**
   * Parse the date according to our specification and put the result
   * into the correct place in dateFields. Allow looser parsing, accepting
   * case-insensitive input and skipped delimiters.
   */
  void parseLoose(_Stream input, _DateBuilder dateFields) {
    new _LoosePatternField(pattern, parent).parse(input, dateFields);
  }

  /**
   * Parse a field representing part of a date pattern. Note that we do not
   * return a value, but rather build up the result in [builder].
   */
  void parseField(_Stream input, _DateBuilder builder) {
   try {
     switch(pattern[0]) {
       case 'a': parseAmPm(input, builder); break;
       case 'c': parseStandaloneDay(input); break;
       case 'd': handleNumericField(input, builder.setDay); break; // day
       // Day of year. Setting month=January with any day of the year works
       case 'D': handleNumericField(input, builder.setDay); break; // dayofyear
       case 'E': parseDayOfWeek(input); break;
       case 'G': break; // era
       case 'h': parse1To12Hours(input, builder); break;
       case 'H': handleNumericField(input, builder.setHour); break; // hour 0-23
       case 'K': handleNumericField(input, builder.setHour); break; //hour 0-11
       case 'k': handleNumericField(input, builder.setHour,-1); break; //hr 1-24
       case 'L': parseStandaloneMonth(input, builder); break;
       case 'M': parseMonth(input, builder); break;
       case 'm': handleNumericField(input, builder.setMinute); break; // minutes
       case 'Q': break; // quarter
       case 'S': handleNumericField(input, builder.setFractionalSecond); break;
       case 's': handleNumericField(input, builder.setSecond); break;
       case 'v': break; // time zone id
       case 'y': handleNumericField(input, builder.setYear); break;
       case 'z': break; // time zone
       case 'Z': break; // time zone RFC
       default: return;
     }
   } catch (e) { throwFormatException(input); }
 }

  /** Formatting logic if we are of type FIELD */
  String formatField(DateTime date) {
     switch (pattern[0]) {
      case 'a': return formatAmPm(date);
      case 'c': return formatStandaloneDay(date);
      case 'd': return formatDayOfMonth(date);
      case 'D': return formatDayOfYear(date);
      case 'E': return formatDayOfWeek(date);
      case 'G': return formatEra(date);
      case 'h': return format1To12Hours(date);
      case 'H': return format0To23Hours(date);
      case 'K': return format0To11Hours(date);
      case 'k': return format24Hours(date);
      case 'L': return formatStandaloneMonth(date);
      case 'M': return formatMonth(date);
      case 'm': return formatMinutes(date);
      case 'Q': return formatQuarter(date);
      case 'S': return formatFractionalSeconds(date);
      case 's': return formatSeconds(date);
      case 'v': return formatTimeZoneId(date);
      case 'y': return formatYear(date);
      case 'z': return formatTimeZone(date);
      case 'Z': return formatTimeZoneRFC(date);
      default: return '';
    }
  }

  /** Return the symbols for our current locale. */
  DateSymbols get symbols => dateTimeSymbols[parent.locale];

  formatEra(DateTime date) {
    var era = date.year > 0 ? 1 : 0;
    return width >= 4 ? symbols.ERANAMES[era] :
                        symbols.ERAS[era];
  }

  formatYear(DateTime date) {
    // TODO(alanknight): Proper handling of years <= 0
    var year = date.year;
    if (year < 0) {
      year = -year;
    }
    return width == 2 ? padTo(2, year % 100) : padTo(width, year);
  }

  /**
   * We are given [input] as a stream from which we want to read a date. We
   * can't dynamically build up a date, so we are given a list [dateFields] of
   * the constructor arguments and an [position] at which to set it
   * (year,month,day,hour,minute,second,fractionalSecond)
   * then after all parsing is done we construct a date from the arguments.
   * This method handles reading any of the numeric fields. The [offset]
   * argument allows us to compensate for zero-based versus one-based values.
   */
  void handleNumericField(_Stream input, Function setter, [int offset = 0]) {
    var result = input.nextInteger();
    if (result == null) throwFormatException(input);
    setter(result + offset);
  }

  /**
   * We are given [input] as a stream from which we want to read a date. We
   * can't dynamically build up a date, so we are given a list [dateFields] of
   * the constructor arguments and an [position] at which to set it
   * (year,month,day,hour,minute,second,fractionalSecond)
   * then after all parsing is done we construct a date from the arguments.
   * This method handles reading any of string fields from an enumerated set.
   */
   int parseEnumeratedString(_Stream input, List possibilities) {
     var results = new _Stream(possibilities).findIndexes(
       (each) => input.peek(each.length) == each);
     if (results.isEmpty) throwFormatException(input);
     results.sort(
       (a, b) => possibilities[a].length.compareTo(possibilities[b].length));
     var longestResult = results.last;
     input.read(possibilities[longestResult].length);
     return longestResult;
     }

  String formatMonth(DateTime date) {
    switch (width) {
      case 5: return symbols.NARROWMONTHS[date.month-1];
      case 4: return symbols.MONTHS[date.month-1];
      case 3: return symbols.SHORTMONTHS[date.month-1];
      default:
        return padTo(width, date.month);
    }
  }

  void parseMonth(input, dateFields) {
    var possibilities;
    switch(width) {
      case 5: possibilities = symbols.NARROWMONTHS; break;
      case 4: possibilities = symbols.MONTHS; break;
      case 3: possibilities = symbols.SHORTMONTHS; break;
      default: return handleNumericField(input, dateFields.setMonth);
    }
    dateFields.month = parseEnumeratedString(input, possibilities) + 1;
  }

  String format24Hours(DateTime date) {
    return padTo(width, date.hour);
  }

  String formatFractionalSeconds(DateTime date) {
    // Always print at least 3 digits. If the width is greater, append 0s
    var basic = padTo(3, date.millisecond);
    if (width - 3 > 0) {
      var extra = padTo(width - 3, 0);
      return basic + extra;
    } else {
      return basic;
    }
  }

  String formatAmPm(DateTime date) {
    var hours = date.hour;
    var index = (date.hour >= 12) && (date.hour < 24) ? 1 : 0;
    var ampm = symbols.AMPMS;
    return ampm[index];
  }

  void parseAmPm(input, dateFields) {
    // If we see a "PM" note it in an extra field.
    var ampm = parseEnumeratedString(input, symbols.AMPMS);
    if (ampm == 1) dateFields.pm = true;
  }

  String format1To12Hours(DateTime date) {
    var hours = date.hour;
    if (date.hour > 12) hours = hours - 12;
    if (hours == 0) hours = 12;
    return padTo(width, hours);
  }

  void parse1To12Hours(_Stream input, _DateBuilder dateFields) {
    handleNumericField(input, dateFields.setHour);
    if (dateFields.hour == 12) dateFields.hour = 0;
  }

  String format0To11Hours(DateTime date) {
    return padTo(width, date.hour % 12);
  }

  String format0To23Hours(DateTime date) {
    return padTo(width, date.hour);
  }

  String formatStandaloneDay(DateTime date) {
    switch (width) {
      case 5: return symbols.STANDALONENARROWWEEKDAYS[date.weekday % 7];
      case 4: return symbols.STANDALONEWEEKDAYS[date.weekday % 7];
      case 3: return symbols.STANDALONESHORTWEEKDAYS[date.weekday % 7];
      default:
        return padTo(1, date.day);
    }
  }

  void parseStandaloneDay(_Stream input) {
    // This is ignored, but we still have to skip over it the correct amount.
    var possibilities;
    switch(width) {
      case 5: possibilities = symbols.STANDALONENARROWWEEKDAYS; break;
      case 4: possibilities = symbols.STANDALONEWEEKDAYS; break;
      case 3: possibilities = symbols.STANDALONESHORTWEEKDAYS; break;
      default: return handleNumericField(input, (x)=>x);
    }
    parseEnumeratedString(input, possibilities);
  }

  String formatStandaloneMonth(DateTime date) {
  switch (width) {
    case 5:
      return symbols.STANDALONENARROWMONTHS[date.month-1];
    case 4:
      return symbols.STANDALONEMONTHS[date.month-1];
    case 3:
      return symbols.STANDALONESHORTMONTHS[date.month-1];
    default:
      return padTo(width, date.month);
    }
  }

  void parseStandaloneMonth(input, dateFields) {
    var possibilities;
    switch(width) {
      case 5: possibilities = symbols.STANDALONENARROWMONTHS; break;
      case 4: possibilities = symbols.STANDALONEMONTHS; break;
      case 3: possibilities = symbols.STANDALONESHORTMONTHS; break;
      default: return handleNumericField(input, dateFields.setMonth);
    }
    dateFields.month = parseEnumeratedString(input, possibilities) + 1;
  }

  String formatQuarter(DateTime date) {
    var quarter = ((date.month - 1) / 3).truncate();
    if (width < 4) {
      return symbols.SHORTQUARTERS[quarter];
    } else {
      return symbols.QUARTERS[quarter];
    }
  }
  String formatDayOfMonth(DateTime date) {
    return padTo(width, date.day);
  }

  String formatDayOfYear(DateTime date) => padTo(width, dayNumberInYear(date));

  /** Return the ordinal day, i.e. the day number in the year. */
  int dayNumberInYear(DateTime date) {
    if (date.month == 1) return date.day;
    if (date.month == 2) return date.day + 31;
    return ordinalDayFromMarchFirst(date) + 59 + (isLeapYear(date) ? 1 : 0);
  }

  /**
   * Return the day of the year counting March 1st as 1, after which the
   * number of days per month is constant, so it's easier to calculate.
   * Formula from http://en.wikipedia.org/wiki/Ordinal_date
   */
  int ordinalDayFromMarchFirst(DateTime date) =>
      ((30.6 * date.month) - 91.4).floor() + date.day;

  /**
   * Return true if this is a leap year. Rely on [DateTime] to do the
   * underlying calculation, even though it doesn't expose the test to us.
   */
  bool isLeapYear(DateTime date) {
    var feb29 = new DateTime(date.year, 2, 29);
    return feb29.month == 2;
  }

  String formatDayOfWeek(DateTime date) {
    // Note that Dart's weekday returns 1 for Monday and 7 for Sunday.
    return (width >= 4 ? symbols.WEEKDAYS :
                        symbols.SHORTWEEKDAYS)[(date.weekday) % 7];
  }

  void parseDayOfWeek(_Stream input) {
    // This is IGNORED, but we still have to skip over it the correct amount.
    var possibilities = width >= 4 ? symbols.WEEKDAYS : symbols.SHORTWEEKDAYS;
    parseEnumeratedString(input, possibilities);
  }

  String formatMinutes(DateTime date) {
    return padTo(width, date.minute);
  }

  String formatSeconds(DateTime date) {
    return padTo(width, date.second);
  }

  String formatTimeZoneId(DateTime date) {
    // TODO(alanknight): implement time zone support
    throw new UnimplementedError();
  }

  String formatTimeZone(DateTime date) {
    throw new UnimplementedError();
  }

  String formatTimeZoneRFC(DateTime date) {
    throw new UnimplementedError();
  }

  /**
  * Return a string representation of the object padded to the left with
  * zeros. Primarily useful for numbers.
  */
  String padTo(int width, Object toBePrinted) {
    var basicString = toBePrinted.toString();
    if (basicString.length >= width) return basicString;
    var buffer = new StringBuffer();
    for (var i = 0; i < width - basicString.length; i++) {
      buffer.write('0');
    }
    buffer.write(basicString);
    return buffer.toString();
  }
}
