/*
  COPYRIGHT 2020. @ishandeveloper
  
  YOU CAN FIND THE REFACTORED CODE AT https://github.com/ishandeveloper/WinAMP_Flutter
  
  LISTEN TO ACTUAL MUSIC IN THE DEMO AT :
  
  https://winamp.ishandeveloper.com
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:ui';

bool mono = false;
double seekTime = 0;
String currentTrack = "No Track Selected";
String trackMin = "00";
String trackSec = "00";

int trackMinint = 0;
int trackSecint = 0;

void main() {
  runApp(
    MaterialApp(
      title: 'Ishan Sharma',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        scaffoldBackgroundColor: Colors.black,
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Player(),
    ),
  );
}

class Player extends StatefulWidget {
  @override
  _PlayerState createState() => _PlayerState();
}

class _PlayerState extends State<Player> {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 768) {
          return DesktopUI();
        }
        return MobileUI();
      },
    );
  }
}

class DesktopUI extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff020088),
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/xp.jpg?raw=false'),
            fit: BoxFit.cover,
          ),
        ),
        child: Center(
          child: Container(
            width: 780,
            height: 350,
            decoration: BoxDecoration(color: Colors.black, boxShadow: [
              BoxShadow(blurRadius: 5, color: Colors.black, spreadRadius: 1)
            ]),
            child: Column(
              children: [
                DesktopNavbar(),
                DesktopMain(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// DESKTOP NAVBAR

class DesktopNavbar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
      child: Row(
        children: [
          WinLogo(),
          SizedBox(width: 10),
          Row(
            children: [
              NavLine(),
              SizedBox(width: 10),
              Text(
                "WINAMP",
                style: TextStyle(
                  color: Colors.white,
                  fontFamily: 'Pixer',
                  fontSize: 18,
                ),
              ),
              SizedBox(width: 10),
              NavLine(),
              SizedBox(width: 10),
              Padding(
                padding: const EdgeInsets.all(0.0),
                child: Container(
                  width: 18,
                  height: 18,
                  decoration: BoxDecoration(
                      image: DecorationImage(
                    image: NetworkImage(
                      'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/btn1.png?raw=false',
                    ),
                    fit: BoxFit.cover,
                  )),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(0.0),
                child: Container(
                  width: 18,
                  height: 18,
                  decoration: BoxDecoration(
                      // color: Colors.white,
                      image: DecorationImage(
                    image: NetworkImage(
                      'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/btn1.png?raw=false',
                    ),
                    fit: BoxFit.cover,
                  )),
                ),
              )
            ],
          )
        ],
      ),
    );
  }
}

class DesktopMain extends StatefulWidget {
  @override
  _DesktopMainState createState() => _DesktopMainState();
}

class _DesktopMainState extends State<DesktopMain> {
  bool paused = true;
  bool initial = true;

  @override
  Widget build(BuildContext context) {
    void stopMusic() {
      setState(() {
        paused = true;
        currentTrack = "No Track Selected";
      });
    }

    void trackTime() {
      setState(() {
        // ignore: division_optimization
        trackMinint = (seekTime / 60).toInt();
        trackSecint = (seekTime - (trackMinint * 60)).toInt();
      });

      if (trackSecint < 10) {
        setState(() {
          trackSec = "0" + trackSecint.toString();
        });
      } else {
        setState(() {
          trackSec = trackSecint.toString();
        });
      }

      setState(() {
        trackMin = "0" + trackMinint.toString();
      });

      if (trackMin == "04" && trackSec == "59") {
        setState(() {
          seekTime = 0;
          trackMinint = 0;
          trackSecint = 0;
          trackMin = "00";
          trackSec = "00";
        });
        stopMusic();
      }
    }

    void seeker() async {
      Timer.periodic(Duration(milliseconds: 1000), (timer) {
        if (!paused) {
          setState(() {
            seekTime += 1;
          });
          trackTime();
        } else {
          // dispose();
        }
      });
    }

    void playMusic() async {
      if (paused) {
        // playAudio('assets/music.mp3');
        setState(() {
          paused = false;
          // initial=false;
          currentTrack = "Silent - DEMO Track (*JavaScript Required)";
        });
        if (initial) {
          setState(() {
            initial = false;
            seekTime = 0;
          });
          seeker();
        }
      }
    }

    void seekMusic(double position) {
      int time = position.toInt();

      setState(() {
        trackSecint = time;
        seekTime = position;
      });
      trackTime();
    }

    void pauseMusic() {
      setState(() {
        paused = true;
        currentTrack = "PAUSED - Silent - DEMO Track (*JavaScript Required)";
      });
    }

    return Container(
      width: 770,
      height: 300,
      decoration: BoxDecoration(
        border: Border.all(color: Color(0xFF555569), width: 2.0),
        gradient: LinearGradient(
          begin: Alignment.centerLeft,
          end: Alignment(0.8, 0.0),
          colors: [
            Color(0xFF212132),
            Color(0XFF353454),
            Color(0xFF474766),
          ],
          tileMode: TileMode.repeated,
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            /* TOP CONTROLS */
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Transform.scale(
                    scale: 1,
                    child: MainInfoWidget(
                        minutes: trackMin,
                        seconds: trackSec,
                        playing: !paused)),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    TrackNameBar(currentTrack),
                    SizedBox(height: 15),
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        MiniControls(
                            units: "kbps",
                            initialValue: 160,
                            min: 98,
                            max: 320),
                        MiniControls(
                          units: "dB",
                          initialValue: 50,
                          min: 0,
                          max: 100,
                          control: (double level) {
                            // setAudioVolume(level);
                          },
                        ),
                        MiniControls(
                            units: "kHz", initialValue: 44, min: 32, max: 98),
                        Row(
                          children: [
                            Column(
                              children: [
                                ControlLabel(
                                    text: "mono",
                                    enabled: mono,
                                    onPress: () {
                                      setState(() {
                                        mono = true;
                                      });
                                    }),
                                SizedBox(height: 15),
                                MiniButton(light: Colors.yellow, text: "EQ"),
                              ],
                            ),
                            SizedBox(width: 10),
                            Column(
                              children: [
                                ControlLabel(
                                    text: "stereo",
                                    enabled: !mono,
                                    onPress: () => setState(() {
                                          mono = false;
                                        })),
                                SizedBox(height: 15),
                                MiniButton(light: Colors.red, text: "PL"),
                              ],
                            )
                          ],
                        )
                      ],
                    ),
                  ],
                )
              ],
            ),
            SizedBox(height: 15),
            SeekBar(
              min: 0,
              max: 300, // Time in seconds,
              value: seekTime,
              seek: (val) {
                print("SEEKED" + val.toString());
                seekMusic(val);
              },
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Row(
                  children: [
                    RetroButton(
                        onPress: () {
                          seekMusic(0);
                        },
                        icon: Icons.fast_rewind),
                    SizedBox(width: 5),
                    RetroButton(
                        onPress: () => playMusic(), icon: Icons.play_arrow),
                    SizedBox(width: 5),
                    RetroButton(onPress: () => pauseMusic(), icon: Icons.pause),
                    SizedBox(width: 5),
                    RetroButton(
                        onPress: () {
                          stopMusic();
                          this.initState();
                        },
                        icon: Icons.stop),
                    SizedBox(width: 5),
                    RetroButton(onPress: () {}, icon: Icons.fast_forward),
                    SizedBox(width: 10),
                    RetroButton(onPress: () {}, icon: Icons.eject),
                  ],
                ),
                Row(
                  children: [
                    TextControlButton(text: "Shuffle", light: Colors.red),
                    SizedBox(width: 10),
                    TextControlButton(
                        icon: true,
                        ico: Icons.repeat,
                        light: Colors.yellow,
                        width: 40)
                  ],
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

class TextControlButton extends StatefulWidget {
  final Color light;
  final String text;
  final bool selected;
  final bool icon;
  final double width;
  final IconData ico;

  TextControlButton(
      {this.light,
      this.text,
      this.selected = false,
      this.icon = false,
      this.width = 60,
      this.ico});

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

class _TextControlButtonState extends State<TextControlButton> {
  bool enabled;
  @override
  void initState() {
    enabled = widget.selected;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          enabled = !enabled;
        });
      },
      child: Container(
        width: widget.width,
        height: 30,
        decoration: BoxDecoration(
            color: enabled ? Color(0xFFBDCED6) : Color(0xFFBDCED6),
            border: Border(
              top: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              left: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              right: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
              bottom: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
            )),
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          Container(
            height: 10,
            width: 10,
            decoration: BoxDecoration(
                color: widget.light,
                border: Border.all(color: Color(0xFF000000), width: 1)),
          ),
          widget.icon
              ? Icon(
                  widget.ico,
                  size: 18,
                  color: Colors.black,
                )
              : Text(
                  widget.text,
                  style: TextStyle(
                      fontFamily: 'Pixer', color: Colors.black, fontSize: 14),
                ),
        ]),
      ),
    );
  }
}

