import 'package:flutter/material.dart';

/// My custom list tile to add extra features to the default
/// implementation
///
/// @author Pierre HUBERT

class CustomListTile extends StatelessWidget {
  final Widget leading;
  final Widget title;
  final Widget subtitle;
  final Widget trailing;
  final bool isThreeLine;
  final bool dense;
  final EdgeInsetsGeometry contentPadding;
  final bool enabled;
  final GestureTapCallback onTap;
  final GestureLongPressCallback onLongPress;
  final bool selected;
  final Color tileColor;

  /// Custom onLongPress function
  final Function(Size, Offset) onLongPressWithInfo;

  /// Show menu onLongPress
  final Function(RelativeRect) onLongPressOpenMenu;

  const CustomListTile({
    Key key,
    this.leading,
    this.title,
    this.subtitle,
    this.trailing,
    this.isThreeLine = false,
    this.dense,
    this.contentPadding,
    this.enabled = true,
    this.onTap,
    this.onLongPress,
    this.selected = false,
    this.onLongPressWithInfo,
    this.onLongPressOpenMenu,
    this.tileColor,
  })  : assert(isThreeLine != null),
        assert(enabled != null),
        assert(selected != null),
        assert(!isThreeLine || subtitle != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      tileColor: tileColor,
      leading: leading,
      title: title,
      subtitle: subtitle,
      trailing: trailing,
      isThreeLine: isThreeLine,
      dense: dense,
      contentPadding: contentPadding,
      enabled: enabled,
      onTap: onTap,
      onLongPress: () => _longPress(context),
      selected: selected,
    );
  }

  void _longPress(BuildContext context) {
    if (onLongPress != null) onLongPress();

    if (onLongPressWithInfo != null || onLongPressOpenMenu != null) {
      RenderBox renderBox = context.findRenderObject();
      final size = renderBox.size;
      final offset = renderBox.localToGlobal(Offset(size.width, size.height));

      if (onLongPressWithInfo != null) onLongPressWithInfo(size, offset);

      if (onLongPressOpenMenu != null) {
        final position = RelativeRect.fromLTRB(
          offset.dx - size.width,
          offset.dy,
          offset.dx,
          offset.dy + size.height,
        );

        onLongPressOpenMenu(position);
      }
    }
  }
}