// Copyright 2014 The Flutter 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 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart' as intl;

import 'l10n/generated_cupertino_localizations.dart';
import 'utils/date_localizations.dart' as util;
import 'widgets_localizations.dart';

/// Implementation of localized strings for Cupertino widgets using the `intl`
/// package for date and time formatting.
///
/// Further localization of strings beyond date time formatting are provided
/// by language specific subclasses of [GlobalCupertinoLocalizations].
///
/// ## Supported languages
///
/// This class supports locales with the following [Locale.languageCode]s:
///
/// {@macro flutter.localizations.cupertino.languages}
///
/// This list is available programmatically via [kCupertinoSupportedLanguages].
///
/// ## Sample code
///
/// To include the localizations provided by this class in a [CupertinoApp],
/// add [GlobalCupertinoLocalizations.delegates] to
/// [CupertinoApp.localizationsDelegates], and specify the locales your
/// app supports with [CupertinoApp.supportedLocales]:
///
/// ```dart
/// new CupertinoApp(
///   localizationsDelegates: GlobalCupertinoLocalizations.delegates,
///   supportedLocales: [
///     const Locale('en', 'US'), // American English
///     const Locale('he', 'IL'), // Israeli Hebrew
///     // ...
///   ],
///   // ...
/// )
/// ```
///
/// See also:
///
///  * [DefaultCupertinoLocalizations], which provides US English localizations
///    for Cupertino widgets.
abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
  /// Initializes an object that defines the Cupertino widgets' localized
  /// strings for the given `localeName`.
  ///
  /// The remaining '*Format' arguments uses the intl package to provide
  /// [DateFormat] configurations for the `localeName`.
  const GlobalCupertinoLocalizations({
    @required String localeName,
    @required intl.DateFormat fullYearFormat,
    @required intl.DateFormat dayFormat,
    @required intl.DateFormat mediumDateFormat,
    @required intl.DateFormat singleDigitHourFormat,
    @required intl.DateFormat singleDigitMinuteFormat,
    @required intl.DateFormat doubleDigitMinuteFormat,
    @required intl.DateFormat singleDigitSecondFormat,
    @required intl.NumberFormat decimalFormat,
  }) : assert(localeName != null),
       _localeName = localeName,
       assert(fullYearFormat != null),
       _fullYearFormat = fullYearFormat,
       assert(dayFormat != null),
       _dayFormat = dayFormat,
       assert(mediumDateFormat != null),
       _mediumDateFormat = mediumDateFormat,
       assert(singleDigitHourFormat != null),
       _singleDigitHourFormat = singleDigitHourFormat,
       assert(singleDigitMinuteFormat != null),
       _singleDigitMinuteFormat = singleDigitMinuteFormat,
       assert(doubleDigitMinuteFormat != null),
       _doubleDigitMinuteFormat = doubleDigitMinuteFormat,
       assert(singleDigitSecondFormat != null),
       _singleDigitSecondFormat = singleDigitSecondFormat,
       assert(decimalFormat != null),
       _decimalFormat =decimalFormat;

  final String _localeName;
  final intl.DateFormat _fullYearFormat;
  final intl.DateFormat _dayFormat;
  final intl.DateFormat _mediumDateFormat;
  final intl.DateFormat _singleDigitHourFormat;
  final intl.DateFormat _singleDigitMinuteFormat;
  final intl.DateFormat _doubleDigitMinuteFormat;
  final intl.DateFormat _singleDigitSecondFormat;
  final intl.NumberFormat _decimalFormat;

  @override
  String datePickerYear(int yearIndex) {
    return _fullYearFormat.format(DateTime.utc(yearIndex));
  }

  @override
  String datePickerMonth(int monthIndex) {
    // It doesn't actually have anything to do with _fullYearFormat. It's just
    // taking advantage of the fact that _fullYearFormat loaded the needed
    // locale's symbols.
    return _fullYearFormat.dateSymbols.MONTHS[monthIndex - 1];
  }

  @override
  String datePickerDayOfMonth(int dayIndex) {
    // Year and month doesn't matter since we just want to day formatted.
    return _dayFormat.format(DateTime.utc(0, 0, dayIndex));
  }

  @override
  String datePickerMediumDate(DateTime date) {
    return _mediumDateFormat.format(date);
  }

  @override
  String datePickerHour(int hour) {
    return _singleDigitHourFormat.format(DateTime.utc(0, 0, 0, hour));
  }

  @override
  String datePickerMinute(int minute) {
    return _doubleDigitMinuteFormat.format(DateTime.utc(0, 0, 0, 0, minute));
  }

  /// Subclasses should provide the optional zero pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected String get datePickerHourSemanticsLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected String get datePickerHourSemanticsLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected String get datePickerHourSemanticsLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected String get datePickerHourSemanticsLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected String get datePickerHourSemanticsLabelMany => null;
  /// Subclasses should provide the required other pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected String get datePickerHourSemanticsLabelOther;

  @override
  String datePickerHourSemanticsLabel(int hour) {
    return intl.Intl.pluralLogic(
      hour,
      zero: datePickerHourSemanticsLabelZero,
      one: datePickerHourSemanticsLabelOne,
      two: datePickerHourSemanticsLabelTwo,
      few: datePickerHourSemanticsLabelFew,
      many: datePickerHourSemanticsLabelMany,
      other: datePickerHourSemanticsLabelOther,
      locale: _localeName,
    ).replaceFirst(r'$hour', _decimalFormat.format(hour));
  }

  /// Subclasses should provide the optional zero pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected String get datePickerMinuteSemanticsLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected String get datePickerMinuteSemanticsLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected String get datePickerMinuteSemanticsLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected String get datePickerMinuteSemanticsLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected String get datePickerMinuteSemanticsLabelMany => null;
  /// Subclasses should provide the required other pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected String get datePickerMinuteSemanticsLabelOther;

  @override
  String datePickerMinuteSemanticsLabel(int minute) {
    return intl.Intl.pluralLogic(
      minute,
      zero: datePickerMinuteSemanticsLabelZero,
      one: datePickerMinuteSemanticsLabelOne,
      two: datePickerMinuteSemanticsLabelTwo,
      few: datePickerMinuteSemanticsLabelFew,
      many: datePickerMinuteSemanticsLabelMany,
      other: datePickerMinuteSemanticsLabelOther,
      locale: _localeName,
    ).replaceFirst(r'$minute', _decimalFormat.format(minute));
  }

  /// A string describing the [DatePickerDateOrder] enum value.
  ///
  /// Subclasses should provide this string value based on the ARB file for
  /// the locale.
  ///
  /// See also:
  ///
  ///  * [datePickerDateOrder], which provides the [DatePickerDateOrder]
  ///    enum value for [CupertinoLocalizations] based on this string value
  @protected
  String get datePickerDateOrderString;

  @override
  DatePickerDateOrder get datePickerDateOrder {
    switch (datePickerDateOrderString) {
      case 'dmy':
        return DatePickerDateOrder.dmy;
      case 'mdy':
        return DatePickerDateOrder.mdy;
      case 'ymd':
        return DatePickerDateOrder.ymd;
      case 'ydm':
        return DatePickerDateOrder.ydm;
      default:
        assert(
          false,
          'Failed to load DatePickerDateOrder $datePickerDateOrderString for '
          "locale $_localeName.\nNon conforming string for $_localeName's "
          '.arb file',
        );
        return null;
    }
  }

  /// A string describing the [DatePickerDateTimeOrder] enum value.
  ///
  /// Subclasses should provide this string value based on the ARB file for
  /// the locale.
  ///
  /// See also:
  ///
  ///  * [datePickerDateTimeOrder], which provides the [DatePickerDateTimeOrder]
  ///    enum value for [CupertinoLocalizations] based on this string value.
  @protected
  String get datePickerDateTimeOrderString;

  @override
  DatePickerDateTimeOrder get datePickerDateTimeOrder {
    switch (datePickerDateTimeOrderString) {
      case 'date_time_dayPeriod':
        return DatePickerDateTimeOrder.date_time_dayPeriod;
      case 'date_dayPeriod_time':
        return DatePickerDateTimeOrder.date_dayPeriod_time;
      case 'time_dayPeriod_date':
        return DatePickerDateTimeOrder.time_dayPeriod_date;
      case 'dayPeriod_time_date':
        return DatePickerDateTimeOrder.dayPeriod_time_date;
      default:
        assert(
          false,
          'Failed to load DatePickerDateTimeOrder $datePickerDateTimeOrderString '
          "for locale $_localeName.\nNon conforming string for $_localeName's "
          '.arb file',
        );
        return null;
    }
  }

  /// The raw version of [tabSemanticsLabel], with `$tabIndex` and `$tabCount` verbatim
  /// in the string.
  @protected
  String get tabSemanticsLabelRaw;

  @override
  String tabSemanticsLabel({ int tabIndex, int tabCount }) {
    assert(tabIndex >= 1);
    assert(tabCount >= 1);
    final String template = tabSemanticsLabelRaw;
    return template
      .replaceFirst(r'$tabIndex', _decimalFormat.format(tabIndex))
      .replaceFirst(r'$tabCount', _decimalFormat.format(tabCount));
  }

  @override
  String timerPickerHour(int hour) {
    return _singleDigitHourFormat.format(DateTime.utc(0, 0, 0, hour));
  }

  @override
  String timerPickerMinute(int minute) {
    return _singleDigitMinuteFormat.format(DateTime.utc(0, 0, 0, 0, minute));
  }

  @override
  String timerPickerSecond(int second) {
    return _singleDigitSecondFormat.format(DateTime.utc(0, 0, 0, 0, 0, second));
  }

  /// Subclasses should provide the optional zero pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected String get timerPickerHourLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected String get timerPickerHourLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected String get timerPickerHourLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected String get timerPickerHourLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected String get timerPickerHourLabelMany => null;
  /// Subclasses should provide the required other pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected String get timerPickerHourLabelOther;

  @override
  String timerPickerHourLabel(int hour) {
    return intl.Intl.pluralLogic(
      hour,
      zero: timerPickerHourLabelZero,
      one: timerPickerHourLabelOne,
      two: timerPickerHourLabelTwo,
      few: timerPickerHourLabelFew,
      many: timerPickerHourLabelMany,
      other: timerPickerHourLabelOther,
      locale: _localeName,
    ).replaceFirst(r'$hour', _decimalFormat.format(hour));
  }

  /// Subclasses should provide the optional zero pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected String get timerPickerMinuteLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected String get timerPickerMinuteLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected String get timerPickerMinuteLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected String get timerPickerMinuteLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected String get timerPickerMinuteLabelMany => null;
  /// Subclasses should provide the required other pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected String get timerPickerMinuteLabelOther;

  @override
  String timerPickerMinuteLabel(int minute) {
    return intl.Intl.pluralLogic(
      minute,
      zero: timerPickerMinuteLabelZero,
      one: timerPickerMinuteLabelOne,
      two: timerPickerMinuteLabelTwo,
      few: timerPickerMinuteLabelFew,
      many: timerPickerMinuteLabelMany,
      other: timerPickerMinuteLabelOther,
      locale: _localeName,
    ).replaceFirst(r'$minute', _decimalFormat.format(minute));
  }

  /// Subclasses should provide the optional zero pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected String get timerPickerSecondLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected String get timerPickerSecondLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected String get timerPickerSecondLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected String get timerPickerSecondLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected String get timerPickerSecondLabelMany => null;
  /// Subclasses should provide the required other pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected String get timerPickerSecondLabelOther;

  @override
  String timerPickerSecondLabel(int second) {
    return intl.Intl.pluralLogic(
      second,
      zero: timerPickerSecondLabelZero,
      one: timerPickerSecondLabelOne,
      two: timerPickerSecondLabelTwo,
      few: timerPickerSecondLabelFew,
      many: timerPickerSecondLabelMany,
      other: timerPickerSecondLabelOther,
      locale: _localeName,
    ).replaceFirst(r'$second', _decimalFormat.format(second));
  }

  /// A [LocalizationsDelegate] for [CupertinoLocalizations].
  ///
  /// Most internationalized apps will use [GlobalCupertinoLocalizations.delegates]
  /// as the value of [CupertinoApp.localizationsDelegates] to include
  /// the localizations for both the cupertino and widget libraries.
  static const LocalizationsDelegate<CupertinoLocalizations> delegate = _GlobalCupertinoLocalizationsDelegate();

  /// A value for [CupertinoApp.localizationsDelegates] that's typically used by
  /// internationalized apps.
  ///
  /// ## Sample code
  ///
  /// To include the localizations provided by this class and by
  /// [GlobalWidgetsLocalizations] in a [CupertinoApp],
  /// use [GlobalCupertinoLocalizations.delegates] as the value of
  /// [CupertinoApp.localizationsDelegates], and specify the locales your
  /// app supports with [CupertinoApp.supportedLocales]:
  ///
  /// ```dart
  /// new CupertinoApp(
  ///   localizationsDelegates: GlobalCupertinoLocalizations.delegates,
  ///   supportedLocales: [
  ///     const Locale('en', 'US'), // English
  ///     const Locale('he', 'IL'), // Hebrew
  ///   ],
  ///   // ...
  /// )
  /// ```
  static const List<LocalizationsDelegate<dynamic>> delegates = <LocalizationsDelegate<dynamic>>[
    GlobalCupertinoLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ];
}