class SeekBar extends StatelessWidget {
  final Function seek;
  final double min;
  final double max;
  final double value;
  SeekBar({this.seek, this.min, this.max, this.value});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
        Container(
          // decoration: BoxDecoration(color: Color(0xff1B1932)),
          child: CustomSlider(
            value: value,
            min: min,
            max: max,
            thumbSize: 34.0,
            sliderWidth: 720.0,
            thumbColor: Colors.yellow,
            roundedRectangleThumbRadius: 0.0,
            topLeftShadow: false,
            bottomRightShadow: true,
            bottomRightShadowBlur: MaskFilter.blur(BlurStyle.outer, 3),
            bottomRightShadowColor: Colors.black,
            activeLineStroke: 2.0,
            activeLineColor: Color(0xff1B1932),
            inactiveLineColor: Color(0xff1B1932),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Center(
                  child: Text(
                '──',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18.0,
                  fontFamily: 'Pixer',
                  fontWeight: FontWeight.bold,
                ),
              )),
            ),
            onChanged: (double val) {
              seek(val);
            },
          ),
        ),
      ],
    );
  }
}

class RetroButton extends StatefulWidget {
  final IconData icon;
  final Function onPress;
  final double width;
  final double height;
  RetroButton({this.icon, this.onPress, this.width = 50, this.height = 30});

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

class _RetroButtonState extends State<RetroButton> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: widget.onPress,
      child: Container(
        width: widget.width,
        height: widget.height,
        decoration: BoxDecoration(
            color: Color(0xFFBDCED6),
            border: Border(
              top: BorderSide(width: 1, color: Color(0xFFFFFFFF)),
              left: BorderSide(width: 1, color: Color(0xFFFFFFFF)),
              right: BorderSide(width: 2, color: Color(0xFF000000)),
              bottom: BorderSide(width: 2, color: Color(0xFF000000)),
            )),
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          Icon(
            widget.icon,
            size: 24,
            color: Color(0xff687582),
          ),
        ]),
      ),
    );
  }
}

class MiniButton extends StatefulWidget {
  final Color light;
  final String text;
  final bool selected;

  MiniButton({this.light, this.text, this.selected = false});

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

class _MiniButtonState extends State<MiniButton> {
  bool enabled;
  @override
  void initState() {
    enabled = widget.selected;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          enabled = !enabled;
        });
      },
      child: Container(
        width: 40,
        height: 25,
        decoration: BoxDecoration(
            color: enabled ? Color(0xFFBDCED6) : Colors.grey[500],
            border: Border(
              top: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              left: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              right: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
              bottom: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
            )),
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          Container(
            height: 10,
            width: 10,
            decoration: BoxDecoration(
                color: widget.light,
                border: Border.all(color: Color(0xFF000000), width: 1)),
          ),
          Text(
            widget.text,
            style: TextStyle(
                fontFamily: 'Pixer', color: Colors.black, fontSize: 16),
          ),
        ]),
      ),
    );
  }
}

class ControlLabel extends StatelessWidget {
  final String text;
  final bool enabled;
  final Function onPress;

  ControlLabel({this.text, this.enabled, this.onPress});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onPress,
      child: Text(
        text,
        style: TextStyle(
            fontFamily: 'Pixer',
            fontSize: 18,
            color: enabled ? Color(0XFF04E406) : Colors.white),
      ),
    );
  }
}

class MiniControls extends StatefulWidget {
  final String units;
  final double initialValue;
  final double min;
  final double max;
  final Function control;

  MiniControls(
      {this.units, this.initialValue, this.min, this.max, this.control});

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

class _MiniControlsState extends State<MiniControls> {
  double _value = 0;

  @override
  void initState() {
    _value = widget.initialValue;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Container(
              width: 45,
              height: 32,
              padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
              decoration: BoxDecoration(
                color: Color(0xFF040405),
                border: Border(
                  right: BorderSide(width: 2, color: Color(0xFF555569)),
                  bottom: BorderSide(width: 2, color: Color(0xFF555569)),
                ),
                image: DecorationImage(
                    image: NetworkImage(
                        'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
                    fit: BoxFit.fill,
                    repeat: ImageRepeat.repeat),
              ),
              child: Text(
                _value.toString(),
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontFamily: 'Pixer',
                    fontSize: 19,
                    color: Color(0XFF04E406)),
              ),
            ),
            SizedBox(
              width: 5,
            ),
            Text(
              widget.units,
              style: TextStyle(
                  fontFamily: 'Pixer', fontSize: 18, color: Colors.white),
            ),
          ],
        ),
        SizedBox(height: 10),
        Container(
          padding: EdgeInsets.all(0),
          width: 110,
          child: AwesomeSlider(
            value: _value,
            min: widget.min,
            max: widget.max,
            thumbSize: 22.0,
            sliderWidth: 80.0,
            thumbColor: Colors.grey[500],
            roundedRectangleThumbRadius: 0.0,
            topLeftShadow: false,
            bottomRightShadow: true,
            bottomRightShadowBlur: MaskFilter.blur(BlurStyle.outer, 3),
            bottomRightShadowColor: Colors.black,
            activeLineStroke: 2.0,
            activeLineColor: Color(0xFF248A19),
            inactiveLineColor: Color(0xFF248A19),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Center(
                  child: Text(
                '〣 ',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18.0,
                  fontFamily: 'Pixer',
                  fontWeight: FontWeight.bold,
                ),
              )),
            ),
            onChanged: (double value) {
              widget.control(value);
              setState(() {
                _value = value;
              });
            },
          ),
        ),
      ],
    );
  }
}

class TrackNameBar extends StatelessWidget {
  final String trackName;

  TrackNameBar(this.trackName);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 460,
      height: 32,
      padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Text(
        this.trackName,
        textAlign: TextAlign.right,
        style: TextStyle(
            fontFamily: 'Pixer', fontSize: 18, color: Color(0XFF04E406)),
      ),
    );
  }
}

class MainInfoWidget extends StatelessWidget {
  final String minutes;
  final String seconds;
  final bool playing;

