// Copyright 2018 The Chromium 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/widgets.dart';

import 'button_theme.dart';
import 'colors.dart';
import 'raised_button.dart';
import 'theme.dart';

// The total time to make the button's fill color opaque and change
// its elevation.
const Duration _kPressDuration = const Duration(milliseconds: 150);

// Half of _kPressDuration: just the time to change the button's
// elevation.
const Duration _kElevationDuration = const Duration(milliseconds: 75);

/// A cross between [RaisedButton] and [FlatButton]: a bordered button whose
/// elevation increases and whose background becomes opaque when the button
/// is pressed.
///
/// An outline button's elevation is initially 0.0 and its background [color]
/// is transparent. When the button is pressed its background becomes opaque
/// and then its elevation increases to [highlightElevation].
///
/// The outline button has a border whose shape is defined by [shape]
/// and whose appearance is defined by [borderSide], [disabledBorderColor],
/// and [highlightedBorderColor].
///
/// If the [onPressed] callback is null, then the button will be disabled and by
/// default will resemble a flat button in the [disabledColor].
///
/// If you want an ink-splash effect for taps, but don't want to use a button,
/// consider using [InkWell] directly.
///
/// Outline buttons have a minimum size of 88.0 by 36.0 which can be overidden
/// with [ButtonTheme].
///
/// See also:
///
///  * [RaisedButton], a filled material design button with a shadow.
///  * [FlatButton], a material design button without a shadow.
///  * [DropdownButton], a button that shows options to select from.
///  * [FloatingActionButton], the round button in material applications.
///  * [IconButton], to create buttons that just contain icons.
///  * [InkWell], which implements the ink splash part of a flat button.
///  * <https://material.google.com/components/buttons.html>
class OutlineButton extends StatefulWidget {
  /// Create a filled button.
  ///
  /// The [highlightElevation], and [borderWidth]
  /// arguments must not be null.
  const OutlineButton({
    Key key,
    @required this.onPressed,
    this.textTheme,
    this.textColor,
    this.disabledTextColor,
    this.color,
    this.highlightColor,
    this.splashColor,
    this.highlightElevation = 2.0,
    this.borderSide,
    this.disabledBorderColor,
    this.highlightedBorderColor,
    this.padding,
    this.shape,
    this.child,
  }) : assert(highlightElevation != null && highlightElevation >= 0.0),
       super(key: key);

  /// Create an outline button from a pair of widgets that serve as the button's
  /// [icon] and [label].
  ///
  /// The icon and label are arranged in a row and padded by 12 logical pixels
  /// at the start, and 16 at the end, with an 8 pixel gap in between.
  ///
  /// The [highlightElevation], [icon], and [label] must not be null.
  OutlineButton.icon({
    Key key,
    @required this.onPressed,
    this.textTheme,
    this.textColor,
    this.disabledTextColor,
    this.color,
    this.highlightColor,
    this.splashColor,
    this.highlightElevation = 2.0,
    this.borderSide,
    this.disabledBorderColor,
    this.highlightedBorderColor,
    this.shape,
    @required Widget icon,
    @required Widget label,
  }) : assert(highlightElevation != null && highlightElevation >= 0.0),
       assert(icon != null),
       assert(label != null),
       padding = const EdgeInsetsDirectional.only(start: 12.0, end: 16.0),
       child = new Row(
         mainAxisSize: MainAxisSize.min,
         children: <Widget>[
           icon,
           const SizedBox(width: 8.0),
           label,
         ],
       ),
       super(key: key);

  /// Called when the button is tapped or otherwise activated.
  ///
  /// If this is set to null, the button will be disabled, see [enabled].
  final VoidCallback onPressed;

  /// Defines the button's base colors, and the defaults for the button's minimum
  /// size, internal padding, and shape.
  ///
  /// Defaults to `ButtonTheme.of(context).textTheme`.
  final ButtonTextTheme textTheme;

