// Copyright 2015 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/widgets.dart';

import 'colors.dart';
import 'constants.dart';
import 'theme.dart';
import 'theme_data.dart';

// Examples can assume:
// String userAvatarUrl;

/// A circle that represents a user.
///
/// Typically used with a user's profile image, or, in the absence of
/// such an image, the user's initials. A given user's initials should
/// always be paired with the same background color, for consistency.
///
/// ## Sample code
///
/// If the avatar is to have an image, the image should be specified in the
/// [backgroundImage] property:
///
/// ```dart
/// new CircleAvatar(
///   backgroundImage: new NetworkImage(userAvatarUrl),
/// )
/// ```
///
/// The image will be cropped to have a circle shape.
///
/// If the avatar is to just have the user's initials, they are typically
/// provided using a [Text] widget as the [child] and a [backgroundColor]:
///
/// ```dart
/// new CircleAvatar(
///   backgroundColor: Colors.brown.shade800,
///   child: new Text('AH'),
/// )
/// ```
///
/// See also:
///
///  * [Chip], for representing users or concepts in long form.
///  * [ListTile], which can combine an icon (such as a [CircleAvatar]) with some
///    text for a fixed height list entry.
///  * <https://material.google.com/components/chips.html#chips-contact-chips>
class CircleAvatar extends StatelessWidget {
  /// Creates a circle that represents a user.
  const CircleAvatar({
    Key key,
    this.child,
    this.backgroundColor,
    this.backgroundImage,
    this.foregroundColor,
    this.radius: 20.0,
  }) : super(key: key);

  /// The widget below this widget in the tree.
  ///
  /// Typically a [Text] widget. If the [CircleAvatar] is to have an image, use
  /// [backgroundImage] instead.
  final Widget child;

  /// The color with which to fill the circle. Changing the background
  /// color will cause the avatar to animate to the new color.
  ///
  /// If a background color is not specified, the theme's primary color is used.
  final Color backgroundColor;

  /// The default text color for text in the circle.
  ///
  /// Falls back to white if a background color is specified, or the primary
  /// text theme color otherwise.
  final Color foregroundColor;

  /// The background image of the circle. Changing the background
  /// image will cause the avatar to animate to the new image.
  ///
  /// If the [CircleAvatar] is to have the user's initials, use [child] instead.
  final ImageProvider backgroundImage;

  /// The size of the avatar. Changing the radius will cause the
  /// avatar to animate to the new size.
  ///
  /// Defaults to 20 logical pixels.
  final double radius;

  @override
  Widget build(BuildContext context) {
    assert(debugCheckHasMediaQuery(context));
    final ThemeData theme = Theme.of(context);
    TextStyle textStyle = theme.primaryTextTheme.title;
    if (foregroundColor != null) {
      textStyle = textStyle.copyWith(color: foregroundColor);
    } else if (backgroundColor != null) {
      switch (ThemeData.estimateBrightnessForColor(backgroundColor)) {
        case Brightness.dark:
          textStyle = textStyle.copyWith(color: Colors.white);
          break;
        case Brightness.light:
          textStyle = textStyle.copyWith(color: Colors.black);
          break;
      }
    }
    return new AnimatedContainer(
      width: radius * 2.0,
      height: radius * 2.0,
      duration: kThemeChangeDuration,
      decoration: new BoxDecoration(
        color: backgroundColor ?? theme.primaryColor,
        image: backgroundImage != null ? new DecorationImage(
          image: backgroundImage
        ) : null,
        shape: BoxShape.circle,
      ),
      child: child != null ? new Center(
        child: new MediaQuery(
          // Need to reset the textScaleFactor here so that the
          // text doesn't escape the avatar when the textScaleFactor is large.
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
          child: new DefaultTextStyle(
            style: textStyle.copyWith(color: foregroundColor),
            child: child,
          ),
        )
      ) : null,
    );
  }
}