using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using CdgLib;
using Vlc.DotNet.Core;

namespace KaraokePlayer
{
    public partial class KaraokeVideoPlayer : UserControl
    {

        private bool hideOverlay = true;
        private GraphicsFile _cdgFile;
        private KaraokeVideoOverlay _overlayForm;
        private DateTime _startTime;
        private readonly System.Timers.Timer _lyricTimer = new System.Timers.Timer();
        public delegate void SongEndedEventHandler(object sender, EventArgs e);
        // An event that clients can use to be notified whenever the
        // elements of the list change.
        public event SongEndedEventHandler songEndedHandler;

        public KaraokeVideoPlayer()
        {
            InitializeComponent();
        }
        public void setup(bool isCDG, bool hideOverlay)
        {
            this.hideOverlay = hideOverlay;
            this.isCDG = isCDG;
            if (isCDG && !hideOverlay)
            {
                this.vlcPlayer.VlcMediaplayerOptions = new string[] {
                    "--effect-list=scope",
                    "--no-video",
                    "--verbose=2"
                };
            }
            else {
                this.vlcPlayer.VlcMediaplayerOptions = new string[] {
                    "--projectm-preset-path=lib\\presets",
                    "--effect-list=scope",
                    "--verbose=2"
                };
            }

            if (!hideOverlay)
            {
                _lyricTimer.Interval = 33;
                _lyricTimer.Elapsed += LyricTimerOnElapsed;
            }
        }

        private void LyricTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            if (isCDG && !hideOverlay)
            {
                var picture = _cdgFile.RenderAtTime((long)(DateTime.Now - _startTime).TotalMilliseconds);
                BeginInvoke(new MethodInvoker(() => { _overlayForm.Graphic.Image = picture; }));
            }
        }

        public async void Play(Uri file)
        {
            vlcPlayer.SetMedia(file);
            if (isCDG && !hideOverlay)
            {
                _cdgFile = await GraphicsFile.LoadAsync(Path.ChangeExtension(file.LocalPath, "cdg"));
            }
            vlcPlayer.Play();
        }

        public void Stop()
        {
            vlcPlayer.Stop();
        }

        private void vlcPlayer_Playing(object sender, VlcMediaPlayerPlayingEventArgs e)
        {
            _startTime = DateTime.Now;
            _lyricTimer.Start();
        }

        private void vlcPlayer_TimeChanged(object sender, VlcMediaPlayerTimeChangedEventArgs e)
        {
            _startTime = DateTime.Now.AddMilliseconds(-e.NewTime);
        }

        private void KaraokeVideoPlayer_ParentChanged(object sender, EventArgs e)
        {

        }

        private void vlcPlayer_VlcLibDirectoryNeeded(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
        {
            e.VlcLibDirectory = new DirectoryInfo(@"lib\vlc\");
        }

        private void KaraokeVideoPlayer_Load(object sender, EventArgs e)
        {
            if (this.FindForm() != null)
            {
                _overlayForm = new KaraokeVideoOverlay(this);
            }
        }

        private void vlcPlayer_EndReached(object sender, VlcMediaPlayerEndReachedEventArgs e)
        {
            if(this.songEndedHandler != null)
            {
                songEndedHandler(sender, e);
            }
        }
    }
}