// 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.

// @dart = 2.8

import 'dart:ui' show lerpDouble;

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

import 'bottom_navigation_bar.dart';
import 'theme.dart';

/// Defines default property values for descendant [BottomNavigationBar]
/// widgets.
///
/// Descendant widgets obtain the current [BottomNavigationBarThemeData] object
/// using `BottomNavigationBarTheme.of(context)`. Instances of
/// [BottomNavigationBarThemeData] can be customized with
/// [BottomNavigationBarThemeData.copyWith].
///
/// Typically a [BottomNavigationBarThemeData] is specified as part of the
/// overall [Theme] with [ThemeData.bottomNavigationBarTheme].
///
/// All [BottomNavigationBarThemeData] properties are `null` by default. When
/// null, the [BottomNavigationBar]'s build method provides defaults.
///
/// See also:
///
///  * [ThemeData], which describes the overall theme information for the
///    application.
@immutable
class BottomNavigationBarThemeData with Diagnosticable {
  /// Creates a theme that can be used for [ThemeData.bottomNavigationBarTheme].
  const BottomNavigationBarThemeData({
    this.backgroundColor,
    this.elevation,
    this.selectedIconTheme,
    this.unselectedIconTheme,
    this.selectedItemColor,
    this.unselectedItemColor,
    this.selectedLabelStyle,
    this.unselectedLabelStyle,
    this.showSelectedLabels,
    this.showUnselectedLabels,
    this.type,
  });

  /// The color of the [BottomNavigationBar] itself.
  ///
  /// See [BottomNavigationBar.backgroundColor].
  final Color backgroundColor;

  /// The z-coordinate of the [BottomNavigationBar].
  ///
  /// See [BottomNavigationBar.elevation].
  final double elevation;

  /// The size, opacity, and color of the icon in the currently selected
  /// [BottomNavigationBarItem.icon].
  ///
  /// See [BottomNavigationBar.selectedIconTheme].
  final IconThemeData selectedIconTheme;

  /// The size, opacity, and color of the icon in the currently unselected
  /// [BottomNavigationBarItem.icon]s.
  ///
  /// See [BottomNavigationBar.unselectedIconTheme].
  final IconThemeData unselectedIconTheme;

  /// The color of the selected [BottomNavigationBarItem.icon] and
  /// [BottomNavigationBarItem.title].
  ///
  /// See [BottomNavigationBar.selectedItemColor].
  final Color selectedItemColor;

  /// The color of the unselected [BottomNavigationBarItem.icon] and
  /// [BottomNavigationBarItem.title]s.
  ///
  /// See [BottomNavigationBar.unselectedItemColor].
  final Color unselectedItemColor;

  /// The [TextStyle] of the [BottomNavigationBarItem] labels when they are
  /// selected.
  ///
  /// See [BottomNavigationBar.selectedLabelStyle].
  final TextStyle selectedLabelStyle;

  /// The [TextStyle] of the [BottomNavigationBarItem] labels when they are not
  /// selected.
  ///
  /// See [BottomNavigationBar.unselectedLabelStyle].
  final TextStyle unselectedLabelStyle;

  /// Whether the labels are shown for the unselected [BottomNavigationBarItem]s.
  ///
  /// See [BottomNavigationBar.showSelectedLabels].
  final bool showSelectedLabels;

  /// Whether the labels are shown for the selected [BottomNavigationBarItem].
  ///
  /// See [BottomNavigationBar.showUnselectedLabels].
  final bool showUnselectedLabels;

  /// Defines the layout and behavior of a [BottomNavigationBar].
  ///
  /// See [BottomNavigationBar.type].
  final BottomNavigationBarType type;

  /// Creates a copy of this object but with the given fields replaced with the
  /// new values.
  BottomNavigationBarThemeData copyWith({
    Color backgroundColor,
    double elevation,
    IconThemeData selectedIconTheme,
    IconThemeData unselectedIconTheme,
    Color selectedItemColor,
    Color unselectedItemColor,
    TextStyle selectedLabelStyle,
    TextStyle unselectedLabelStyle,
    bool showSelectedLabels,
    bool showUnselectedLabels,
    BottomNavigationBarType type,
  }) {
    return BottomNavigationBarThemeData(
      backgroundColor: backgroundColor ?? this.backgroundColor,
      elevation: elevation ?? this.elevation,
      selectedIconTheme: selectedIconTheme ?? this.selectedIconTheme,
      unselectedIconTheme: unselectedIconTheme ?? this.unselectedIconTheme,
      selectedItemColor: selectedItemColor ?? this.selectedItemColor,
      unselectedItemColor: unselectedItemColor ?? this.unselectedItemColor,
      selectedLabelStyle: selectedLabelStyle ?? this.selectedLabelStyle,
      unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle,
      showSelectedLabels: showSelectedLabels ?? this.showSelectedLabels,
      showUnselectedLabels: showUnselectedLabels ?? this.showUnselectedLabels,
      type: type ?? this.type,
    );
  }

