
import 'dart:math';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';

class HourglassPainter extends CustomPainter{
  double fillAmount =0;
  List<Color> colors = [Colors.black];
  List<double> colorStops = [1];
  HourglassPainter(this.fillAmount, this.colors, this.colorStops);
  @override
  void paint(Canvas canvas, Size size) {
    double hourglassCurve = size.height * 0.5;
    double hourglassInset = size.width / 10;
    double hourglassHalfHeight = (size.height / 2) - hourglassInset;
    // const LinearGradient gradient = LinearGradient(
    //   tileMode: TileMode.clamp,
    //   colors: <Color>[
    //     Colors.blue,
    //     Colors.green,
    //     Colors.red// blue sky
    //   ],
    //   stops: <double>[0.2, 0.6,1],
    // );

    final outlinePainter = Paint()
      ..color=Colors.orangeAccent
    ..strokeCap=StrokeCap.round
    ..strokeWidth=5
     // ..shader=ui.Gradient.linear(Offset(0,0), Offset(100,100), [Colors.green, Colors.amber, Colors.blue])
    ..style=PaintingStyle.stroke;
    final outlinePainter2 = Paint()
      ..color=Colors.amber
      ..strokeCap=StrokeCap.round
      ..strokeWidth=8
    // ..shader=ui.Gradient.linear(Offset(0,0), Offset(100,100), [Colors.green, Colors.amber, Colors.blue])
      ..style=PaintingStyle.stroke;
    final contentPainter = Paint()
      ..color=Colors.brown
    ..strokeCap=StrokeCap.round
    ..strokeWidth=1;


    final outline = Path();

    outline.moveTo(hourglassInset, hourglassInset);
    outline.arcToPoint(Offset(size.width-hourglassInset,hourglassInset));
    outline.arcToPoint(Offset(size.width * 0.6,size.height * 0.45),radius: Radius.circular(hourglassCurve),clockwise: true);
    outline.arcToPoint(Offset(size.width * 0.55,size.height * 0.55),radius: Radius.circular(20),clockwise: false);
    outline.arcToPoint(Offset(size.width-hourglassInset,size.height-10),radius: Radius.circular(hourglassCurve),clockwise: true);
    outline.arcToPoint(Offset(hourglassInset, size.height-hourglassInset));
    outline.arcToPoint(Offset(size.width * 0.45,size.height * 0.55),radius: Radius.circular(hourglassCurve),clockwise: true);
    outline.arcToPoint(Offset(size.width * 0.4,size.height * 0.45),radius: Radius.circular(20),clockwise: false);
    outline.arcToPoint(Offset(hourglassInset,hourglassInset),radius: Radius.circular(hourglassCurve),clockwise: true);
    outline.close();

    final topContent = Path();
    double topStartHeight = size.height*(0.4 -((1-fillAmount) *0.3));
    double topEndHeight = size.height * 0.48;
    double topContentStartWidthOffset = getTopContentWidthOffset(size.width, topStartHeight, hourglassHalfHeight, hourglassInset);
    double topContentEndWidthOffset = getTopContentWidthOffset(size.width, topEndHeight, hourglassHalfHeight, hourglassInset);
    // double contentWidthOffset = (((size.width /2) - hourglassInset) * sin((endHeight/hourglassHalfHeight) * (pi/6)));

    topContent.moveTo(topContentStartWidthOffset,topStartHeight);
    topContent.arcToPoint(Offset(hourglassInset+ topContentEndWidthOffset,topEndHeight), radius: Radius.circular(hourglassCurve),clockwise: false);
    topContent.arcToPoint(Offset((size.width - hourglassInset)-topContentEndWidthOffset,topEndHeight));
    topContent.arcToPoint(Offset(size.width - topContentStartWidthOffset,topStartHeight), radius: Radius.circular(hourglassCurve),clockwise: false);
    topContent.close();
    
    final bottomContent = Path();
    double bottomStartHeight = size.height-12;
    double bottomEndHeight = size.height * (0.95 - (fillAmount * 0.32));
    double bottomContentStartWidthOffset = getBottomContentWidthOffset(size.width, bottomStartHeight, hourglassHalfHeight, hourglassInset);
    double bottomContentEndWidthOffset = getBottomContentWidthOffset(size.width, bottomEndHeight, hourglassHalfHeight, hourglassInset);
    // double contentWidthOffset = (((size.width /2) - hourglassInset) * sin((endHeight/hourglassHalfHeight) * (pi/6)));

    bottomContent.moveTo(bottomContentStartWidthOffset,bottomStartHeight);
    bottomContent.arcToPoint(Offset(hourglassInset+ bottomContentEndWidthOffset,bottomEndHeight), radius: Radius.circular(hourglassCurve),clockwise: true);
    bottomContent.arcToPoint(Offset(size.width/2,bottomEndHeight-size.height*0.02),);
    bottomContent.arcToPoint(Offset((size.width - hourglassInset)-bottomContentEndWidthOffset,bottomEndHeight));
    bottomContent.arcToPoint(Offset(size.width - bottomContentStartWidthOffset,bottomStartHeight), radius: Radius.circular(hourglassCurve),clockwise: true);
    bottomContent.close();

    final fallingSand = Path();
    fallingSand.moveTo(size.width*0.4,(size.height*0.48));
    fallingSand.arcToPoint(Offset(size.width*0.495,(size.height*0.57)));
    fallingSand.lineTo(size.width*0.48,size.height -hourglassInset);
    fallingSand.lineTo(size.width*0.52,size.height -hourglassInset);
    fallingSand.arcToPoint(Offset(size.width*0.505,(size.height*0.57)));
    fallingSand.arcToPoint(Offset(size.width*0.6,(size.height*0.48)));
    fallingSand.close();

    final gradient = ui.Gradient.linear(
        Offset(size.width/2, bottomStartHeight - 1),
        Offset(size.width/2, bottomEndHeight),
         colors,
        colorStops,
    TileMode.clamp);
    final bottomContentPainter = Paint()
      ..shader=gradient
      ..style=PaintingStyle.fill
      ..strokeCap=StrokeCap.round
      ..strokeWidth=1;

    print('bottom: $bottomStartHeight, top: $bottomEndHeight');

    canvas.drawPath(fallingSand, contentPainter);
    canvas.drawPath(topContent, contentPainter);
    canvas.drawPath(bottomContent, bottomContentPainter);
    canvas.drawPath(outline, outlinePainter);
    canvas.drawLine(Offset(0,0),Offset(size.width,0),outlinePainter2);
    canvas.drawLine(Offset(0,size.height),Offset(size.width,size.height),outlinePainter2);
  }

  double getTopContentWidthOffset(double width,double height,double fullHeight, double inset){
    return (((width /2) - inset) * sin((height/fullHeight) * (pi/3.8)));
  }
  double getBottomContentWidthOffset(double width,double height,double fullHeight, double inset){
    return (((width /2) - inset) * sin(1-((height/fullHeight) * (pi/8.9))));
  }


  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
    //throw UnimplementedError();
  }

}