// 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;

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

/// Implementation of localized strings for the material widgets using the
/// `intl` package for date and time formatting.
///
/// ## Supported languages
///
/// This class supports locales with the following [Locale.languageCode]s:
///
/// {@macro flutter.localizations.material.languages}
///
/// This list is available programmatically via [kMaterialSupportedLanguages].
///
/// ## Sample code
///
/// To include the localizations provided by this class in a [MaterialApp],
/// add [GlobalMaterialLocalizations.delegates] to
/// [MaterialApp.localizationsDelegates], and specify the locales your
/// app supports with [MaterialApp.supportedLocales]:
///
/// ```dart
/// MaterialApp(
///   localizationsDelegates: GlobalMaterialLocalizations.delegates,
///   supportedLocales: [
///     const Locale('en', 'US'), // American English
///     const Locale('he', 'IL'), // Israeli Hebrew
///     // ...
///   ],
///   // ...
/// )
/// ```
///
/// ## Overriding translations
///
/// To create a translation that's similar to an existing language's translation
/// but has slightly different strings, subclass the relevant translation
/// directly and then create a [LocalizationsDelegate<MaterialLocalizations>]
/// subclass to define how to load it.
///
/// Avoid subclassing an unrelated language (for example, subclassing
/// [MaterialLocalizationEn] and then passing a non-English `localeName` to the
/// constructor). Doing so will cause confusion for locale-specific behaviors;
/// in particular, translations that use the `localeName` for determining how to
/// pluralize will end up doing invalid things. Subclassing an existing
/// language's translations is only suitable for making small changes to the
/// existing strings. For providing a new language entirely, implement
/// [MaterialLocalizations] directly.
///
/// See also:
///
///  * The Flutter Internationalization Tutorial,
///    <https://flutter.dev/tutorials/internationalization/>.
///  * [DefaultMaterialLocalizations], which only provides US English translations.
abstract class GlobalMaterialLocalizations implements MaterialLocalizations {
  /// Initializes an object that defines the material widgets' localized strings
  /// for the given `locale`.
  ///
  /// The arguments are used for further runtime localization of data,
  /// specifically for selecting plurals, date and time formatting, and number
  /// formatting. They correspond to the following values:
  ///
  ///  1. The string that would be returned by [Intl.canonicalizedLocale] for
  ///     the locale.
  ///  2. The [DateFormat] for [formatYear].
  ///  3. The [DateFormat] for [formatShortDate].
  ///  4. The [DateFormat] for [formatMediumDate].
  ///  5. The [DateFormat] for [formatFullDate].
  ///  6. The [DateFormat] for [formatMonthYear].
  ///  7. The [DateFormat] for [formatShortMonthDay].
  ///  8. The [NumberFormat] for [formatDecimal] (also used by [formatHour] and
  ///     [formatTimeOfDay] when [timeOfDayFormat] doesn't use [HourFormat.HH]).
  ///  9. The [NumberFormat] for [formatHour] and the hour part of
  ///     [formatTimeOfDay] when [timeOfDayFormat] uses [HourFormat.HH], and for
  ///     [formatMinute] and the minute part of [formatTimeOfDay].
  ///
  /// The [narrowWeekdays] and [firstDayOfWeekIndex] properties use the values
  /// from the [intl.DateFormat] used by [formatFullDate].
  const GlobalMaterialLocalizations({
    required String localeName,
    required intl.DateFormat fullYearFormat,
    required intl.DateFormat compactDateFormat,
    required intl.DateFormat shortDateFormat,
    required intl.DateFormat mediumDateFormat,
    required intl.DateFormat longDateFormat,
    required intl.DateFormat yearMonthFormat,
    required intl.DateFormat shortMonthDayFormat,
    required intl.NumberFormat decimalFormat,
    required intl.NumberFormat twoDigitZeroPaddedFormat,
  }) : assert(localeName != null),
       _localeName = localeName,
       assert(fullYearFormat != null),
       _fullYearFormat = fullYearFormat,
       assert(compactDateFormat != null),
       _compactDateFormat = compactDateFormat,
       assert(shortDateFormat != null),
       _shortDateFormat = shortDateFormat,
       assert(mediumDateFormat != null),
       _mediumDateFormat = mediumDateFormat,
       assert(longDateFormat != null),
       _longDateFormat = longDateFormat,
       assert(yearMonthFormat != null),
       _yearMonthFormat = yearMonthFormat,
       assert(shortMonthDayFormat != null),
       _shortMonthDayFormat = shortMonthDayFormat,
       assert(decimalFormat != null),
       _decimalFormat = decimalFormat,
       assert(twoDigitZeroPaddedFormat != null),
       _twoDigitZeroPaddedFormat = twoDigitZeroPaddedFormat;

