import 'package:flutter/material.dart';

class HTStarRating extends StatefulWidget {
  final double rating; // 当前分数
  final double maxRating; // 满分
  final int count; // 总共几颗心
  final double size; // 星星大小
  final Color defaultColor;
  final Color selectedColor;
  final Widget unselectedImage;
  final Widget selectedImage;

  HTStarRating({
    required this.rating, // 必填
    //选填, 初始默认值
    this.maxRating = 10,
    this.count = 5,
    this.size = 30,
    this.defaultColor = Colors.grey,
    this.selectedColor = Colors.red,
    Widget? unselectedImage,
    Widget? selectedImage,
  })  : unselectedImage = unselectedImage ??
            Icon(Icons.star_border, color: defaultColor, size: size),
        selectedImage =
            selectedImage ?? Icon(Icons.star, color: selectedColor, size: size);

  @override
  _HTStarRatingState createState() => _HTStarRatingState();
}

class _HTStarRatingState extends State<HTStarRating> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Row(mainAxisSize: MainAxisSize.min, children: buildDefaultStar()),
        Row(mainAxisSize: MainAxisSize.min, children: buildSelectedStar())
      ],
    );
  }

  /*
  *  创建默认的星星
  * */
  List<Widget> buildDefaultStar() {
    return List.generate(widget.count, (index) {
      return widget.unselectedImage;
    });
  }

  /*
  *  创建选中的星星
  * */
  List<Widget> buildSelectedStar() {
    // 创建stats
    List<Widget> starts = [];
    final star = widget.selectedImage;
    //构建满的start
    double oneValue = widget.maxRating / widget.count;
    int entireCount = (widget.rating / oneValue).floor(); //.floor() 向下取整

    for (var i = 0; i < entireCount; i++) {
      starts.add(star);
    }
    //构建部分start
    double leftWidth = ((widget.rating / oneValue) - entireCount) * widget.size;
    final halfStar = ClipRect(clipper: HTStartClipper(leftWidth), child: star);
    starts.add(halfStar);

    // 防止传入参数大于总分
    if (starts.length > widget.count) {
      return starts.sublist(0, widget.count);
    }

    return starts;
  }
}

/*
* 切割
* */
class HTStartClipper extends CustomClipper<Rect> {
  double width;

  HTStartClipper(this.width);

  @override
  Rect getClip(Size size) {
    return Rect.fromLTRB(0, 0, width, size.height);
  }

  @override
  bool shouldReclip(HTStartClipper oldClipper) {
    return oldClipper.width != this.width;
  }
}