using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;

using FingersDance.Control.TimeLine;
using FingersDance.Data;
using FingersDance.ViewModels;
using FingersDance.Factory;
using GestureControl;

namespace FingersDance.Control.SyncSource
{
	public partial class UserControlSyncSource
	{
        #region Variables   
        public event EventHandler OnSuccessAnnotation;

        private String AnnotationOrSearchMode;
        private Project searchedProject;
        #endregion

		public UserControlSyncSource()
		{
			this.InitializeComponent();

			// Insert code required on object creation below this point.
		}

        public void Load(string path, Cutting cut, String AnnotOrSearchMode, Project searchedProj)
        {
            this.UserControlPlayer.initPlayer(path);
            AnnotationOrSearchMode = AnnotOrSearchMode;
            searchedProject = searchedProj;
            //Initialisation du Timer
            UCTimeLine.initTimer(cut);
            UserControlPlayer.playerPlay();
            userControlTimeLine.OnSuccessAnnotation += new EventHandler(userControlTimeLine_OnSuccessAnnotation);
            userControlTimeLine.AnnotationAdded += new EventHandler(userControlTimeLine_AnnotationAdded);
            userControlTimeLine.AnnotationRemoved += new EventHandler(userControlTimeLine_AnnotationRemoved);
            UserControlPlayer.PlayerStopOrPause += new EventHandler(UserControlPlayer_PlayerStopOrPause);
            UserControlPlayer.NewGestureRegognized += new EventHandler(UserControlPlayer_NewGestureRegognized);
            UCTimeLine.NewGestureRecognized += new EventHandler<NewGestureRecognizedEventArg>(UCTimeLine_NewGestureRecognized);
        }

        void userControlTimeLine_AnnotationRemoved(object sender, EventArgs e)
        {
            try
            {
                DataDictionary Data = (new DataFactory()).Data;
                Data.RemoveAnnotation((Annotation)sender);
            }
            catch { }
        }

        //  Ajout Annotation
        void userControlTimeLine_AnnotationAdded(object sender, EventArgs e)
        {
            try
            {
                DataDictionary Data = (new DataFactory()).Data;
                Data.AddAnnotation((Annotation)sender);
            }
            catch { }
        }

        #region player
        private void UserControlPlayer_PlayerOpened(object sender, EventArgs e)
        {
            //Initialisation du slider
            UCTimeLine.initslider(UserControlPlayer.TotalMilliseconds);
            //Demarrage du Timer
            UCTimeLine.timerStart();

        }

        public void UserControlPlayer_PlayerStopOrPause(object sender, EventArgs e)
        {
            try
            {
                userControlTimeLine.thumbRotation((bool)sender);
            }catch(Exception ){}
        }

        public void setUserPlayerVolume(double val)
        {
            try
            {
                UserControlPlayer.setSound(val);
            }
            catch (Exception) { }
        }
        public void setUserPlayerMute(bool b)
        {
            try
            {
                UserControlPlayer.setMute(b);
            }
            catch (Exception) { }
        }

        #endregion

        #region TimeLine


        private void UserControlTimeLine_DragStarted(object sender, EventArgs e)
        {
            UserControlPlayer.playerPause();
        }


        private void UserControlTimeLine_DragCompleted(object sender, EventArgs e)
        {
        }
        private void userControlTimeLine_OnSuccessAnnotation(object sender, EventArgs e)
        {
            OnSuccessAnnotation(this, new EventArgs());
        }

        #endregion


        #region SynSource pour chaque X milliseconds
        private void UserControlTimeLine_TimerTick(object sender, EventArgs e)
        {
            if (!UCTimeLine.IsDragging)
            {
                
                    UCTimeLine.Slider.Value = UserControlPlayer.Player.Position.TotalMilliseconds;
            
            }
            int SliderValue = (int)UCTimeLine.Slider.Value;
            if (UCTimeLine.FinishedDragging)
            {
                TimeSpan ts = new TimeSpan(0, 0, 0, 0, SliderValue);

                UserControlPlayer.Player.Position = ts;
                UserControlPlayer.playerPlay();

                UCTimeLine.IsDragging = false;
                UCTimeLine.FinishedDragging = false;
            }
            UserControlPlayer.Time = (float)SliderValue / 1000;
            DataDictionary Data = (new DataFactory()).Data;
            UserControlPlayer.ApplyColor(Data.GetColors((int)((float)SliderValue / 1000)));
        }
        #endregion

        public UserControlTimeLine userControlTimeLine
        {
            get { return this.UCTimeLine; }
        }

        public void PlayerPause()
        {
            UserControlPlayer.playerPause();
        }

        public void SyncSourceClose()
        {
            //TimeLine and Player To Null
            UCTimeLine.TimerTick -= UserControlTimeLine_TimerTick;
            UCTimeLine = null;
            UserControlPlayer.playerStop();
            UserControlPlayer = null;
        }

        public void UserControlPlayer_NewGestureRegognized(object sender, EventArgs e)
        {
            try
            {
                GestureEventArg grea = (GestureEventArg)e;
                //Console.WriteLine("Timeline NewGestureRegognized " + grea.Gesture.Name + ", " + grea.Gesture.Start + ", " + grea.Gesture.End);
                if (AnnotationOrSearchMode == "Annotation")
                {
                    // If the stroke has been drawed very fast, end and start can be the same, so we add a little length.
                    float dur = (float)(grea.End - grea.Start);
                    if (dur == 0) dur = (float)0.5;
                    // We build the list of string
                    List<String> gestList = new List<String>();
                    foreach (Gesture elt in grea.Gestures)
                        gestList.Add(elt.Name);
                    UCTimeLine.addAnnotation((float)grea.Start, dur, gestList);
                }
                else
                {
                    // We are in search mode. So we have to get all the searchedProject's annotation which have the wanted gesture
                    List<Annotation> searchedAnnot = new List<Annotation>();
                    foreach(Cutting cut in searchedProject.Cuttings)
                    {
                        foreach (Annotation annot in cut.AnnotList)
                        {
                            foreach(Gesture gest in grea.Gestures)
                                foreach(String annotGest in annot.GestureType)
                                    if (annotGest == gest.Name)
                                    {
                                        // One of the gesture is enough for the annotation to be added
                                        searchedAnnot.Add(annot);
                                        break;
                                    }
                        }
                    }
                    // The list was built. If the number of found annotations is >0, we send the list to the timeline
                    UCTimeLine.updateAnnotationList(searchedAnnot);
                }
            }
            catch { }
        }

        public void searchAnnotations(String gestureName)
        {
            // We are in search mode. So we have to get all the searchedProject's annotation which have the wanted gesture
            List<Annotation> searchedAnnot = new List<Annotation>();
            foreach (Cutting cut in searchedProject.Cuttings)
            {
                foreach (Annotation annot in cut.AnnotList)
                {
                    foreach (String annotGest in annot.GestureType)
                        if (annotGest == gestureName)
                        {
                            // One of the gesture is enough for the annotation to be added
                            searchedAnnot.Add(annot);
                        }
                }
            }
            // The list was built. If the number of found annotations is >0, we send the list to the timeline
            UCTimeLine.updateAnnotationList(searchedAnnot);
        }

        void UCTimeLine_NewGestureRecognized(object sender, NewGestureRecognizedEventArg e)
        {
            searchAnnotations(e.GestureName);
        }
    }
}