  final String _localeName;
  final intl.DateFormat _fullYearFormat;
  final intl.DateFormat _compactDateFormat;
  final intl.DateFormat _shortDateFormat;
  final intl.DateFormat _mediumDateFormat;
  final intl.DateFormat _longDateFormat;
  final intl.DateFormat _yearMonthFormat;
  final intl.DateFormat _shortMonthDayFormat;
  final intl.NumberFormat _decimalFormat;
  final intl.NumberFormat _twoDigitZeroPaddedFormat;

  @override
  String formatHour(TimeOfDay timeOfDay, { bool alwaysUse24HourFormat = false }) {
    switch (hourFormat(of: timeOfDayFormat(alwaysUse24HourFormat: alwaysUse24HourFormat))) {
      case HourFormat.HH:
        return _twoDigitZeroPaddedFormat.format(timeOfDay.hour);
      case HourFormat.H:
        return formatDecimal(timeOfDay.hour);
      case HourFormat.h:
        final int hour = timeOfDay.hourOfPeriod;
        return formatDecimal(hour == 0 ? 12 : hour);
    }
  }

  @override
  String formatMinute(TimeOfDay timeOfDay) {
    return _twoDigitZeroPaddedFormat.format(timeOfDay.minute);
  }

  @override
  String formatYear(DateTime date) {
    return _fullYearFormat.format(date);
  }

  @override
  String formatCompactDate(DateTime date) {
    return _compactDateFormat.format(date);
  }

  @override
  String formatShortDate(DateTime date) {
    return _shortDateFormat.format(date);
  }

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

  @override
  String formatFullDate(DateTime date) {
    return _longDateFormat.format(date);
  }

  @override
  String formatMonthYear(DateTime date) {
    return _yearMonthFormat.format(date);
  }

  @override
  String formatShortMonthDay(DateTime date) {
    return _shortMonthDayFormat.format(date);
  }

  @override
  DateTime? parseCompactDate(String? inputString) {
    try {
      return inputString != null ? _compactDateFormat.parseStrict(inputString) : null;
    } on FormatException {
      return null;
    }
  }

  @override
  List<String> get narrowWeekdays {
    return _longDateFormat.dateSymbols.NARROWWEEKDAYS;
  }

  @override
  int get firstDayOfWeekIndex => (_longDateFormat.dateSymbols.FIRSTDAYOFWEEK + 1) % 7;

  @override
  String formatDecimal(int number) {
    return _decimalFormat.format(number);
  }

  @override
  String formatTimeOfDay(TimeOfDay timeOfDay, { bool alwaysUse24HourFormat = false }) {
    // Not using intl.DateFormat for two reasons:
    //
    // - DateFormat supports more formats than our material time picker does,
    //   and we want to be consistent across time picker format and the string
    //   formatting of the time of day.
    // - DateFormat operates on DateTime, which is sensitive to time eras and
    //   time zones, while here we want to format hour and minute within one day
    //   no matter what date the day falls on.
    final String hour = formatHour(timeOfDay, alwaysUse24HourFormat: alwaysUse24HourFormat);
    final String minute = formatMinute(timeOfDay);
    switch (timeOfDayFormat(alwaysUse24HourFormat: alwaysUse24HourFormat)) {
      case TimeOfDayFormat.h_colon_mm_space_a:
        return '$hour:$minute ${_formatDayPeriod(timeOfDay)!}';
      case TimeOfDayFormat.H_colon_mm:
      case TimeOfDayFormat.HH_colon_mm:
        return '$hour:$minute';
      case TimeOfDayFormat.HH_dot_mm:
        return '$hour.$minute';
      case TimeOfDayFormat.a_space_h_colon_mm:
        return '${_formatDayPeriod(timeOfDay)!} $hour:$minute';
      case TimeOfDayFormat.frenchCanadian:
        return '$hour h $minute';
    }
  }