class _GlobalCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
  const _GlobalCupertinoLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => kCupertinoSupportedLanguages.contains(locale.languageCode);

  static final Map<Locale, Future<CupertinoLocalizations>> _loadedTranslations = <Locale, Future<CupertinoLocalizations>>{};

  @override
  Future<CupertinoLocalizations> load(Locale locale) {
    assert(isSupported(locale));
    return _loadedTranslations.putIfAbsent(locale, () {
      util.loadDateIntlDataIfNotLoaded();

      final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
      assert(
        locale.toString() == localeName,
        'Flutter does not support the non-standard locale form $locale (which '
        'might be $localeName',
      );

      intl.DateFormat fullYearFormat;
      intl.DateFormat dayFormat;
      intl.DateFormat mediumDateFormat;
      // We don't want any additional decoration here. The am/pm is handled in
      // the date picker. We just want an hour number localized.
      intl.DateFormat singleDigitHourFormat;
      intl.DateFormat singleDigitMinuteFormat;
      intl.DateFormat doubleDigitMinuteFormat;
      intl.DateFormat singleDigitSecondFormat;
      intl.NumberFormat decimalFormat;

      void loadFormats(String locale) {
        fullYearFormat = intl.DateFormat.y(locale);
        dayFormat = intl.DateFormat.d(locale);
        mediumDateFormat = intl.DateFormat.MMMEd(locale);
        // TODO(xster): fix when https://github.com/dart-lang/intl/issues/207 is resolved.
        singleDigitHourFormat = intl.DateFormat('HH', locale);
        singleDigitMinuteFormat = intl.DateFormat.m(locale);
        doubleDigitMinuteFormat = intl.DateFormat('mm', locale);
        singleDigitSecondFormat = intl.DateFormat.s(locale);
        decimalFormat = intl.NumberFormat.decimalPattern(locale);
      }

      if (intl.DateFormat.localeExists(localeName)) {
        loadFormats(localeName);
      } else if (intl.DateFormat.localeExists(locale.languageCode)) {
        loadFormats(locale.languageCode);
      } else {
        loadFormats(null);
      }

      return SynchronousFuture<CupertinoLocalizations>(getCupertinoTranslation(
        locale,
        fullYearFormat,
        dayFormat,
        mediumDateFormat,
        singleDigitHourFormat,
        singleDigitMinuteFormat,
        doubleDigitMinuteFormat,
        singleDigitSecondFormat,
        decimalFormat,
      ));
    });
  }

  @override
  bool shouldReload(_GlobalCupertinoLocalizationsDelegate old) => false;

  @override
  String toString() => 'GlobalCupertinoLocalizations.delegate(${kCupertinoSupportedLanguages.length} locales)';
}
