// 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 'dart:async';

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)';
}