  /// The color to use for this button's text.
  ///
  /// The button's [Material.textStyle] will be the current theme's button
  /// text style, [ThemeData.textTheme.button], configured with this color.
  ///
  /// The default text color depends on the button theme's text theme,
  /// [ButtonThemeData.textTheme].
  ///
  /// See also:
  ///
  ///   * [disabledTextColor], the text color to use when the button has been
  ///     disabled.
  final Color textColor;

  /// The color to use for this button's text when the button is disabled.
  ///
  /// The button's [Material.textStyle] will be the current theme's button
  /// text style, [ThemeData.textTheme.button], configured with this color.
  ///
  /// The default value is the theme's disabled color,
  /// [ThemeData.disabledColor].
  ///
  /// See also:
  ///
  ///  * [textColor], which specifies the color to use for this button's text
  ///    when the button is [enabled].
  final Color disabledTextColor;

  /// The button's opaque fill color when it's [enabled] and has been pressed.
  ///
  /// If null this value defaults to white for light themes (see
  /// [ThemeData.brightness]), and black for dark themes.
  final Color color;

  /// The splash color of the button's [InkWell].
  ///
  /// The ink splash indicates that the button has been touched. It
  /// appears on top of the button's child and spreads in an expanding
  /// circle beginning where the touch occurred.
  ///
  /// If [textTheme] is [ButtonTextTheme.primary], the default splash color is
  /// is based on the theme's primary color [ThemeData.primaryColor],
  /// otherwise it's the current theme's splash color, [ThemeData.splashColor].
  ///
  /// The appearance of the splash can be configured with the theme's splash
  /// factory, [ThemeData.splashFactory].
  final Color splashColor;

  /// The highlight color of the button's [InkWell].
  ///
  /// The highlight indicates that the button is actively being pressed. It
  /// appears on top of the button's child and quickly spreads to fill
  /// the button, and then fades out.
  ///
  /// If [textTheme] is [ButtonTextTheme.primary], the default highlight color is
  /// transparent (in other words the highlight doesn't appear). Otherwise it's
  /// the current theme's highlight color, [ThemeData.highlightColor].
  final Color highlightColor;

  /// The elevation of the button when it's [enabled] and has been pressed.
  ///
  /// If null, this value defaults to 2.0.
  ///
  /// The elevation of an outline button is always 0.0 unless its enabled
  /// and has been pressed.
  final double highlightElevation;

  /// Defines the color of the border when the button is enabled but not
  /// pressed, and the border outline's width and style in general.
  ///
  /// If the border side's [BorderSide.style] is [BorderStyle.none], then
  /// an outline is not drawn.
  ///
  /// If null the default border's style is [BorderStyle.solid], its
  /// [BorderSide.width] is 2.0, and its color is a light shade of grey.
  final BorderSide borderSide;

  /// The outline border's color when the button is [enabled] and pressed.
  ///
  /// If null this value defaults to the theme's primary color,
  /// [ThemeData.primaryColor].
  final Color highlightedBorderColor;

  /// The outline border's color when the button is not [enabled].
  ///
  /// If null this value defaults to a very light shade of grey for light
  /// themes (see [ThemeData.brightness]), and a very dark shade of grey for
  /// dark themes.
  final Color disabledBorderColor;

  /// The internal padding for the button's [child].
  ///
  /// Defaults to the value from the current [ButtonTheme],
  /// [ButtonThemeData.padding].
  final EdgeInsetsGeometry padding;

  /// The shape of the button's [Material] and its outline.
  ///
  /// The button's highlight and splash are clipped to this shape. If the
  /// button has a [highlightElevation], then its drop shadow is defined by this
  /// shape as well.
  final ShapeBorder shape;

  /// The button's label.
  ///
  /// Often a [Text] widget in all caps.
  final Widget child;

  /// Whether the button is enabled or disabled.
  ///
  /// Buttons are disabled by default. To enable a button, set its [onPressed]
  /// property to a non-null value.
  bool get enabled => onPressed != null;