  String? _formatDayPeriod(TimeOfDay timeOfDay) {
    switch (timeOfDay.period) {
      case DayPeriod.am:
        return anteMeridiemAbbreviation;
      case DayPeriod.pm:
        return postMeridiemAbbreviation;
    }
  }

  /// The raw version of [dateRangeStartDateSemanticLabel], with `$formattedDate` verbatim
  /// in the string.
  @protected
  String get dateRangeStartDateSemanticLabelRaw;

  @override
  String dateRangeStartDateSemanticLabel(String formattedDate) {
    return dateRangeStartDateSemanticLabelRaw.replaceFirst(r'$fullDate', formattedDate);
  }

  /// The raw version of [dateRangeEndDateSemanticLabel], with `$fullDate` verbatim
  /// in the string.
  @protected
  String get dateRangeEndDateSemanticLabelRaw;

  @override
  String dateRangeEndDateSemanticLabel(String formattedDate) {
    return dateRangeEndDateSemanticLabelRaw.replaceFirst(r'$fullDate', formattedDate);
  }

  /// The raw version of [scrimOnTapHint], with `$modalRouteContentName` verbatim
  /// in the string.
  @protected
  String get scrimOnTapHintRaw;

  @override
  String scrimOnTapHint(String modalRouteContentName) {
    final String text = scrimOnTapHintRaw;
    return text.replaceFirst(r'$modalRouteContentName', modalRouteContentName);
  }

  /// The raw version of [aboutListTileTitle], with `$applicationName` verbatim
  /// in the string.
  @protected
  String get aboutListTileTitleRaw;

  @override
  String aboutListTileTitle(String applicationName) {
    final String text = aboutListTileTitleRaw;
    return text.replaceFirst(r'$applicationName', applicationName);
  }

  /// The raw version of [pageRowsInfoTitle], with `$firstRow`, `$lastRow`' and
  /// `$rowCount` verbatim in the string, for the case where the value is
  /// approximate.
  @protected
  String get pageRowsInfoTitleApproximateRaw;

  /// The raw version of [pageRowsInfoTitle], with `$firstRow`, `$lastRow`' and
  /// `$rowCount` verbatim in the string, for the case where the value is
  /// precise.
  @protected
  String get pageRowsInfoTitleRaw;

  @override
  String pageRowsInfoTitle(int firstRow, int lastRow, int rowCount, bool rowCountIsApproximate) {
    String? text = rowCountIsApproximate ? pageRowsInfoTitleApproximateRaw : null;
    text ??= pageRowsInfoTitleRaw;
    assert(text != null, 'A $_localeName localization was not found for pageRowsInfoTitle or pageRowsInfoTitleApproximate');
    return text
      .replaceFirst(r'$firstRow', formatDecimal(firstRow))
      .replaceFirst(r'$lastRow', formatDecimal(lastRow))
      .replaceFirst(r'$rowCount', formatDecimal(rowCount));
  }

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

  @override
  String tabLabel({ required int tabIndex, required int tabCount }) {
    assert(tabIndex >= 1);
    assert(tabCount >= 1);
    final String template = tabLabelRaw;
    return template
      .replaceFirst(r'$tabIndex', formatDecimal(tabIndex))
      .replaceFirst(r'$tabCount', formatDecimal(tabCount));
  }

