/*
 * @Author       : WuWei
 * @LastEditors  : WuWei
 * @Date         : 2022-08-17 23:52:35
 * @LastEditTime : 2023-02-08 09:08:33
 * @Description  : Do not edit
 */
import 'package:flutter/material.dart';

import 'styles/date_picker_styles.dart';

///
mixin CommonDatePickerFunctions {
  /// Builds widgets showing abbreviated days of week. The first widget in the
  /// returned list corresponds to the first day of week for the current locale.
  ///
  /// Examples:
  ///
  /// ```
  /// ┌ Sunday is the first day of week in the US (en_US)
  /// |
  /// S M T W T F S  <-- the returned list contains these widgets
  /// _ _ _ _ _ 1 2
  /// 3 4 5 6 7 8 9
  ///
  /// ┌ But it's Monday in the UK (en_GB)
  /// |
  /// M T W T F S S  <-- the returned list contains these widgets
  /// _ _ _ _ 1 2 3
  /// 4 5 6 7 8 9 10
  /// ```
  List<Widget> getDayHeaders(DayHeaderStyleBuilder headerStyleBuilder,
      List<String> narrowWeekdays, int firstDayOfWeekIndex) {
    final List<Widget> result = <Widget>[];

    for (int i = firstDayOfWeekIndex; true; i = (i + 1) % 7) {
      DayHeaderStyle headerStyle = headerStyleBuilder(i);
      final String weekday = narrowWeekdays[i];

      Widget header = ExcludeSemantics(
        child: Container(
          decoration: headerStyle.decoration,
          child: Center(child: Text(weekday, style: headerStyle.textStyle)),
        ),
      );

      result.add(header);
      if (i == (firstDayOfWeekIndex - 1) % 7) {
        break;
      }
    }
    return result;
  }

  /// Computes the offset from the first day of week that the first day of the
  /// [month] falls on.
  ///
  /// For example, September 1, 2017 falls on a Friday, which in the calendar
  /// localized for United States English appears as:
  ///
  /// ```
  /// S M T W T F S
  /// _ _ _ _ _ 1 2
  /// ```
  ///
  /// The offset for the first day of the months is the number of leading blanks
  /// in the calendar, i.e. 5.
  ///
  /// The same date localized for the Russian calendar has a different offset,
  /// because the first day of week is Monday rather than Sunday:
  ///
  /// ```
  /// M T W T F S S
  /// _ _ _ _ 1 2 3
  /// ```
  ///
  /// So the offset is 4, rather than 5.
  ///
  /// This code consolidates the following:
  ///
  /// - [DateTime.weekday] provides a 1-based index into days of week, with 1
  ///   falling on Monday.
  /// - [MaterialLocalizations.firstDayOfWeekIndex] provides a 0-based index
  ///   into the [MaterialLocalizations.narrowWeekdays] list.
  /// - [MaterialLocalizations.narrowWeekdays] list provides localized names of
  ///   days of week, always starting with Sunday and ending with Saturday.
  int computeFirstDayOffset(int year, int month, int firstDayOfWeekFromSunday) {
    // 0-based day of week, with 0 representing Monday.
    final int weekdayFromMonday = DateTime(year, month).weekday - 1;
    // firstDayOfWeekFromSunday recomputed to be Monday-based
    final int firstDayOfWeekFromMonday = (firstDayOfWeekFromSunday - 1) % 7;
    // Number of days between the first day of week appearing on the calendar,
    // and the day corresponding to the 1-st of the month.
    return (weekdayFromMonday - firstDayOfWeekFromMonday) % 7;
  }
}