  MainInfoWidget({this.minutes, this.seconds, this.playing});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 250,
      height: 150,
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            SidebarText(),
            Column(
              children: [
                MusicTimer(minutes: this.minutes, seconds: this.seconds),
                Container(
                  width: 190,
                  height: 50,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                        image: playing
                            ? NetworkImage(
                                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/music_bars.gif?raw=false')
                            : NetworkImage(
                                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/musicbars.png?raw=false')),
                  ),
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class SidebarText extends StatelessWidget {
  const SidebarText({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Text(
          "O",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "A",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "I",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "D",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "V",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
      ],
    );
  }
}

class MusicTimer extends StatelessWidget {
  final String minutes;
  final String seconds;

  MusicTimer({this.minutes, this.seconds});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          "▶- ",
          style: TextStyle(
              fontFamily: 'Pixer', fontSize: 36, color: Color(0XFF04E406)),
        ),
        Text(
          "${this.minutes}:${this.seconds}",
          style: TextStyle(
              fontFamily: 'Pixer', fontSize: 64, color: Color(0XFF04E406)),
        ),
      ],
    );
  }
}

class WinLogo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 36,
      height: 36,
      decoration: BoxDecoration(
          // color: Colors.white,
          image: DecorationImage(
        image: NetworkImage(
          'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/logo.png?raw=false',
        ),
        fit: BoxFit.cover,
      )),
    );
  }
}

class NavLine extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 285,
      color: Colors.yellow,
      height: 5,
    );
  }
}

/* MOBILE */
class MobileUI extends StatefulWidget {
  @override
  _MobileUIState createState() => _MobileUIState();
}

class _MobileUIState extends State<MobileUI> {
  bool mono = false;
  double seekTime = 0;
  String currentTrack = "No Track Selected";
  String trackMin = "00";
  String trackSec = "00";

  int trackMinint = 0;
  int trackSecint = 0;

  bool paused = true;
  bool initial = true;

  @override
  void initState() {
    setState(() {
      mono = false;
      seekTime = 0;
      currentTrack = "No Track Selected";
      trackMin = "00";
      trackSec = "00";
      trackMinint = 0;
      trackSecint = 0;
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // ignore: unused_element
    void stopMusic() {
      setState(() {
        paused = true;
        currentTrack = "No Track Selected";
      });
    }

    void trackTime() {
      setState(() {
        // ignore: division_optimization
        trackMinint = (seekTime / 60).toInt();
        trackSecint = (seekTime - (trackMinint * 60)).toInt();
      });

      if (trackSecint < 10) {
        setState(() {
          trackSec = "0" + trackSecint.toString();
        });
      } else {
        setState(() {
          trackSec = trackSecint.toString();
        });
      }

      setState(() {
        trackMin = "0" + trackMinint.toString();
      });

      if (trackMin == "03" && trackSec == "04") {
        setState(() {
          seekTime = 0;
          trackMinint = 0;
          trackSecint = 0;
          trackMin = "00";
          trackSec = "00";
        });
        stopMusic();
        // seekAudio(0);
      }
    }

    void seeker() async {
      Timer.periodic(Duration(milliseconds: 1000), (timer) {
        if (!paused) {
          trackTime();

          if (seekTime == 185) {
            stopMusic();
          }

          setState(() {
            seekTime += 1;
          });
        } else {
          // dispose();
        }
      });
    }

    // ignore: unused_element
    void playMusic() {
      if (paused) {
        // playAudio();
        setState(() {
          paused = false;
          // initial=false;
          currentTrack = "Silent - DEMO Track (*JavaScript Required)";
        });
        if (initial) {
          setState(() {
            initial = false;
            seekTime = 0;
          });
          seeker();
        }
      }
    }

    // ignore: unused_element
    void seekMusic(double position) {
      int time = position.toInt();
      // seekAudio(time);

      setState(() {
        trackSecint = time;
        seekTime = position;
      });
      trackTime();
    }

    // ignore: unused_element
    void pauseMusic() {
      // pauseAudio();

      setState(() {
        paused = true;
        currentTrack = "PAUSED - Silent - DEMO Track";
      });
    }

    return Scaffold(
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          MobileNav(),
          Container(
            width: MediaQuery.of(context).size.width * 0.97,
            height: MediaQuery.of(context).size.height - 40,
            decoration: BoxDecoration(
              border: Border.all(color: Color(0xFF555569), width: 2.0),
              gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment(0.8, 0.0),
                colors: [
                  Color(0xFF212132),
                  Color(0XFF353454),
                  Color(0xFF474766),
                ],
                tileMode: TileMode.repeated,
              ),
            ),
            child: Padding(
              padding: const EdgeInsets.only(left: 4.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  SizedBox(width: MediaQuery.of(context).size.width * 0.98),
                  SizedBox(height: 5),
                  MobileTrackBar(currentTrack),
                  SizedBox(height: 10),
                  MobileInfoWidget(
                    minutes: trackMin,
                    seconds: trackSec,
                    playing: !paused,
                  ),
                  SizedBox(height: 15),
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      MiniControls(
                          units: "kbps", initialValue: 160, min: 98, max: 320),
                      MiniControls(
                        units: "dB",
                        initialValue: 50,
                        min: 0,
                        max: 100,
                        control: (double level) {
                          // setAudioVolume(level);
                        },
                      ),
                      MiniControls(
                          units: "kHz", initialValue: 44, min: 32, max: 98),
                      SizedBox(width: 10),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          ControlLabel(
                              text: "mono",
                              enabled: mono,
                              onPress: () {
                                setState(() {
                                  mono = true;
                                });
                              }),
                          SizedBox(height: 15),
                          MiniButton(light: Colors.yellow, text: "EQ"),
                        ],
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          ControlLabel(
                              text: "stereo",
                              enabled: !mono,
                              onPress: () => setState(() {
                                    mono = false;
                                  })),
                          SizedBox(height: 15),
                          MiniButton(light: Colors.red, text: "PL"),
                        ],
                      )
                    ],
                  ),
                  SizedBox(height: 40),
                  MobileSeekBar(
                    min: 0,
                    max: 185, // Time in seconds,
                    value: seekTime,
                    seek: (val) {
                      print("SEEKED" + val.toString());
                      seekMusic(val);
                    },
                  ),
                  SizedBox(height: 40),
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      RetroButton(
                          width: 60,
                          height: 40,
                          onPress: () {
                            seekMusic(0);
                          },
                          icon: Icons.fast_rewind),
                      // SizedBox(width: 10),
                      RetroButton(
                        onPress: () => playMusic(),
                        icon: Icons.play_arrow,
                        width: 60,
                        height: 40,
                      ),
                      // SizedBox(width: 10),
                      RetroButton(
                          width: 60,
                          height: 40,
                          onPress: () => pauseMusic(),
                          icon: Icons.pause),
                      // SizedBox(width: 10),
                      RetroButton(
                          width: 60,
                          height: 40,
                          onPress: () {
                            stopMusic();
                            this.initState();
                          },
                          icon: Icons.stop),
                      // SizedBox(width: 10),
                      RetroButton(
                        width: 60,
                        height: 40,
                        icon: Icons.fast_forward,
                        onPress: () {},
                      ),
                    ],
                  ),
                  SizedBox(height: 25),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    mainAxisSize: MainAxisSize.max,
                    children: [
                      Transform.scale(
                        scale: 1.25,
                        child: TextControlButton(
                            text: "Shuffle", light: Colors.red, width: 65),
                      ),
                      Transform.scale(
                        scale: 1.25,
                        child: TextControlButton(
                            icon: true,
                            ico: Icons.repeat,
                            light: Colors.yellow,
                            width: 65),
                      )
                    ],
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  Container(
                    width: 54,
                    height: 54,
                    decoration: BoxDecoration(
                        // color: Colors.white,
                        image: DecorationImage(
                      image: NetworkImage(
                        'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/logo2.png?raw=true',
                      ),
                      fit: BoxFit.cover,
                    )),
                  )
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// MOBILE SEEKBAR