  /// The "zero" form of [selectedRowCountTitle].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [selectedRowCountTitleOne], the "one" form
  ///  * [selectedRowCountTitleTwo], the "two" form
  ///  * [selectedRowCountTitleFew], the "few" form
  ///  * [selectedRowCountTitleMany], the "many" form
  ///  * [selectedRowCountTitleOther], the "other" form
  @protected
  String? get selectedRowCountTitleZero => null;

  /// The "one" form of [selectedRowCountTitle].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [selectedRowCountTitleZero], the "zero" form
  ///  * [selectedRowCountTitleTwo], the "two" form
  ///  * [selectedRowCountTitleFew], the "few" form
  ///  * [selectedRowCountTitleMany], the "many" form
  ///  * [selectedRowCountTitleOther], the "other" form
  @protected
  String? get selectedRowCountTitleOne => null;

  /// The "two" form of [selectedRowCountTitle].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [selectedRowCountTitleZero], the "zero" form
  ///  * [selectedRowCountTitleOne], the "one" form
  ///  * [selectedRowCountTitleFew], the "few" form
  ///  * [selectedRowCountTitleMany], the "many" form
  ///  * [selectedRowCountTitleOther], the "other" form
  @protected
  String? get selectedRowCountTitleTwo => null;

  /// The "few" form of [selectedRowCountTitle].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [selectedRowCountTitleZero], the "zero" form
  ///  * [selectedRowCountTitleOne], the "one" form
  ///  * [selectedRowCountTitleTwo], the "two" form
  ///  * [selectedRowCountTitleMany], the "many" form
  ///  * [selectedRowCountTitleOther], the "other" form
  @protected
  String? get selectedRowCountTitleFew => null;

  /// The "many" form of [selectedRowCountTitle].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [selectedRowCountTitleZero], the "zero" form
  ///  * [selectedRowCountTitleOne], the "one" form
  ///  * [selectedRowCountTitleTwo], the "two" form
  ///  * [selectedRowCountTitleFew], the "few" form
  ///  * [selectedRowCountTitleOther], the "other" form
  @protected
  String? get selectedRowCountTitleMany => null;

  /// The "other" form of [selectedRowCountTitle].
  ///
  /// This form is required.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [selectedRowCountTitleZero], the "zero" form
  ///  * [selectedRowCountTitleOne], the "one" form
  ///  * [selectedRowCountTitleTwo], the "two" form
  ///  * [selectedRowCountTitleFew], the "few" form
  ///  * [selectedRowCountTitleMany], the "many" form
  @protected
  String get selectedRowCountTitleOther;

  @override
  String selectedRowCountTitle(int selectedRowCount) {
    return intl.Intl.pluralLogic(
      selectedRowCount,
      zero: selectedRowCountTitleZero,
      one: selectedRowCountTitleOne,
      two: selectedRowCountTitleTwo,
      few: selectedRowCountTitleFew,
      many: selectedRowCountTitleMany,
      other: selectedRowCountTitleOther,
      locale: _localeName,
    ).replaceFirst(r'$selectedRowCount', formatDecimal(selectedRowCount));
  }

  /// The format to use for [timeOfDayFormat].
  @protected
  TimeOfDayFormat get timeOfDayFormatRaw;

  /// The [TimeOfDayFormat] corresponding to one of the following supported
  /// patterns:
  ///
  ///  * `HH:mm`
  ///  * `HH.mm`
  ///  * `HH 'h' mm`
  ///  * `HH:mm น.`
  ///  * `H:mm`
  ///  * `h:mm a`
  ///  * `a h:mm`
  ///  * `ah:mm`
  ///
  /// See also:
  ///
  ///  * <http://demo.icu-project.org/icu-bin/locexp?d_=en&_=en_US>, which shows
  ///    the short time pattern used in the `en_US` locale.
  @override
  TimeOfDayFormat timeOfDayFormat({ bool alwaysUse24HourFormat = false }) {
    assert(alwaysUse24HourFormat != null);
    if (alwaysUse24HourFormat) {
      return _get24HourVersionOf(timeOfDayFormatRaw);
    }
    return timeOfDayFormatRaw;
  }