  @override
  _OutlineButtonState createState() => new _OutlineButtonState();


  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(new ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled'));
    properties.add(new DiagnosticsProperty<ButtonTextTheme>('textTheme', textTheme, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('textColor', textColor, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('disabledTextColor', disabledTextColor, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('color', color, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('highlightColor', highlightColor, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('splashColor', splashColor, defaultValue: null));
    properties.add(new DiagnosticsProperty<double>('highlightElevation', highlightElevation, defaultValue: 2.0));
    properties.add(new DiagnosticsProperty<BorderSide>('borderSide', borderSide, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('disabledBorderColor', disabledBorderColor, defaultValue: null));
    properties.add(new DiagnosticsProperty<Color>('highlightedBorderColor', highlightedBorderColor, defaultValue: null));
    properties.add(new DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
    properties.add(new DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
  }
}

class _OutlineButtonState extends State<OutlineButton> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _fillAnimation;
  Animation<double> _elevationAnimation;
  bool _pressed = false;

  @override
  void initState() {
    super.initState();

    // The Material widget animates its shape (which includes the outline
    // border) and elevation over _kElevationDuration. When pressed, the
    // button makes its fill color opaque white first, and then sets
    // its highlightElevation. We can't change the elevation while the
    // button's fill is translucent, because the shadow fills the interior
    // of the button.

    _controller = new AnimationController(
      duration: _kPressDuration,
      vsync: this
    );
    _fillAnimation = new CurvedAnimation(
      parent: _controller,
      curve: const Interval(0.0, 0.5,
        curve: Curves.fastOutSlowIn,
      ),
    );
    _elevationAnimation = new CurvedAnimation(
      parent: _controller,
      curve: const Interval(0.5, 0.5),
      reverseCurve: const Interval(1.0, 1.0),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  ButtonTextTheme _getTextTheme(ButtonThemeData buttonTheme) {
    return widget.textTheme ?? buttonTheme.textTheme;
  }

  // TODO(hmuller): this method is the same as FlatButton
  Color _getTextColor(ThemeData theme, ButtonThemeData buttonTheme) {
    final Color color = widget.enabled ? widget.textColor : widget.disabledTextColor;
    if (color != null)
      return color;

    final bool themeIsDark = theme.brightness == Brightness.dark;
    switch (_getTextTheme(buttonTheme)) {
      case ButtonTextTheme.normal:
        return widget.enabled
          ? (themeIsDark ? Colors.white : Colors.black87)
          : theme.disabledColor;
      case ButtonTextTheme.accent:
        return widget.enabled
          ? theme.accentColor
          : theme.disabledColor;
      case ButtonTextTheme.primary:
        return widget.enabled
          ? theme.buttonColor
          : (themeIsDark ? Colors.white30 : Colors.black38);
    }
    return null;
  }

  Color _getFillColor(ThemeData theme) {
    final bool themeIsDark = theme.brightness == Brightness.dark;
    final Color color = widget.color ?? (themeIsDark
      ? const Color(0x00000000)
      : const Color(0x00FFFFFF));
    final Tween<Color> colorTween = new ColorTween(
      begin: color.withAlpha(0x00),
      end: color.withAlpha(0xFF),
    );
    return colorTween.evaluate(_fillAnimation);
  }

  // TODO(hmuller): this method is the same as FlatButton
  Color _getSplashColor(ThemeData theme, ButtonThemeData buttonTheme) {
    if (widget.splashColor != null)
      return widget.splashColor;

    switch (_getTextTheme(buttonTheme)) {
      case ButtonTextTheme.normal:
      case ButtonTextTheme.accent:
        return theme.splashColor;
      case ButtonTextTheme.primary:
        return theme.brightness == Brightness.dark
          ? Colors.white12
          : theme.primaryColor.withOpacity(0.12);
    }
    return Colors.transparent;
  }

  BorderSide _getOutline(ThemeData theme, ButtonThemeData buttonTheme) {
    final bool themeIsDark = theme.brightness == Brightness.dark;
    if (widget.borderSide?.style == BorderStyle.none)
      return widget.borderSide;

    final Color color = widget.enabled
      ? (_pressed
         ? widget.highlightedBorderColor ?? theme.primaryColor
         : (widget.borderSide?.color ??
            (themeIsDark ? Colors.grey[600] : Colors.grey[200])))
      : (widget.disabledBorderColor ??
         (themeIsDark ? Colors.grey[800] : Colors.grey[100]));

    return new BorderSide(
      color: color,
      width: widget.borderSide?.width ?? 2.0,
    );
  }

  double _getHighlightElevation() {
    return new Tween<double>(
      begin: 0.0,
      end: widget.highlightElevation ?? 2.0,
    ).evaluate(_elevationAnimation);
  }

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final ButtonThemeData buttonTheme = ButtonTheme.of(context);
    final Color textColor = _getTextColor(theme, buttonTheme);
    final Color splashColor = _getSplashColor(theme, buttonTheme);

    return new AnimatedBuilder(
      animation: _controller,
      builder: (BuildContext context, Widget child) {
        return new RaisedButton(
          textColor: textColor,
          disabledTextColor: widget.disabledTextColor,
          color: _getFillColor(theme),
          splashColor: splashColor,
          highlightColor: widget.highlightColor,
          disabledColor: Colors.transparent,
          onPressed: widget.onPressed,
          elevation: 0.0,
          disabledElevation: 0.0,
          highlightElevation: _getHighlightElevation(),
          onHighlightChanged: (bool value) {
            setState(() {
              _pressed = value;
              if (value)
                _controller.forward();
              else
                _controller.reverse();
            });
          },
          padding: widget.padding,
          shape: new _OutlineBorder(
            shape: widget.shape ?? buttonTheme.shape,
            side: _getOutline(theme, buttonTheme),
          ),
          animationDuration: _kElevationDuration,
          child: widget.child,
        );
      },
    );
  }
}

// Render the button's outline border using using the OutlineButton's
// border parameters and the button or buttonTheme's shape.
class _OutlineBorder extends ShapeBorder {
  const _OutlineBorder({
    @required this.shape,
    @required this.side,
  }) : assert(shape != null),
       assert(side != null);

  final ShapeBorder shape;
  final BorderSide side;

  @override
  EdgeInsetsGeometry get dimensions {
    return new EdgeInsets.all(side.width);
  }

  @override
  ShapeBorder scale(double t) {
    return new _OutlineBorder(
      shape: shape.scale(t),
      side: side.scale(t),
    );
  }

  @override
  ShapeBorder lerpFrom(ShapeBorder a, double t) {
    assert(t != null);
    if (a is _OutlineBorder) {
      return new _OutlineBorder(
        side: BorderSide.lerp(a.side, side, t),
        shape: ShapeBorder.lerp(a.shape, shape, t),
      );
    }
    return super.lerpFrom(a, t);
  }

  @override
  ShapeBorder lerpTo(ShapeBorder b, double t) {
    assert(t != null);
    if (b is _OutlineBorder) {
      return new _OutlineBorder(
        side: BorderSide.lerp(side, b.side, t),
        shape: ShapeBorder.lerp(shape, b.shape, t),
      );
    }
    return super.lerpTo(b, t);
  }

  @override
  Path getInnerPath(Rect rect, { TextDirection textDirection }) {
    return shape.getInnerPath(rect.deflate(side.width), textDirection: textDirection);
  }

  @override
  Path getOuterPath(Rect rect, { TextDirection textDirection }) {
    return shape.getOuterPath(rect, textDirection: textDirection);
  }

  @override
  void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {
    switch (side.style) {
      case BorderStyle.none:
        break;
      case BorderStyle.solid:
        canvas.drawPath(shape.getOuterPath(rect), side.toPaint());
    }
  }

  @override
  bool operator ==(dynamic other) {
    if (identical(this, other))
      return true;
    if (runtimeType != other.runtimeType)
      return false;
    final _OutlineBorder typedOther = other;
    return side == typedOther.side && shape == typedOther.shape;
  }

  @override
  int get hashCode => hashValues(side, shape);
}