class MobileSeekBar extends StatelessWidget {
  final Function seek;
  final double min;
  final double max;
  final double value;
  MobileSeekBar({this.seek, this.min, this.max, this.value});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
        Container(
          // decoration: BoxDecoration(color: Color(0xff1B1932)),
          child: MobileSlider(
            value: value,
            min: min,
            max: max,
            thumbSize: 28.0,
            sliderWidth: MediaQuery.of(context).size.width * 0.9,
            thumbColor: Colors.yellow,
            roundedRectangleThumbRadius: 0.0,
            topLeftShadow: false,
            bottomRightShadow: true,
            bottomRightShadowBlur: MaskFilter.blur(BlurStyle.outer, 3),
            bottomRightShadowColor: Colors.black,
            activeLineStroke: 2.0,
            activeLineColor: Color(0xff1B1932),
            inactiveLineColor: Color(0xff1B1932),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Center(
                  child: Text(
                '──',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18.0,
                  fontFamily: 'Pixer',
                  fontWeight: FontWeight.bold,
                ),
              )),
            ),
            onChanged: (double val) {
              seek(val);
            },
          ),
        ),
      ],
    );
  }
}

// MOBILE SLIDER
class MobileSlider extends StatefulWidget {
  MobileSlider({
    this.value,
    this.min,
    this.max,
    this.onChanged,
    this.child,
    this.sliderWidth,
    this.thumbSize,
    this.thumbColor = Colors.grey,
    this.roundedRectangleThumbRadius = 0.0,
    this.inactiveLineColor = Colors.blue,
    this.inactiveLineStroke,
    this.activeLineColor = Colors.blue,
    this.activeLineStroke,
    this.topLeftShadow = false,
    this.topLeftShadowColor = Colors.blueGrey,
    this.topLeftShadowBlur,
    this.bottomRightShadow = false,
    this.bottomRightShadowColor = Colors.blueGrey,
    this.bottomRightShadowBlur,
  })  : assert(value != null),
        assert(min != null),
        assert(max != null),
        assert(min <= max),
        assert(value >= min && value <= max);

  /// Value of the Slider Position
  /// (Value!=null)
  /// (value >= min && value <= max)

  final double value;

  /// minimum value for the Slider
  /// (min != null)
  /// (min <= max)
  final double min;

  /// maximum value for the Slider
  /// (max != null)
  final double max;

  /// Called when the user starts selecting a new value for the slider.
  final ValueChanged<double> onChanged;

  /// Provide a child Widget to the Slider Thumb
  final Widget child;

  /// Total Width of the Slider.
  /// Default width will be the Canvas Width with a difference of 40px
  final double sliderWidth;

  /// Size of the thumb
  /// Default value will be a 90px ratio of the original Canvas
  final double thumbSize;

  ///Colour of the thumb
  ///Default colour is grey Colour
  final Color thumbColor;

  /// Give this radius to convert the Rectangle into a Rounded Rectangle
  /// Increase in radius will make the  rectangle into a circle
  final double roundedRectangleThumbRadius;

  ///The color for the inactive portion of the slider track.
  ///Default colour is Blue Colour
  final Color inactiveLineColor;

  ///The stroke value for the inactive portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for inactiveLineStroke = activeLineStroke unless given different values for both
  final double inactiveLineStroke;

  ///The color for the active portion of the slider track.
  ///Default colour is Blue Colour
  final Color activeLineColor;

  ///The stroke value for the active portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for activeLineStroke = inactiveLineStroke unless given different values for both
  final double activeLineStroke;

  ///Give true value if a Shadow required on Top - Left of the thumb
  final bool topLeftShadow;

  ///Colour of shadow of Top - Left of the thumb
  ///Default is Blue - Grey
  final Color topLeftShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter topLeftShadowBlur;

  ///Give true value if a Shadow required on Bottom - Right of the thumb
  final bool bottomRightShadow;

  ///Colour of shadow of Bottom - Right of the thumb
  ///Default is Blue - Grey
  final Color bottomRightShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter bottomRightShadowBlur;

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

class _MobileSliderState extends State<MobileSlider> {
  double sliderXCoordinatePositionNow = 0.0;

  double _strokeOfInactiveLine() => (widget.inactiveLineStroke == null)
      ? (widget.activeLineStroke == null) ? 4.0 : widget.activeLineStroke
      : widget.inactiveLineStroke;

  double _strokeOfActiveLine() => (widget.activeLineStroke == null)
      ? (widget.inactiveLineStroke == null) ? 4.0 : widget.inactiveLineStroke
      : widget.activeLineStroke;