  /// The "zero" form of [licensesPackageDetailText].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [licensesPackageDetailTextZero], the "zero" form
  ///  * [licensesPackageDetailTextOne], the "one" form
  ///  * [licensesPackageDetailTextTwo], the "two" form
  ///  * [licensesPackageDetailTextFew], the "few" form
  ///  * [licensesPackageDetailTextMany], the "many" form
  ///  * [licensesPackageDetailTextOther], the "other" form
  @protected
  String? get licensesPackageDetailTextZero => null;

  /// The "one" form of [licensesPackageDetailText].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [licensesPackageDetailTextZero], the "zero" form
  ///  * [licensesPackageDetailTextOne], the "one" form
  ///  * [licensesPackageDetailTextTwo], the "two" form
  ///  * [licensesPackageDetailTextFew], the "few" form
  ///  * [licensesPackageDetailTextMany], the "many" form
  ///  * [licensesPackageDetailTextOther], the "other" form
  @protected
  String? get licensesPackageDetailTextOne => null;

  /// The "two" form of [licensesPackageDetailText].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [licensesPackageDetailTextZero], the "zero" form
  ///  * [licensesPackageDetailTextOne], the "one" form
  ///  * [licensesPackageDetailTextTwo], the "two" form
  ///  * [licensesPackageDetailTextFew], the "few" form
  ///  * [licensesPackageDetailTextMany], the "many" form
  ///  * [licensesPackageDetailTextOther], the "other" form
  @protected
  String? get licensesPackageDetailTextTwo => null;

  /// The "many" form of [licensesPackageDetailText].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [licensesPackageDetailTextZero], the "zero" form
  ///  * [licensesPackageDetailTextOne], the "one" form
  ///  * [licensesPackageDetailTextTwo], the "two" form
  ///  * [licensesPackageDetailTextFew], the "few" form
  ///  * [licensesPackageDetailTextMany], the "many" form
  ///  * [licensesPackageDetailTextOther], the "other" form
  @protected
  String? get licensesPackageDetailTextMany => null;

  /// The "few" form of [licensesPackageDetailText].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [licensesPackageDetailTextZero], the "zero" form
  ///  * [licensesPackageDetailTextOne], the "one" form
  ///  * [licensesPackageDetailTextTwo], the "two" form
  ///  * [licensesPackageDetailTextFew], the "few" form
  ///  * [licensesPackageDetailTextMany], the "many" form
  ///  * [licensesPackageDetailTextOther], the "other" form
  @protected
  String? get licensesPackageDetailTextFew => null;

  /// The "other" form of [licensesPackageDetailText].
  ///
  /// This form is required.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [licensesPackageDetailTextZero], the "zero" form
  ///  * [licensesPackageDetailTextOne], the "one" form
  ///  * [licensesPackageDetailTextTwo], the "two" form
  ///  * [licensesPackageDetailTextFew], the "few" form
  ///  * [licensesPackageDetailTextMany], the "many" form
  ///  * [licensesPackageDetailTextOther], the "other" form
  @protected
  String get licensesPackageDetailTextOther;

  @override
  String licensesPackageDetailText(int licenseCount) {
    return intl.Intl.pluralLogic(
      licenseCount,
      zero: licensesPackageDetailTextZero,
      one: licensesPackageDetailTextOne,
      two: licensesPackageDetailTextTwo,
      many: licensesPackageDetailTextMany,
      few: licensesPackageDetailTextFew,
      other: licensesPackageDetailTextOther,
      locale: _localeName,
    ).replaceFirst(r'$licenseCount', formatDecimal(licenseCount));
  }

  /// The "zero" form of [remainingTextFieldCharacterCount].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [remainingTextFieldCharacterCountZero], the "zero" form
  ///  * [remainingTextFieldCharacterCountOne], the "one" form
  ///  * [remainingTextFieldCharacterCountTwo], the "two" form
  ///  * [remainingTextFieldCharacterCountFew], the "few" form
  ///  * [remainingTextFieldCharacterCountMany], the "many" form
  ///  * [remainingTextFieldCharacterCountOther], the "other" form
  @protected
  String? get remainingTextFieldCharacterCountZero => null;

