import 'package:flutter/material.dart';

class EcgPainter extends CustomPainter {
  /// 分为新数据和历史数据
  final List<int> newPoints;
  final List<int> oldPoints;

  /// 横坐标数据量（横轴一共多少个点）
  final int xDataCount;

  /// 纵坐标最大值
  final double yMax;

  EcgPainter({
    required this.newPoints,
    required this.oldPoints,
    required this.xDataCount,
    required this.yMax,
  });

  @override
  void paint(Canvas canvas, Size size) {
    /// 如果只存在新数据，那么直接绘制新数据心电折线，如果只存在历史数据，那么直接绘制历史数据心电折线，如果两者都存在，那么先绘制历史数据心电折线，再绘制新数据心电折线
    if (newPoints.isNotEmpty && oldPoints.isEmpty) {
      // print("newPoints: ${newPoints.length}");
      drawPoints(canvas, size, newPoints);
    } else if (newPoints.isEmpty && oldPoints.isNotEmpty) {
      drawPoints(canvas, size, oldPoints);
    } else if (newPoints.isNotEmpty && oldPoints.isNotEmpty) {
      drawPointsWithFade(canvas, size, oldPoints, offset: newPoints.length);
      drawPoints(canvas, size, newPoints);
    }
  }

  void drawPoints(
    Canvas canvas,
    Size size,
    List<int> points, {
    int offset = 0,
  }) {
    final paint = Paint()
      ..color = Colors.green
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    final double xGridSize = size.width / xDataCount;
    final double yScale = size.height / 2 / yMax;

    final double yCenter = size.height / 2;

    final path = Path();
    for (int i = offset; i < points.length; i++) {
      final offsetX = i * xGridSize;
      final offsetY = -points[i] * yScale + yCenter;
      if (i == offset) {
        path.moveTo(offsetX, offsetY);
      } else {
        path.lineTo(offsetX, offsetY);
      }
    }
    canvas.drawPath(path, paint);
  }

  /// 由渐隐到渐显的曲线
  void drawPointsWithFade(
    Canvas canvas,
    Size size,
    List<int> points, {
    int offset = 0,
  }) {
    final paint = Paint()
      ..color = Colors.green
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    final double xGridSize = size.width / xDataCount;
    final double yScale = size.height / 2 / yMax;

    final double yCenter = size.height / 2;

    final path = Path();
    for (int i = offset; i < points.length; i++) {
      final offsetX = i * xGridSize;
      final offsetY = -points[i] * yScale + yCenter;
      if (i == offset) {
        path.moveTo(offsetX, offsetY);
      } else {
        path.lineTo(offsetX, offsetY);
      }
    }
    final double shaderStartX = offset * xGridSize;
    final double shaderWidth = 30 * xGridSize;
    Rect rect = Rect.fromLTWH(shaderStartX, 0, shaderWidth, size.height);
    paint.shader = const LinearGradient(
      begin: Alignment.centerLeft,
      end: Alignment.centerRight,
      colors: [Color.fromARGB(0, 76, 175, 79), Colors.green],
    ).createShader(rect);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