  MaskFilter _topLeftShadowBlur() => (widget.topLeftShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.topLeftShadowBlur;

  MaskFilter _bottomRightShadowBlur() => (widget.bottomRightShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.bottomRightShadowBlur;

  double _incrementValueForThumb() =>
      (widget.value == 0.0) ? widget.min : widget.value - widget.min;

  double _lineLengthForPixel() => _sliderWidth() - _sliderHeight();
  double _userValueForPixel() => widget.max - widget.min;
  double _pixelDivision() => _lineLengthForPixel() / _userValueForPixel();

  double _sliderChildPosition() => _incrementValueForThumb() * _pixelDivision();

  double _sliderWidth() {
    double userInputWidth = widget.sliderWidth;
    double screenWidth = window.physicalSize.width;
    double pixelRatio = window.devicePixelRatio;
    double sliderWidth = (userInputWidth == null)
        ? ((screenWidth / pixelRatio) - 40.0)
        : userInputWidth;
    return sliderWidth;
  }

  double _sliderHeight() {
    double userInputHeight = widget.thumbSize;
    double screenHeight = window.physicalSize.height;
    double pixelRatio = window.devicePixelRatio;
    double multiplicationFactor = (90 / 805.3333334);
    double sliderHeight = (userInputHeight == null)
        ? ((screenHeight / pixelRatio) * multiplicationFactor)
        : userInputHeight;
    return sliderHeight.roundToDouble();
    // return 25;
  }

  void _onDragUpdate(DragUpdateDetails dragUpdateDetails) {
    Offset localDragUpdate = dragUpdateDetails.localPosition;
    double xCoordinate;
    (localDragUpdate.dx < 0)
        ? xCoordinate = 0
        : (localDragUpdate.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragUpdate.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _onDragStart(DragStartDetails dragStartDetails) {
    Offset localDragStart = dragStartDetails.localPosition;
    double xCoordinate;
    (localDragStart.dx < 0)
        ? xCoordinate = 0
        : (localDragStart.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragStart.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _value() {
    double incrementValue = sliderXCoordinatePositionNow / _pixelDivision();
    double value = (incrementValue > _userValueForPixel())
        ? _userValueForPixel()
        : incrementValue;
    double userValue = value + widget.min;
    if (widget.onChanged != null) {
      widget.onChanged(userValue);
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onHorizontalDragUpdate: (DragUpdateDetails updateDetails) {
        _onDragUpdate(updateDetails);
        _value();
      },
      onHorizontalDragStart: (DragStartDetails startDetails) {
        _onDragStart(startDetails);
        _value();
      },
      child: Container(
        padding: EdgeInsets.all(0.0),
        child: Stack(
          children: <Widget>[
            Container(
              height: _sliderHeight(),
              width: _sliderWidth(),
              child: CustomPaint(
                painter: MobileSliderPaint(
                  sliderLength: _sliderWidth(),
                  thumbSize: _sliderHeight(),
                  thumbColor: widget.thumbColor,
                  value: _incrementValueForThumb(),
                  min: widget.min,
                  max: widget.max,
                  inactiveLineColor: widget.inactiveLineColor,
                  inactiveLineStroke: _strokeOfInactiveLine(),
                  activeLineColor: widget.activeLineColor,
                  activeLineStroke: _strokeOfActiveLine(),
                  currentTouchPosition: sliderXCoordinatePositionNow,
                  roundedThumbRadius: widget.roundedRectangleThumbRadius,
                  topLeftShadowColor: widget.topLeftShadowColor,
                  bottomRightShadowColor: widget.bottomRightShadowColor,
                  topLeftShadowBlurFactor: _topLeftShadowBlur(),
                  bottomRightShadowBlurFactor: _bottomRightShadowBlur(),
                  bottomRightShadow: widget.bottomRightShadow,
                  topLeftShadow: widget.topLeftShadow,
                ),
              ),
            ),
            Positioned(
              height: _sliderHeight(),
              width: _sliderHeight(),
              left: _sliderChildPosition(),
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: widget.child,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MobileSliderPaint extends CustomPainter {
  MobileSliderPaint({
    @required this.sliderLength,
    @required this.thumbSize,
    @required this.thumbColor,
    @required this.value,
    @required this.min,
    @required this.max,
    @required this.roundedThumbRadius,
    @required this.inactiveLineColor,
    @required this.inactiveLineStroke,
    @required this.currentTouchPosition,
    @required this.activeLineColor,
    @required this.activeLineStroke,
    @required this.topLeftShadowColor,
    @required this.bottomRightShadowColor,
    @required this.topLeftShadowBlurFactor,
    @required this.bottomRightShadowBlurFactor,
    @required this.topLeftShadow,
    @required this.bottomRightShadow,
  });
  final double sliderLength;
  final double thumbSize;
  final Color thumbColor;
  final double value;
  final double min;
  final double max;
  final double roundedThumbRadius;
  final Color inactiveLineColor;
  final double inactiveLineStroke;
  final double currentTouchPosition;
  final Color activeLineColor;
  final double activeLineStroke;
  final Color topLeftShadowColor;
  final Color bottomRightShadowColor;
  final MaskFilter bottomRightShadowBlurFactor;
  final MaskFilter topLeftShadowBlurFactor;
  final bool topLeftShadow;
  final bool bottomRightShadow;

  @override
  void paint(Canvas canvas, Size size) {
    double roundedRectangleTopLeftShadowShift = 13.0;
    double roundedRectangleBottomRightShadowShift = 1.5;
    double _increment() {
      double lineLengthForPixel = sliderLength - thumbSize;
      double userValueForPixel = max - min;
      double pixelDivision = lineLengthForPixel / userValueForPixel;
      return value * pixelDivision;
    }

    ///    Inactive Line Paint

    Path inactiveLinePath = Path();
    Paint inactiveLinePaint = Paint()
      ..color = inactiveLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 20;
    inactiveLinePath.moveTo(0.0, thumbSize / 2);
    inactiveLinePath.lineTo(sliderLength, thumbSize / 2);
    canvas.drawPath(inactiveLinePath, inactiveLinePaint);

    ///    Active Line Paint

    Path activeLinePath = Path();
    Paint activeLinePaint = Paint()
      ..color = activeLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 20;
    activeLinePath.moveTo(0.0, thumbSize / 2);
    activeLinePath.lineTo(currentTouchPosition, thumbSize / 2);
    canvas.drawPath(activeLinePath, activeLinePaint);

    ///    Rounded Rectangle Top Left Shadow Paint

    Path roundedRectangleTopLeftShadow = Path();
    Paint roundedRectangleTopLeftShadowPaint = Paint()
      ..color = topLeftShadowColor
      ..maskFilter = topLeftShadowBlurFactor;

    roundedRectangleTopLeftShadow.addRRect(RRect.fromLTRBR(
        0.0 - roundedRectangleTopLeftShadowShift + _increment(),
        0.0 - roundedRectangleTopLeftShadowShift,
        thumbSize - roundedRectangleTopLeftShadowShift + _increment(),
        thumbSize - roundedRectangleTopLeftShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (topLeftShadow == true)
      canvas.drawPath(
          roundedRectangleTopLeftShadow, roundedRectangleTopLeftShadowPaint);

    ///    Rounded Rectangle Bottom Right Shadow Paint

    Path roundedRectangleBottomRightShadow = Path();
    Paint roundedRectangleBottomRightShadowPaint = Paint()
      ..color = bottomRightShadowColor
      ..maskFilter = bottomRightShadowBlurFactor;
    roundedRectangleBottomRightShadow.addRRect(RRect.fromLTRBR(
        0.0 + roundedRectangleBottomRightShadowShift + _increment(),
        0.0 + roundedRectangleBottomRightShadowShift,
        thumbSize + roundedRectangleBottomRightShadowShift + _increment(),
        thumbSize + roundedRectangleBottomRightShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (bottomRightShadow == true)
      canvas.drawPath(roundedRectangleBottomRightShadow,
          roundedRectangleBottomRightShadowPaint);

    ///   Rounded Rectangle Thumb Paint

    Path roundedRectangle = Path();
    Paint roundedRectanglePaint = Paint()..color = thumbColor;

    roundedRectangle.addRRect(RRect.fromLTRBR(
        -5.0 + _increment(),
        0.0,
        thumbSize + 5 + _increment(),
        thumbSize,
        Radius.circular(roundedThumbRadius)));
    canvas.drawPath(roundedRectangle, roundedRectanglePaint);
  }

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

// MOBILE TRACK BAR

class MobileTrackBar extends StatelessWidget {
  final String trackName;

  MobileTrackBar(this.trackName);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width * 0.98,
      height: 32,
      padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Text(
        this.trackName,
        textAlign: TextAlign.right,
        style: TextStyle(
            fontFamily: 'Pixer', fontSize: 18, color: Color(0XFF04E406)),
      ),
    );
  }
}

class MobileInfoWidget extends StatelessWidget {
  final String minutes;
  final String seconds;
  final bool playing;

  MobileInfoWidget({this.minutes, this.seconds, this.playing});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width * 0.98,
      height: 250,
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.9,
                ),
                MusicTimer(
                  minutes: this.minutes,
                  seconds: this.seconds,
                ),
                Container(
                  width: MediaQuery.of(context).size.width * 0.90,
                  height: 140,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: playing
                          ? NetworkImage(
                              'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/music_bars.gif?raw=false')
                          : NetworkImage(
                              'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/musicbars.png?raw=false'),
                    ),
                  ),
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// MOBILE NAV

class MobileNav extends StatelessWidget {
  const MobileNav({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Container(
            width: MediaQuery.of(context).size.width * 0.33,
            color: Colors.yellow,
            height: 5,
          ),
          SizedBox(width: 10),
          Text(
            "WINAMP",
            style: TextStyle(
              color: Colors.white,
              fontFamily: 'Pixer',
              fontSize: 18,
            ),
          ),
          Container(
            width: MediaQuery.of(context).size.width * 0.33,
            color: Colors.yellow,
            height: 5,
          ),
        ],
      ),
    );
  }
}

// AWESOME SLIDER

class AwesomeSlider extends StatefulWidget {
  AwesomeSlider({
    this.value,
    this.min,
    this.max,
    this.onChanged,
    this.child,
    this.sliderWidth,
    this.thumbSize,
    this.thumbColor = Colors.grey,
    this.roundedRectangleThumbRadius = 0.0,
    this.inactiveLineColor = Colors.blue,
    this.inactiveLineStroke,
    this.activeLineColor = Colors.blue,
    this.activeLineStroke,
    this.topLeftShadow = false,
    this.topLeftShadowColor = Colors.blueGrey,
    this.topLeftShadowBlur,
    this.bottomRightShadow = false,
    this.bottomRightShadowColor = Colors.blueGrey,
    this.bottomRightShadowBlur,
  })  : assert(value != null),
        assert(min != null),
        assert(max != null),
        assert(min <= max),
        assert(value >= min && value <= max);

  /// Value of the Slider Position
  /// (Value!=null)
  /// (value >= min && value <= max)

  final double value;

  /// minimum value for the Slider
  /// (min != null)
  /// (min <= max)
  final double min;

  /// maximum value for the Slider
  /// (max != null)
  final double max;

  /// Called when the user starts selecting a new value for the slider.
  final ValueChanged<double> onChanged;

  /// Provide a child Widget to the Slider Thumb
  final Widget child;

  /// Total Width of the Slider.
  /// Default width will be the Canvas Width with a difference of 40px
  final double sliderWidth;

  /// Size of the thumb
  /// Default value will be a 90px ratio of the original Canvas
  final double thumbSize;

  ///Colour of the thumb
  ///Default colour is grey Colour
  final Color thumbColor;

  /// Give this radius to convert the Rectangle into a Rounded Rectangle
  /// Increase in radius will make the  rectangle into a circle
  final double roundedRectangleThumbRadius;

  ///The color for the inactive portion of the slider track.
  ///Default colour is Blue Colour
  final Color inactiveLineColor;

  ///The stroke value for the inactive portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for inactiveLineStroke = activeLineStroke unless given different values for both
  final double inactiveLineStroke;

  ///The color for the active portion of the slider track.
  ///Default colour is Blue Colour
  final Color activeLineColor;

  ///The stroke value for the active portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for activeLineStroke = inactiveLineStroke unless given different values for both
  final double activeLineStroke;

  ///Give true value if a Shadow required on Top - Left of the thumb
  final bool topLeftShadow;

  ///Colour of shadow of Top - Left of the thumb
  ///Default is Blue - Grey
  final Color topLeftShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter topLeftShadowBlur;

  ///Give true value if a Shadow required on Bottom - Right of the thumb
  final bool bottomRightShadow;

  ///Colour of shadow of Bottom - Right of the thumb
  ///Default is Blue - Grey
  final Color bottomRightShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter bottomRightShadowBlur;

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

class _AwesomeSliderState extends State<AwesomeSlider> {
  double sliderXCoordinatePositionNow = 0.0;

  double _strokeOfInactiveLine() => (widget.inactiveLineStroke == null)
      ? (widget.activeLineStroke == null) ? 4.0 : widget.activeLineStroke
      : widget.inactiveLineStroke;

  double _strokeOfActiveLine() => (widget.activeLineStroke == null)
      ? (widget.inactiveLineStroke == null) ? 4.0 : widget.inactiveLineStroke
      : widget.activeLineStroke;

  MaskFilter _topLeftShadowBlur() => (widget.topLeftShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.topLeftShadowBlur;

  MaskFilter _bottomRightShadowBlur() => (widget.bottomRightShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.bottomRightShadowBlur;

  double _incrementValueForThumb() =>
      (widget.value == 0.0) ? widget.min : widget.value - widget.min;

  double _lineLengthForPixel() => _sliderWidth() - _sliderHeight();
  double _userValueForPixel() => widget.max - widget.min;
  double _pixelDivision() => _lineLengthForPixel() / _userValueForPixel();

  double _sliderChildPosition() => _incrementValueForThumb() * _pixelDivision();

  double _sliderWidth() {
    double userInputWidth = widget.sliderWidth;
    double screenWidth = window.physicalSize.width;
    double pixelRatio = window.devicePixelRatio;
    double sliderWidth = (userInputWidth == null)
        ? ((screenWidth / pixelRatio) - 40.0)
        : userInputWidth;
    return sliderWidth;
  }

  double _sliderHeight() {
    double userInputHeight = widget.thumbSize;
    double screenHeight = window.physicalSize.height;
    double pixelRatio = window.devicePixelRatio;
    double multiplicationFactor = (90 / 805.3333334);
    double sliderHeight = (userInputHeight == null)
        ? ((screenHeight / pixelRatio) * multiplicationFactor)
        : userInputHeight;
    return sliderHeight.roundToDouble();
  }

  void _onDragUpdate(DragUpdateDetails dragUpdateDetails) {
    Offset localDragUpdate = dragUpdateDetails.localPosition;
    double xCoordinate;
    (localDragUpdate.dx < 0)
        ? xCoordinate = 0
        : (localDragUpdate.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragUpdate.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _onDragStart(DragStartDetails dragStartDetails) {
    Offset localDragStart = dragStartDetails.localPosition;
    double xCoordinate;
    (localDragStart.dx < 0)
        ? xCoordinate = 0
        : (localDragStart.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragStart.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _value() {
    double incrementValue = sliderXCoordinatePositionNow / _pixelDivision();
    double value = (incrementValue > _userValueForPixel())
        ? _userValueForPixel()
        : incrementValue;
    double userValue = value + widget.min;
    if (widget.onChanged != null) {
      widget.onChanged(userValue);
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onHorizontalDragUpdate: (DragUpdateDetails updateDetails) {
        _onDragUpdate(updateDetails);
        _value();
      },
      onHorizontalDragStart: (DragStartDetails startDetails) {
        _onDragStart(startDetails);
        _value();
      },
      child: Container(
        padding: EdgeInsets.all(0.0),
        child: Stack(
          children: <Widget>[
            Container(
              height: _sliderHeight(),
              width: _sliderWidth(),
              child: CustomPaint(
                painter: AwesomeSliderPaint(
                  sliderLength: _sliderWidth(),
                  thumbSize: _sliderHeight(),
                  thumbColor: widget.thumbColor,
                  value: _incrementValueForThumb(),
                  min: widget.min,
                  max: widget.max,
                  inactiveLineColor: widget.inactiveLineColor,
                  inactiveLineStroke: _strokeOfInactiveLine(),
                  activeLineColor: widget.activeLineColor,
                  activeLineStroke: _strokeOfActiveLine(),
                  currentTouchPosition: sliderXCoordinatePositionNow,
                  roundedThumbRadius: widget.roundedRectangleThumbRadius,
                  topLeftShadowColor: widget.topLeftShadowColor,
                  bottomRightShadowColor: widget.bottomRightShadowColor,
                  topLeftShadowBlurFactor: _topLeftShadowBlur(),
                  bottomRightShadowBlurFactor: _bottomRightShadowBlur(),
                  bottomRightShadow: widget.bottomRightShadow,
                  topLeftShadow: widget.topLeftShadow,
                ),
              ),
            ),
            Positioned(
              height: _sliderHeight(),
              width: _sliderHeight(),
              left: _sliderChildPosition(),
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: widget.child,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class AwesomeSliderPaint extends CustomPainter {
  AwesomeSliderPaint({
    @required this.sliderLength,
    @required this.thumbSize,
    @required this.thumbColor,
    @required this.value,
    @required this.min,
    @required this.max,
    @required this.roundedThumbRadius,
    @required this.inactiveLineColor,
    @required this.inactiveLineStroke,
    @required this.currentTouchPosition,
    @required this.activeLineColor,
    @required this.activeLineStroke,
    @required this.topLeftShadowColor,
    @required this.bottomRightShadowColor,
    @required this.topLeftShadowBlurFactor,
    @required this.bottomRightShadowBlurFactor,
    @required this.topLeftShadow,
    @required this.bottomRightShadow,
  });
  final double sliderLength;
  final double thumbSize;
  final Color thumbColor;
  final double value;
  final double min;
  final double max;
  final double roundedThumbRadius;
  final Color inactiveLineColor;
  final double inactiveLineStroke;
  final double currentTouchPosition;
  final Color activeLineColor;
  final double activeLineStroke;
  final Color topLeftShadowColor;
  final Color bottomRightShadowColor;
  final MaskFilter bottomRightShadowBlurFactor;
  final MaskFilter topLeftShadowBlurFactor;
  final bool topLeftShadow;
  final bool bottomRightShadow;

  @override
  void paint(Canvas canvas, Size size) {
    double roundedRectangleTopLeftShadowShift = 13.0;
    double roundedRectangleBottomRightShadowShift = 1.5;
    double _increment() {
      double lineLengthForPixel = sliderLength - thumbSize;
      double userValueForPixel = max - min;
      double pixelDivision = lineLengthForPixel / userValueForPixel;
      return value * pixelDivision;
    }

    ///    Inactive Line Paint

    Path inactiveLinePath = Path();
    Paint inactiveLinePaint = Paint()
      ..color = inactiveLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = inactiveLineStroke;
    inactiveLinePath.moveTo(0.0, thumbSize / 2);
    inactiveLinePath.lineTo(sliderLength, thumbSize / 2);
    canvas.drawPath(inactiveLinePath, inactiveLinePaint);

    ///    Active Line Paint

    Path activeLinePath = Path();
    Paint activeLinePaint = Paint()
      ..color = activeLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = activeLineStroke;
    activeLinePath.moveTo(0.0, thumbSize / 2);
    activeLinePath.lineTo(currentTouchPosition, thumbSize / 2);
    canvas.drawPath(activeLinePath, activeLinePaint);

    ///    Rounded Rectangle Top Left Shadow Paint

    Path roundedRectangleTopLeftShadow = Path();
    Paint roundedRectangleTopLeftShadowPaint = Paint()
      ..color = topLeftShadowColor
      ..maskFilter = topLeftShadowBlurFactor;

    roundedRectangleTopLeftShadow.addRRect(RRect.fromLTRBR(
        0.0 - roundedRectangleTopLeftShadowShift + _increment(),
        0.0 - roundedRectangleTopLeftShadowShift,
        thumbSize - roundedRectangleTopLeftShadowShift + _increment(),
        thumbSize - roundedRectangleTopLeftShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (topLeftShadow == true)
      canvas.drawPath(
          roundedRectangleTopLeftShadow, roundedRectangleTopLeftShadowPaint);

    ///    Rounded Rectangle Bottom Right Shadow Paint

    Path roundedRectangleBottomRightShadow = Path();
    Paint roundedRectangleBottomRightShadowPaint = Paint()
      ..color = bottomRightShadowColor
      ..maskFilter = bottomRightShadowBlurFactor;
    roundedRectangleBottomRightShadow.addRRect(RRect.fromLTRBR(
        0.0 + roundedRectangleBottomRightShadowShift + _increment(),
        0.0 + roundedRectangleBottomRightShadowShift,
        thumbSize + roundedRectangleBottomRightShadowShift + _increment(),
        thumbSize + roundedRectangleBottomRightShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (bottomRightShadow == true)
      canvas.drawPath(roundedRectangleBottomRightShadow,
          roundedRectangleBottomRightShadowPaint);

    ///   Rounded Rectangle Thumb Paint

    Path roundedRectangle = Path();
    Paint roundedRectanglePaint = Paint()..color = thumbColor;

    roundedRectangle.addRRect(RRect.fromLTRBR(
        0.0 + _increment(),
        0.0,
        thumbSize + _increment(),
        thumbSize,
        Radius.circular(roundedThumbRadius)));
    canvas.drawPath(roundedRectangle, roundedRectanglePaint);
  }

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

// CUSTOM SLIDER

class CustomSlider extends StatefulWidget {
  CustomSlider({
    this.value,
    this.min,
    this.max,
    this.onChanged,
    this.child,
    this.sliderWidth,
    this.thumbSize,
    this.thumbColor = Colors.grey,
    this.roundedRectangleThumbRadius = 0.0,
    this.inactiveLineColor = Colors.blue,
    this.inactiveLineStroke,
    this.activeLineColor = Colors.blue,
    this.activeLineStroke,
    this.topLeftShadow = false,
    this.topLeftShadowColor = Colors.blueGrey,
    this.topLeftShadowBlur,
    this.bottomRightShadow = false,
    this.bottomRightShadowColor = Colors.blueGrey,
    this.bottomRightShadowBlur,
  })  : assert(value != null),
        assert(min != null),
        assert(max != null),
        assert(min <= max),
        assert(value >= min && value <= max);

  /// Value of the Slider Position
  /// (Value!=null)
  /// (value >= min && value <= max)

  final double value;

  /// minimum value for the Slider
  /// (min != null)
  /// (min <= max)
  final double min;

  /// maximum value for the Slider
  /// (max != null)
  final double max;

  /// Called when the user starts selecting a new value for the slider.
  final ValueChanged<double> onChanged;

  /// Provide a child Widget to the Slider Thumb
  final Widget child;

  /// Total Width of the Slider.
  /// Default width will be the Canvas Width with a difference of 40px
  final double sliderWidth;

  /// Size of the thumb
  /// Default value will be a 90px ratio of the original Canvas
  final double thumbSize;

  ///Colour of the thumb
  ///Default colour is grey Colour
  final Color thumbColor;

  /// Give this radius to convert the Rectangle into a Rounded Rectangle
  /// Increase in radius will make the  rectangle into a circle
  final double roundedRectangleThumbRadius;

  ///The color for the inactive portion of the slider track.
  ///Default colour is Blue Colour
  final Color inactiveLineColor;

  ///The stroke value for the inactive portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for inactiveLineStroke = activeLineStroke unless given different values for both
  final double inactiveLineStroke;

  ///The color for the active portion of the slider track.
  ///Default colour is Blue Colour
  final Color activeLineColor;

  ///The stroke value for the active portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for activeLineStroke = inactiveLineStroke unless given different values for both
  final double activeLineStroke;

  ///Give true value if a Shadow required on Top - Left of the thumb
  final bool topLeftShadow;

  ///Colour of shadow of Top - Left of the thumb
  ///Default is Blue - Grey
  final Color topLeftShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter topLeftShadowBlur;

  ///Give true value if a Shadow required on Bottom - Right of the thumb
  final bool bottomRightShadow;

  ///Colour of shadow of Bottom - Right of the thumb
  ///Default is Blue - Grey
  final Color bottomRightShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter bottomRightShadowBlur;

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

class _CustomSliderState extends State<CustomSlider> {
  double sliderXCoordinatePositionNow = 0.0;

  double _strokeOfInactiveLine() => (widget.inactiveLineStroke == null)
      ? (widget.activeLineStroke == null) ? 4.0 : widget.activeLineStroke
      : widget.inactiveLineStroke;

  double _strokeOfActiveLine() => (widget.activeLineStroke == null)
      ? (widget.inactiveLineStroke == null) ? 4.0 : widget.inactiveLineStroke
      : widget.activeLineStroke;

  MaskFilter _topLeftShadowBlur() => (widget.topLeftShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.topLeftShadowBlur;

  MaskFilter _bottomRightShadowBlur() => (widget.bottomRightShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.bottomRightShadowBlur;

  double _incrementValueForThumb() =>
      (widget.value == 0.0) ? widget.min : widget.value - widget.min;

  double _lineLengthForPixel() => _sliderWidth() - _sliderHeight();
  double _userValueForPixel() => widget.max - widget.min;
  double _pixelDivision() => _lineLengthForPixel() / _userValueForPixel();

  double _sliderChildPosition() => _incrementValueForThumb() * _pixelDivision();

  double _sliderWidth() {
    double userInputWidth = widget.sliderWidth;
    double screenWidth = window.physicalSize.width;
    double pixelRatio = window.devicePixelRatio;
    double sliderWidth = (userInputWidth == null)
        ? ((screenWidth / pixelRatio) - 40.0)
        : userInputWidth;
    return sliderWidth;
  }

  double _sliderHeight() {
    double userInputHeight = widget.thumbSize;
    double screenHeight = window.physicalSize.height;
    double pixelRatio = window.devicePixelRatio;
    double multiplicationFactor = (90 / 805.3333334);
    double sliderHeight = (userInputHeight == null)
        ? ((screenHeight / pixelRatio) * multiplicationFactor)
        : userInputHeight;
    return sliderHeight.roundToDouble();
    // return 25;
  }

  void _onDragUpdate(DragUpdateDetails dragUpdateDetails) {
    Offset localDragUpdate = dragUpdateDetails.localPosition;
    double xCoordinate;
    (localDragUpdate.dx < 0)
        ? xCoordinate = 0
        : (localDragUpdate.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragUpdate.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _onDragStart(DragStartDetails dragStartDetails) {
    Offset localDragStart = dragStartDetails.localPosition;
    double xCoordinate;
    (localDragStart.dx < 0)
        ? xCoordinate = 0
        : (localDragStart.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragStart.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _value() {
    double incrementValue = sliderXCoordinatePositionNow / _pixelDivision();
    double value = (incrementValue > _userValueForPixel())
        ? _userValueForPixel()
        : incrementValue;
    double userValue = value + widget.min;
    if (widget.onChanged != null) {
      widget.onChanged(userValue);
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onHorizontalDragUpdate: (DragUpdateDetails updateDetails) {
        _onDragUpdate(updateDetails);
        _value();
      },
      onHorizontalDragStart: (DragStartDetails startDetails) {
        _onDragStart(startDetails);
        _value();
      },
      child: Container(
        padding: EdgeInsets.all(0.0),
        child: Stack(
          children: <Widget>[
            Container(
              height: _sliderHeight(),
              width: _sliderWidth(),
              child: CustomPaint(
                painter: CustomSliderPaint(
                  sliderLength: _sliderWidth(),
                  thumbSize: _sliderHeight(),
                  thumbColor: widget.thumbColor,
                  value: _incrementValueForThumb(),
                  min: widget.min,
                  max: widget.max,
                  inactiveLineColor: widget.inactiveLineColor,
                  inactiveLineStroke: _strokeOfInactiveLine(),
                  activeLineColor: widget.activeLineColor,
                  activeLineStroke: _strokeOfActiveLine(),
                  currentTouchPosition: sliderXCoordinatePositionNow,
                  roundedThumbRadius: widget.roundedRectangleThumbRadius,
                  topLeftShadowColor: widget.topLeftShadowColor,
                  bottomRightShadowColor: widget.bottomRightShadowColor,
                  topLeftShadowBlurFactor: _topLeftShadowBlur(),
                  bottomRightShadowBlurFactor: _bottomRightShadowBlur(),
                  bottomRightShadow: widget.bottomRightShadow,
                  topLeftShadow: widget.topLeftShadow,
                ),
              ),
            ),
            Positioned(
              height: _sliderHeight(),
              width: _sliderHeight(),
              left: _sliderChildPosition(),
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: widget.child,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class CustomSliderPaint extends CustomPainter {
  CustomSliderPaint({
    @required this.sliderLength,
    @required this.thumbSize,
    @required this.thumbColor,
    @required this.value,
    @required this.min,
    @required this.max,
    @required this.roundedThumbRadius,
    @required this.inactiveLineColor,
    @required this.inactiveLineStroke,
    @required this.currentTouchPosition,
    @required this.activeLineColor,
    @required this.activeLineStroke,
    @required this.topLeftShadowColor,
    @required this.bottomRightShadowColor,
    @required this.topLeftShadowBlurFactor,
    @required this.bottomRightShadowBlurFactor,
    @required this.topLeftShadow,
    @required this.bottomRightShadow,
  });
  final double sliderLength;
  final double thumbSize;
  final Color thumbColor;
  final double value;
  final double min;
  final double max;
  final double roundedThumbRadius;
  final Color inactiveLineColor;
  final double inactiveLineStroke;
  final double currentTouchPosition;
  final Color activeLineColor;
  final double activeLineStroke;
  final Color topLeftShadowColor;
  final Color bottomRightShadowColor;
  final MaskFilter bottomRightShadowBlurFactor;
  final MaskFilter topLeftShadowBlurFactor;
  final bool topLeftShadow;
  final bool bottomRightShadow;

  @override
  void paint(Canvas canvas, Size size) {
    double roundedRectangleTopLeftShadowShift = 13.0;
    double roundedRectangleBottomRightShadowShift = 1.5;
    double _increment() {
      double lineLengthForPixel = sliderLength - thumbSize;
      double userValueForPixel = max - min;
      double pixelDivision = lineLengthForPixel / userValueForPixel;
      return value * pixelDivision;
    }

    ///    Inactive Line Paint

    Path inactiveLinePath = Path();
    Paint inactiveLinePaint = Paint()
      ..color = inactiveLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 30;
    inactiveLinePath.moveTo(0.0, thumbSize / 2);
    inactiveLinePath.lineTo(sliderLength, thumbSize / 2);
    canvas.drawPath(inactiveLinePath, inactiveLinePaint);

    ///    Active Line Paint

    Path activeLinePath = Path();
    Paint activeLinePaint = Paint()
      ..color = activeLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 32;
    activeLinePath.moveTo(0.0, thumbSize / 2);
    activeLinePath.lineTo(currentTouchPosition, thumbSize / 2);
    canvas.drawPath(activeLinePath, activeLinePaint);

    ///    Rounded Rectangle Top Left Shadow Paint

    Path roundedRectangleTopLeftShadow = Path();
    Paint roundedRectangleTopLeftShadowPaint = Paint()
      ..color = topLeftShadowColor
      ..maskFilter = topLeftShadowBlurFactor;

    roundedRectangleTopLeftShadow.addRRect(RRect.fromLTRBR(
        0.0 - roundedRectangleTopLeftShadowShift + _increment(),
        0.0 - roundedRectangleTopLeftShadowShift,
        thumbSize - roundedRectangleTopLeftShadowShift + _increment(),
        thumbSize - roundedRectangleTopLeftShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (topLeftShadow == true)
      canvas.drawPath(
          roundedRectangleTopLeftShadow, roundedRectangleTopLeftShadowPaint);

    ///    Rounded Rectangle Bottom Right Shadow Paint

    Path roundedRectangleBottomRightShadow = Path();
    Paint roundedRectangleBottomRightShadowPaint = Paint()
      ..color = bottomRightShadowColor
      ..maskFilter = bottomRightShadowBlurFactor;
    roundedRectangleBottomRightShadow.addRRect(RRect.fromLTRBR(
        0.0 + roundedRectangleBottomRightShadowShift + _increment(),
        0.0 + roundedRectangleBottomRightShadowShift,
        thumbSize + roundedRectangleBottomRightShadowShift + _increment(),
        thumbSize + roundedRectangleBottomRightShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (bottomRightShadow == true)
      canvas.drawPath(roundedRectangleBottomRightShadow,
          roundedRectangleBottomRightShadowPaint);

    ///   Rounded Rectangle Thumb Paint

    Path roundedRectangle = Path();
    Paint roundedRectanglePaint = Paint()..color = thumbColor;

    roundedRectangle.addRRect(RRect.fromLTRBR(
        -5.0 + _increment(),
        0.0,
        thumbSize + 5 + _increment(),
        thumbSize,
        Radius.circular(roundedThumbRadius)));
    canvas.drawPath(roundedRectangle, roundedRectanglePaint);
  }

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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.