  /// The "one" form of [remainingTextFieldCharacterCount].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [remainingTextFieldCharacterCountZero], the "zero" form
  ///  * [remainingTextFieldCharacterCountOne], the "one" form
  ///  * [remainingTextFieldCharacterCountTwo], the "two" form
  ///  * [remainingTextFieldCharacterCountFew], the "few" form
  ///  * [remainingTextFieldCharacterCountMany], the "many" form
  ///  * [remainingTextFieldCharacterCountOther], the "other" form
  @protected
  String? get remainingTextFieldCharacterCountOne => null;

  /// The "two" form of [remainingTextFieldCharacterCount].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [remainingTextFieldCharacterCountZero], the "zero" form
  ///  * [remainingTextFieldCharacterCountOne], the "one" form
  ///  * [remainingTextFieldCharacterCountTwo], the "two" form
  ///  * [remainingTextFieldCharacterCountFew], the "few" form
  ///  * [remainingTextFieldCharacterCountMany], the "many" form
  ///  * [remainingTextFieldCharacterCountOther], the "other" form
  @protected
  String? get remainingTextFieldCharacterCountTwo => null;

  /// The "many" form of [remainingTextFieldCharacterCount].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [remainingTextFieldCharacterCountZero], the "zero" form
  ///  * [remainingTextFieldCharacterCountOne], the "one" form
  ///  * [remainingTextFieldCharacterCountTwo], the "two" form
  ///  * [remainingTextFieldCharacterCountFew], the "few" form
  ///  * [remainingTextFieldCharacterCountMany], the "many" form
  ///  * [remainingTextFieldCharacterCountOther], the "other" form
  @protected
  String? get remainingTextFieldCharacterCountMany => null;

  /// The "few" form of [remainingTextFieldCharacterCount].
  ///
  /// This form is optional.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [remainingTextFieldCharacterCountZero], the "zero" form
  ///  * [remainingTextFieldCharacterCountOne], the "one" form
  ///  * [remainingTextFieldCharacterCountTwo], the "two" form
  ///  * [remainingTextFieldCharacterCountFew], the "few" form
  ///  * [remainingTextFieldCharacterCountMany], the "many" form
  ///  * [remainingTextFieldCharacterCountOther], the "other" form
  @protected
  String? get remainingTextFieldCharacterCountFew => null;

  /// The "other" form of [remainingTextFieldCharacterCount].
  ///
  /// This form is required.
  ///
  /// See also:
  ///
  ///  * [Intl.plural], to which this form is passed.
  ///  * [remainingTextFieldCharacterCountZero], the "zero" form
  ///  * [remainingTextFieldCharacterCountOne], the "one" form
  ///  * [remainingTextFieldCharacterCountTwo], the "two" form
  ///  * [remainingTextFieldCharacterCountFew], the "few" form
  ///  * [remainingTextFieldCharacterCountMany], the "many" form
  ///  * [remainingTextFieldCharacterCountOther], the "other" form
  @protected
  String get remainingTextFieldCharacterCountOther;

  @override
  String remainingTextFieldCharacterCount(int remaining) {
    return intl.Intl.pluralLogic(
      remaining,
      zero: remainingTextFieldCharacterCountZero,
      one: remainingTextFieldCharacterCountOne,
      two: remainingTextFieldCharacterCountTwo,
      many: remainingTextFieldCharacterCountMany,
      few: remainingTextFieldCharacterCountFew,
      other: remainingTextFieldCharacterCountOther,
      locale: _localeName,
    ).replaceFirst(r'$remainingCount', formatDecimal(remaining));
  }

  @override
  ScriptCategory get scriptCategory;