  /// Linearly interpolate between two [BottomNavigationBarThemeData].
  ///
  /// The argument `t` must not be null.
  ///
  /// {@macro dart.ui.shadow.lerp}
  static BottomNavigationBarThemeData lerp(BottomNavigationBarThemeData a, BottomNavigationBarThemeData b, double t) {
    assert(t != null);
    return BottomNavigationBarThemeData(
      backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
      elevation: lerpDouble(a?.elevation, b?.elevation, t),
      selectedIconTheme: IconThemeData.lerp(a?.selectedIconTheme, b?.selectedIconTheme, t),
      unselectedIconTheme: IconThemeData.lerp(a?.unselectedIconTheme, b?.unselectedIconTheme, t),
      selectedItemColor: Color.lerp(a?.selectedItemColor, b?.selectedItemColor, t),
      unselectedItemColor: Color.lerp(a?.unselectedItemColor, b?.unselectedItemColor, t),
      selectedLabelStyle: TextStyle.lerp(a?.selectedLabelStyle, b?.selectedLabelStyle, t),
      unselectedLabelStyle: TextStyle.lerp(a?.unselectedLabelStyle, b?.unselectedLabelStyle, t),
      showSelectedLabels: t < 0.5 ? a?.showSelectedLabels : b?.showSelectedLabels,
      showUnselectedLabels: t < 0.5 ? a?.showUnselectedLabels : b?.showUnselectedLabels,
      type: t < 0.5 ? a?.type : b?.type,
    );
  }

  @override
  int get hashCode {
    return hashValues(
      backgroundColor,
      elevation,
      selectedIconTheme,
      unselectedIconTheme,
      selectedItemColor,
      unselectedItemColor,
      selectedLabelStyle,
      unselectedLabelStyle,
      showSelectedLabels,
      showUnselectedLabels,
      type,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
    return other is BottomNavigationBarThemeData
        && other.backgroundColor == backgroundColor
        && other.elevation == elevation
        && other.selectedIconTheme == selectedIconTheme
        && other.unselectedIconTheme == unselectedIconTheme
        && other.selectedItemColor == selectedItemColor
        && other.unselectedItemColor == unselectedItemColor
        && other.selectedLabelStyle == selectedLabelStyle
        && other.unselectedLabelStyle == unselectedLabelStyle
        && other.showSelectedLabels == showSelectedLabels
        && other.showUnselectedLabels == showUnselectedLabels
        && other.type == type;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
    properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
    properties.add(DiagnosticsProperty<IconThemeData>('selectedIconTheme', selectedIconTheme, defaultValue: null));
    properties.add(DiagnosticsProperty<IconThemeData>('unselectedIconTheme', unselectedIconTheme, defaultValue: null));
    properties.add(ColorProperty('selectedItemColor', selectedItemColor, defaultValue: null));
    properties.add(ColorProperty('unselectedItemColor', unselectedItemColor, defaultValue: null));
    properties.add(DiagnosticsProperty<TextStyle>('selectedLabelStyle', selectedLabelStyle, defaultValue: null));
    properties.add(DiagnosticsProperty<TextStyle>('unselectedLabelStyle', unselectedLabelStyle, defaultValue: null));
    properties.add(DiagnosticsProperty<bool>('showSelectedLabels', showSelectedLabels, defaultValue: null));
    properties.add(DiagnosticsProperty<bool>('showUnselectedLabels', showUnselectedLabels, defaultValue: null));
    properties.add(DiagnosticsProperty<BottomNavigationBarType>('type', type, defaultValue: null));
  }
}

/// Applies a bottom navigation bar theme to descendant [BottomNavigationBar]
/// widgets.
///
/// Descendant widgets obtain the current theme's [BottomNavigationBarTheme]
/// object using [BottomNavigationBarTheme.of]. When a widget uses
/// [BottomNavigationBarTheme.of], it is automatically rebuilt if the theme
/// later changes.
///
/// A bottom navigation theme can be specified as part of the overall Material
/// theme using [ThemeData.bottomNavigationBarTheme].
///
/// See also:
///
///  * [BottomNavigationBarThemeData], which describes the actual configuration
///    of a bottom navigation bar theme.
class BottomNavigationBarTheme extends InheritedWidget {
  /// Constructs a bottom navigation bar theme that configures all descendant
  /// [BottomNavigationBar] widgets.
  ///
  /// The [data] must not be null.
  const BottomNavigationBarTheme({
    Key key,
    @required this.data,
    Widget child,
  }) : assert(data != null), super(key: key, child: child);

  /// The properties used for all descendant [BottomNavigationBar] widgets.
  final BottomNavigationBarThemeData data;

  /// Returns the configuration [data] from the closest
  /// [BottomNavigationBarTheme] ancestor. If there is no ancestor, it returns
  /// [ThemeData.bottomNavigationBarTheme]. Applications can assume that the
  /// returned value will not be null.
  ///
  /// Typical usage is as follows:
  ///
  /// ```dart
  /// BottomNavigationBarThemeData theme = BottomNavigationBarTheme.of(context);
  /// ```
  static BottomNavigationBarThemeData of(BuildContext context) {
    final BottomNavigationBarTheme bottomNavTheme = context.dependOnInheritedWidgetOfExactType<BottomNavigationBarTheme>();
    return bottomNavTheme?.data ?? Theme.of(context).bottomNavigationBarTheme;
  }

  @override
  bool updateShouldNotify(BottomNavigationBarTheme oldWidget) => data != oldWidget.data;
}
