// 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 'debug.dart';
import 'ink_well.dart';
import 'theme.dart';

/// Material List items are one to three lines of text optionally flanked by icons.
/// Icons are defined with the [leading] and [trailing] parameters. The first line of text
/// is not optional and is specified with [title]. The value of [subtitle] will
/// occupy the space allocated for an aditional line of text, or two lines if
/// isThreeLine: true is specified. If dense: true is specified then the overall
/// height of this list item and the size of the DefaultTextStyles that wrap
/// the [title] and [subtitle] widget are reduced.
class ListItem extends StatelessWidget {
  ListItem({
    Key key,
    this.leading,
    this.title,
    this.subtitle,
    this.trailing,
    this.isThreeLine: false,
    this.dense: false,
    this.enabled: true,
    this.onTap,
    this.onLongPress
  }) : super(key: key) {
    assert(isThreeLine ? subtitle != null : true);
  }

  final Widget leading;
  final Widget title;
  final Widget subtitle;
  final Widget trailing;
  final bool isThreeLine;
  final bool dense;
  final bool enabled;
  final GestureTapCallback onTap;
  final GestureLongPressCallback onLongPress;

  /// Add a one pixel border in between each item. If color isn't specified the
  /// dividerColor of the context's theme is used.
  static Iterable<Widget> divideItems({ BuildContext context, Iterable<Widget> items, Color color }) sync* {
    assert(items != null);
    assert(color != null || context != null);

    final Color dividerColor = color ?? Theme.of(context).dividerColor;
    final Iterator<Widget> iterator = items.iterator;
    final bool isNotEmpty = iterator.moveNext();

    Widget item = iterator.current;
    while(iterator.moveNext()) {
      yield new DecoratedBox(
        decoration: new BoxDecoration(
          border: new Border(
            bottom: new BorderSide(color: dividerColor)
          )
        ),
        child: item
      );
      item = iterator.current;
    }
    if (isNotEmpty)
      yield item;
  }

  TextStyle primaryTextStyle(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final TextStyle style = theme.textTheme.subhead;
    if (!enabled) {
      final Color color = theme.disabledColor;
      return dense ? style.copyWith(fontSize: 13.0, color: color) : style.copyWith(color: color);
    }
    return dense ? style.copyWith(fontSize: 13.0) : style;
  }

  TextStyle secondaryTextStyle(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final Color color = theme.textTheme.caption.color;
    final TextStyle style = theme.textTheme.body1;
    return dense ? style.copyWith(color: color, fontSize: 12.0) : style.copyWith(color: color);
  }

  @override
  Widget build(BuildContext context) {
    assert(debugCheckHasMaterial(context));
    final bool isTwoLine = !isThreeLine && subtitle != null;
    final bool isOneLine = !isThreeLine && !isTwoLine;
    double itemHeight;
    if (isOneLine)
      itemHeight = dense ? 48.0 : 56.0;
    else if (isTwoLine)
      itemHeight = dense ? 60.0 : 72.0;
    else
      itemHeight = dense ? 76.0 : 88.0;

    double iconMarginTop = 0.0;
    if (isThreeLine)
      iconMarginTop = dense ? 8.0 : 16.0;

    // Overall, the list item is a Row() with these children.
    final List<Widget> children = <Widget>[];

    if (leading != null) {
      children.add(new Container(
        margin: new EdgeInsets.only(right: 16.0, top: iconMarginTop),
        width: 40.0,
        child: new Align(
          alignment: new FractionalOffset(0.0, isThreeLine ? 0.0 : 0.5),
          child: leading
        )
      ));
    }

    final Widget primaryLine = new DefaultTextStyle(
      style: primaryTextStyle(context),
      child: title ?? new Container()
    );
    Widget center = primaryLine;
    if (isTwoLine || isThreeLine) {
      center = new Column(
        mainAxisAlignment: MainAxisAlignment.collapse,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          primaryLine,
          new DefaultTextStyle(
            style: secondaryTextStyle(context),
            child: subtitle
          )
        ]
      );
    }
    children.add(new Flexible(
      child: center
    ));

    if (trailing != null) {
      children.add(new Container(
        margin: new EdgeInsets.only(left: 16.0, top: iconMarginTop),
        child: new Align(
          alignment: new FractionalOffset(1.0, isThreeLine ? 0.0 : 0.5),
          child: trailing
        )
      ));
    }

    return new InkWell(
      onTap: enabled ? onTap : null,
      onLongPress: enabled ? onLongPress : null,
      child: new Container(
        height: itemHeight,
        padding: const EdgeInsets.symmetric(horizontal: 16.0),
        child: new Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: children
        )
      )
    );
  }
}