  /// A [LocalizationsDelegate] for [MaterialLocalizations].
  ///
  /// Most internationalized apps will use [GlobalMaterialLocalizations.delegates]
  /// as the value of [MaterialApp.localizationsDelegates] to include
  /// the localizations for both the material and widget libraries.
  static const LocalizationsDelegate<MaterialLocalizations> delegate = _MaterialLocalizationsDelegate();

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

/// Finds the [TimeOfDayFormat] to use instead of the `original` when the
/// `original` uses 12-hour format and [MediaQueryData.alwaysUse24HourFormat]
/// is true.
TimeOfDayFormat _get24HourVersionOf(TimeOfDayFormat original) {
  switch (original) {
    case TimeOfDayFormat.HH_colon_mm:
    case TimeOfDayFormat.HH_dot_mm:
    case TimeOfDayFormat.frenchCanadian:
    case TimeOfDayFormat.H_colon_mm:
      return original;
    case TimeOfDayFormat.h_colon_mm_space_a:
    case TimeOfDayFormat.a_space_h_colon_mm:
      return TimeOfDayFormat.HH_colon_mm;
  }
}

class _MaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  const _MaterialLocalizationsDelegate();

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

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

  @override
  Future<MaterialLocalizations> 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 compactDateFormat;
      intl.DateFormat shortDateFormat;
      intl.DateFormat mediumDateFormat;
      intl.DateFormat longDateFormat;
      intl.DateFormat yearMonthFormat;
      intl.DateFormat shortMonthDayFormat;
      if (intl.DateFormat.localeExists(localeName)) {
        fullYearFormat = intl.DateFormat.y(localeName);
        compactDateFormat = intl.DateFormat.yMd(localeName);
        shortDateFormat = intl.DateFormat.yMMMd(localeName);
        mediumDateFormat = intl.DateFormat.MMMEd(localeName);
        longDateFormat = intl.DateFormat.yMMMMEEEEd(localeName);
        yearMonthFormat = intl.DateFormat.yMMMM(localeName);
        shortMonthDayFormat = intl.DateFormat.MMMd(localeName);
      } else if (intl.DateFormat.localeExists(locale.languageCode)) {
        fullYearFormat = intl.DateFormat.y(locale.languageCode);
        compactDateFormat = intl.DateFormat.yMd(locale.languageCode);
        shortDateFormat = intl.DateFormat.yMMMd(locale.languageCode);
        mediumDateFormat = intl.DateFormat.MMMEd(locale.languageCode);
        longDateFormat = intl.DateFormat.yMMMMEEEEd(locale.languageCode);
        yearMonthFormat = intl.DateFormat.yMMMM(locale.languageCode);
        shortMonthDayFormat = intl.DateFormat.MMMd(locale.languageCode);
      } else {
        fullYearFormat = intl.DateFormat.y();
        compactDateFormat = intl.DateFormat.yMd();
        shortDateFormat = intl.DateFormat.yMMMd();
        mediumDateFormat = intl.DateFormat.MMMEd();
        longDateFormat = intl.DateFormat.yMMMMEEEEd();
        yearMonthFormat = intl.DateFormat.yMMMM();
        shortMonthDayFormat = intl.DateFormat.MMMd();
      }

      intl.NumberFormat decimalFormat;
      intl.NumberFormat twoDigitZeroPaddedFormat;
      if (intl.NumberFormat.localeExists(localeName)) {
        decimalFormat = intl.NumberFormat.decimalPattern(localeName);
        twoDigitZeroPaddedFormat = intl.NumberFormat('00', localeName);
      } else if (intl.NumberFormat.localeExists(locale.languageCode)) {
        decimalFormat = intl.NumberFormat.decimalPattern(locale.languageCode);
        twoDigitZeroPaddedFormat = intl.NumberFormat('00', locale.languageCode);
      } else {
        decimalFormat = intl.NumberFormat.decimalPattern();
        twoDigitZeroPaddedFormat = intl.NumberFormat('00');
      }

      return SynchronousFuture<MaterialLocalizations>(getMaterialTranslation(
        locale,
        fullYearFormat,
        compactDateFormat,
        shortDateFormat,
        mediumDateFormat,
        longDateFormat,
        yearMonthFormat,
        shortMonthDayFormat,
        decimalFormat,
        twoDigitZeroPaddedFormat,
      )!);
    });
  }

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

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