using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;

using FingersDance.Control.UserPanel;
using FingersDance.Control.Screen;
using FingersDance.Control.Close;
using FingersDance.ViewModels;
using FingersDance.Data;
using FingersDance.Factory;

namespace FingersDance
{
    /// <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class SurfaceWindow1 : SurfaceWindow
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// 
        #region Variables

        private UserControlUserPanel Panel1 = null;
        private UserControlUserPanel Panel2 = null;
        private UserControlUserPanel Panel3 = null;
        private UserControlUserPanel Panel4 = null;
        ActionGenerator _Factory = (new ActionFactory()).GetGenerator();
        private MainViewModel _mainviewmodel = new MainViewModel();
        #endregion


        #region Constructor
        public SurfaceWindow1()
        {
            InitializeComponent();
            //Permet d'initialiser l'inertie du Pivot une fois relaché.
            InitPivotInertia();
            //Permet d'initialiser les quand Grid à la position initiale du pivot
            InitGridPositions();
            // Add handlers for Application activation events
            AddActivationHandlers();
            // Add credit text
            CreditsText1.Text = CreditsText2.Text = CreditsText3.Text = CreditsText4.Text =
                "MICROSOFT :\nPierre-Louis Xech\n\nEFREI :\nSantiago Aria\nRiley Ikni\nJonathan Pamphile\nAmine Tarari\n\nSTRATE COLLEGE :\nAnnabelle Eugénia\nHuieun Kim\nBaptiste Lanne\nIoana Ocnarescu\nVanessa Reiser\nDominique Sciamma\n\nINSTITUT DE RECHERCHE ET D'INNOVATION\nThibaut Cavalié\nYves-Marie Haussonne\nVincent Puig";
        }
        #endregion

        #region Initialization

        private void InitPivotInertia()
        {
            try
            {
                ScatterViewItem item = (ScatterViewItem)scaterview.Items.GetItemAt(0);
                item.DecelerationRate = double.NaN;
            }
            catch (Exception ex) { }
        }

        private void InitGridPositions()
        {
            //Initialise les 4 Grids à la positions initiale du Pivot.   
            try
            {
                ScatterViewItem item = (ScatterViewItem)scaterview.Items.GetItemAt(0);
                Grid1.Width =item.Center.X;
                Grid1.Height = item.Center.Y;
                
                Grid2.Width = item.Center.X;
                Grid2.Height = 768 - item.Center.Y;

                Grid3.Width = 1024 - item.Center.X;
                Grid3.Height = 768 - item.Center.Y;

                Grid4.Width = 1024 - item.Center.X;
                Grid4.Height = item.Center.Y;
            }
            catch (Exception ex) { }
        }

        #endregion

        #region Application Default Functions
        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            // Remove handlers for Application activation events
            RemoveActivationHandlers();
        }

        /// <summary>
        /// Adds handlers for Application activation events.
        /// </summary>
        private void AddActivationHandlers()
        {
            // Subscribe to surface application activation events
            ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
        }

        /// <summary>
        /// Removes handlers for Application activation events.
        /// </summary>
        private void RemoveActivationHandlers()
        {
            // Unsubscribe from surface application activation events
            ApplicationLauncher.ApplicationActivated -= OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed -= OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated -= OnApplicationDeactivated;
        }

        /// <summary>
        /// This is called when application has been activated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationActivated(object sender, EventArgs e)
        {
            //TODO: enable audio, animations here

        }

        /// <summary>
        /// This is called when application is in preview mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationPreviewed(object sender, EventArgs e)
        {
            //TODO: Disable audio here if it is enabled

            //TODO: optionally enable animations here
        }

        /// <summary>
        ///  This is called when application has been deactivated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationDeactivated(object sender, EventArgs e)
        {
            //TODO: disable audio, animations here
        }

        /// <summary>
        ///  This is called when application has been loaded, we change the orientation
        ///  of the application
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainSurfaceWindow_Loaded(object sender, RoutedEventArgs e)
        {

            if (ApplicationLauncher.InitialOrientation == UserOrientation.Top)
            {
                // Rotate the main canvas by 180 degrees.
                this.MainGrid.LayoutTransform = new RotateTransform(180.0);
            }
            else
            {
                // Remove the rotate transform on the main canvas.
                this.MainGrid.LayoutTransform = null;
            }
            // Dismiss the loading screen.
            ApplicationLauncher.SignalApplicationLoadComplete();
        }
        #endregion


        

        #region Pivot Actions
        private void scaterview_ContactChanged(object sender, ContactEventArgs e)
        { }
        private void ScatterViewItemPivot_ContactChanged(object sender, ContactEventArgs e)
        {
            //Permet la MAJ des 4 Grids à la position du pivot
            try
            {
                Grid1.Width = e.GetPosition(mainSurfaceWindow).X;
                Grid1.Height = e.GetPosition(mainSurfaceWindow).Y;

                Grid3.Width = e.GetPosition(mainSurfaceWindow).X;
                Grid3.Height = 768 - e.GetPosition(mainSurfaceWindow).Y;

                Grid4.Width = 1024 - e.GetPosition(mainSurfaceWindow).X;
                Grid4.Height = 768 - e.GetPosition(mainSurfaceWindow).Y;

                Grid2.Width = 1024 - e.GetPosition(mainSurfaceWindow).X;
                Grid2.Height = e.GetPosition(mainSurfaceWindow).Y;

                //GRISAGE
                //Grid1
                if (Grid1.Width < (1024 / 4) || Grid2.Height < (768 / 4))
                {
                    try
                    {
                        if (Panel1 != null)
                            Panel1.PlayerPause();
                        Grid1.Children[1].Visibility = Visibility.Hidden;
                    }
                    catch (Exception) { }
                }
                else
                {
                    try
                    { 
                        Grid1.Children[1].Visibility = Visibility.Visible; 
                    }
                    catch (Exception) { }
                }
                //Grid2
                if (Grid2.Width < (1024 / 4) || Grid2.Height < (768 / 4))
                {
                    try
                    {
                        if (Panel2 != null)
                            Panel2.PlayerPause();
                        Grid2.Children[1].Visibility = Visibility.Hidden; 
                    }
                    catch (Exception) { }
                }
                else
                {
                    try
                    {
                        Grid2.Children[1].Visibility = Visibility.Visible; 
                    }
                    catch (Exception) { }
                }
                //Grid3
                if (Grid3.Width < (1024 / 4) || Grid3.Height < (768 / 4))
                {
                    try
                    {
                        if (Panel3 != null)
                            Panel3.PlayerPause();
                        Grid3.Children[1].Visibility = Visibility.Hidden;
                    }
                    catch (Exception) { }
                }
                else
                {
                    try
                    {
                        Grid3.Children[1].Visibility = Visibility.Visible; 
                    }
                    catch (Exception) { }
                }
                //Grid4
                if (Grid4.Width < (1024 / 4) || Grid4.Height < (768 / 4))
                {
                    try
                    {
                        if (Panel4 != null)
                            Panel4.PlayerPause();
                        Grid4.Children[1].Visibility = Visibility.Hidden;
                    }
                    catch (Exception) { }
                }
                else
                {
                    try
                    { 
                        Grid4.Children[1].Visibility = Visibility.Visible;
                    }
                    catch (Exception) { }
                }
            }
            catch (Exception) { }
        }

        private void UserControlPivot_EH_SurfaceButtonPlayer_ContactDown(object sender, EventArgs e)
        {
            //  Traitement du contact down sur le pivot (Création d'un screen ou suppression d'un panel
            switch ((int)sender)
            {
                case 1:
                    if (Panel1 == null && Grid1.Children.Count == 3)
                    {
                        //1-Creation du control Screen
                        UserControlScreen Screen = new UserControlScreen(1, _mainviewmodel);
                        Screen.Name = "Screen1";
                        Screen.contexteGrid = Grid1.Name.ToString();
                        //2-Rajout du screen dans la grid correspondante
                        Grid1.Children.Add(Screen);

                        Screen.UC_Screen_NewCutting += new System.EventHandler(this.SessionInput_EH_SurfaceButtonSubmit_ContactDown); 
                    }
                    else //Affichage du message de confirmation
                    {
                        if (Panel1 != null && Grid1.Children.Count == 4)
                        {
                            UserControlClose UCclose = new UserControlClose(1, "Êtes-vous sûr de vouloir quitter ?");
                            UCclose.Name = "CloseAlert1";
                            Grid1.Children.Add(UCclose);
                            UCclose.ConfirmYesOrNo += new EventHandler<ConfirmEventArgs>(CloseAlert_EH_SurfaceButton_ContactDown);
                        }
                    }
                    break;
                case 2:
                    if (Panel2 == null && Grid2.Children.Count == 3)
                    {
                        //1-Creation du control Screen
                        UserControlScreen Screen = new UserControlScreen(2, _mainviewmodel);
                        Screen.Name = "Screen2";
                        Screen.contexteGrid = Grid2.Name.ToString();
                        //2-Rajout du screen dans la grid correspondante
                        Grid2.Children.Add(Screen);

                        Screen.UC_Screen_NewCutting += new System.EventHandler(this.SessionInput_EH_SurfaceButtonSubmit_ContactDown);
                    }
                    else //Affichage du message de confirmation
                    {
                        if (Panel2 != null && Grid2.Children.Count == 4)
                        {
                            UserControlClose UCclose = new UserControlClose(2, "Êtes-vous sûr de vouloir quitter ?");
                            UCclose.Name = "CloseAlert2";
                            Grid2.Children.Add(UCclose);
                            UCclose.ConfirmYesOrNo += new EventHandler<ConfirmEventArgs>(CloseAlert_EH_SurfaceButton_ContactDown);
                        }
                    }
                    break;
                case 3:
                    if (Panel3 == null && Grid3.Children.Count == 3)
                    {
                        //1-Creation du control Screen
                        UserControlScreen Screen = new UserControlScreen(3, _mainviewmodel);
                        Screen.Name = "Screen3";
                        Screen.contexteGrid = Grid3.Name.ToString();
                        //2-Rajout du screen dans la grid correspondante
                        Grid3.Children.Add(Screen);

                        Screen.UC_Screen_NewCutting += new System.EventHandler(this.SessionInput_EH_SurfaceButtonSubmit_ContactDown);
                    }
                    else //Affichage du message de confirmation
                    {
                        if (Panel3 != null && Grid3.Children.Count == 4)
                        {
                            UserControlClose UCclose = new UserControlClose(3, "Êtes-vous sûr de vouloir quitter ?");
                            UCclose.Name = "CloseAlert3";
                            Grid3.Children.Add(UCclose);
                            UCclose.ConfirmYesOrNo += new EventHandler<ConfirmEventArgs>(CloseAlert_EH_SurfaceButton_ContactDown);
                        }
                    }
                    break;
                case 4:
                    if (Panel4 == null && Grid4.Children.Count == 3)
                    {
                        //1-Creation du control Screen
                        UserControlScreen Screen = new UserControlScreen(4, _mainviewmodel);
                        Screen.Name = "Screen4";
                        Screen.contexteGrid = Grid4.Name.ToString();
                        //2-Rajout du screen dans la grid correspondante
                        Grid4.Children.Add(Screen);

                        Screen.UC_Screen_NewCutting += new System.EventHandler(this.SessionInput_EH_SurfaceButtonSubmit_ContactDown);
                    }
                    else //Affichage du message de confirmation
                    {
                        if (Panel4 != null && Grid4.Children.Count == 4)
                        {
                            UserControlClose UCclose = new UserControlClose(4, "Êtes-vous sûr de vouloir quitter ?");
                            UCclose.Name = "CloseAlert4";
                            Grid4.Children.Add(UCclose);
                            UCclose.ConfirmYesOrNo += new EventHandler<ConfirmEventArgs>(CloseAlert_EH_SurfaceButton_ContactDown);
                        }
                    }
                    break;
            }

        }

        #endregion


        //Button Submit du control SessionInput
        private void SessionInput_EH_SurfaceButtonSubmit_ContactDown(object sender, EventArgs e)
        {
            try
            {
                // We get UserControlScreen's instance and content
                Grid root = (Grid)(((UserControlScreen)sender).Parent);
                // We remove the UserControlScreen's instance
                root.Children.Remove(((UserControlScreen)sender));

                if ((((UserControlScreen)sender).Cutting != null && ((UserControlScreen)sender).AnnotationOrSearchMode == "Annotation") || (((UserControlScreen)sender).AnnotationOrSearchMode == "Search"))
                {
                    //2-Creation du User Panel
                    Cutting newCutting = ((UserControlScreen)sender).Cutting;

                    // We test if each Panel does not already own the sent cuttingVM
                    if (((UserControlScreen)sender).Cutting != null && ((UserControlScreen)sender).AnnotationOrSearchMode == "Annotation")
                    {
                        if (Panel1 != null)
                            if (Panel1.Cutting != null)
                                if (Panel1.Cutting.Title==newCutting.Title)
                                    return;
                        if (Panel2 != null)
                            if (Panel2.Cutting != null)
                                if (Panel2.Cutting.Title == newCutting.Title)
                                    return;
                        if (Panel3 != null)
                            if (Panel3.Cutting != null)
                                if (Panel3.Cutting.Title == newCutting.Title)
                                    return;
                        if (Panel4 != null)
                            if (Panel4.Cutting != null)
                                if (Panel4.Cutting.Title == newCutting.Title)
                                    return;

                        // We add the new cutting to the _mainviewmodel's datas IF THE CUTTING IS NEW (if not it means that it is from a loaded project)
                        if (!_mainviewmodel.Project.CuttingsDict.ContainsKey(newCutting.Title))
                        {
                            _mainviewmodel.Project.Cuttings.Add(newCutting);
                            _mainviewmodel.Project.CuttingsDict.Add(newCutting.Title, newCutting);
                        }
                    }

                    // And now we build the new UserPanel
                    Random c = new Random();
                    uint color = (uint)c.Next(12) + 1; // for the number to be >0
                    switch (((UserControlScreen)sender).id)
                    {
                        case 1:
                            UserControlPivot.ApplyColor(1, color);
                            Panel1 = new UserControlUserPanel(1, (new ColorFactory()).Colors[color], newCutting, _mainviewmodel.Project.VideoPath, ((UserControlScreen)sender).AnnotationOrSearchMode, ((UserControlScreen)sender).SearchedProject);
                            Panel1.Name = "UserPanel1";
                            Panel1.OnSuccessAnnotation += new EventHandler(Panel_OnSuccessAnnotation);
                            Panel1.OnTagVisualisation += new EventHandler(Panel_OnTagVisualisation);
                            Panel1.idcolor = color;
                            //3-Rajout sur la Grid Root
                            root.Children.Add(Panel1);
                            break;
                        case 2:
                            UserControlPivot.ApplyColor(2, color);
                            Panel2 = new UserControlUserPanel(2, (new ColorFactory()).Colors[color], newCutting, _mainviewmodel.Project.VideoPath, ((UserControlScreen)sender).AnnotationOrSearchMode, ((UserControlScreen)sender).SearchedProject);
                            Panel2.Name = "UserPanel2";
                            Panel2.OnSuccessAnnotation += new EventHandler(Panel_OnSuccessAnnotation);
                            Panel2.OnTagVisualisation += new EventHandler(Panel_OnTagVisualisation);
                            Panel2.idcolor = color;
                            //3-Rajout sur la Grid Root
                            root.Children.Add(Panel2);
                            break;
                        case 3:
                            UserControlPivot.ApplyColor(3, color);
                            Panel3 = new UserControlUserPanel(3, (new ColorFactory()).Colors[color], newCutting, _mainviewmodel.Project.VideoPath, ((UserControlScreen)sender).AnnotationOrSearchMode, ((UserControlScreen)sender).SearchedProject);
                            Panel3.Name = "UserPanel3";
                            Panel3.OnSuccessAnnotation += new EventHandler(Panel_OnSuccessAnnotation);
                            Panel3.OnTagVisualisation += new EventHandler(Panel_OnTagVisualisation);
                            Panel3.idcolor = color;
                            //3-Rajout sur la Grid Root
                            root.Children.Add(Panel3);
                            break;
                        case 4:
                            UserControlPivot.ApplyColor(4, color);
                            Panel4 = new UserControlUserPanel(4, (new ColorFactory()).Colors[color], newCutting, _mainviewmodel.Project.VideoPath, ((UserControlScreen)sender).AnnotationOrSearchMode, ((UserControlScreen)sender).SearchedProject);
                            Panel4.Name = "UserPanel4";
                            Panel4.OnSuccessAnnotation += new EventHandler(Panel_OnSuccessAnnotation);
                            Panel4.OnTagVisualisation += new EventHandler(Panel_OnTagVisualisation);
                            Panel4.idcolor = color;
                            //3-Rajout sur la Grid Root
                            root.Children.Add(Panel4);
                            break;
                    }
                }
            }
            catch (Exception ex) { }
        }

        //Actions du boutton Alert selon l'action close OK ou NON
        private void CloseAlert_EH_SurfaceButton_ContactDown(object sender, ConfirmEventArgs e)
        {
            Grid root = (Grid)(((UserControlClose)sender).Parent);
            if(e.Confirmed==true)
            {
                switch(e.PanelNumber)
                {
                    case 1:
                        UserControlPivot.ApplyColor(1, 0);
                        root.Children.Remove(Panel1);
                        Panel1 = null;
                        break;
                    case 2:
                        UserControlPivot.ApplyColor(2, 0);
                        root.Children.Remove(Panel2);
                        Panel2 = null;
                        break;
                    case 3:
                        UserControlPivot.ApplyColor(3, 0);
                        root.Children.Remove(Panel3);
                        Panel3 = null;
                        break;
                    case 4:
                        UserControlPivot.ApplyColor(4, 0);
                        root.Children.Remove(Panel4);
                        Panel4 = null;
                        break;
                }
            }
            root.Children.Remove(((UserControlClose)sender));
            if (Panel1 == null && Panel2 == null && Panel3 == null && Panel4 == null)
                _mainviewmodel.CloseProject();
        }


        //On success annotation we save the update datas
        private void Panel_OnSuccessAnnotation(object sender, EventArgs e)
        {
            // We save datas
            saveDatas();
        }

        //
        // Enable to save datas in a xml file with LDT format
        //
        private void saveDatas()
        {
            // We build the xml to be saved, with the ldt format
            XDocument d = new XDocument(
                new XElement("iri",
                    new XElement("project",
                        new XAttribute("id", "1"),
                        new XAttribute("user", "IRI-Strate-EFREI"),
                        new XAttribute("title", _mainviewmodel.Project.Name),
                        new XAttribute("abstract", _mainviewmodel.Project.Description)
                    ),
                    new XElement("medias",
                        new XElement("media",
                            new XAttribute("id","for_oneflat"),
                            new XAttribute("src","srcIri"),
                            new XAttribute("video",""),
                            new XAttribute("extra",""),
                            new XAttribute("pict","")
                        )
                    ),
                    new XElement("annotations",
                        new XElement("content",
                            new XAttribute("id", "for_oneflat"),
                            new XAttribute("title", "Déc. personnels"),
                            new XAttribute("author", "perso"),
                            new XAttribute("abstract", "Ensemble de découpages définis par un utilisateur")
                        )
                    ),
                    new XElement("displays"),
                    new XElement("edits")
                )
            );
            // We add each cutting
            XElement annotContent = (XElement)(d.Root.Elements().ToList()[2]).FirstNode;
            foreach (Cutting cut in _mainviewmodel.Project.Cuttings)
            {
                XElement cutNode = new XElement("decoupage", new XAttribute("id", cut.Id), new XAttribute("author", "perso"),
                                                new XElement("title",cut.Title),
                                                new XElement("abstract",""));
                XElement cutElmts = new XElement("elements");
                cutNode.Add(cutElmts);
                foreach (Annotation annot in cut.AnnotList)
                {
                    cutElmts.Add(new XElement("element", new XAttribute("id", annot.Id),
                                                         new XAttribute("begin", annot.TcBegin),
                                                         new XAttribute("dur", annot.Dur),
                                                         new XAttribute("author", cut.Title),
                                                         new XAttribute("date", DateTime.Now.Day.ToString() + "/" + DateTime.Now.Month.ToString() + "/" + DateTime.Now.Year.ToString()),
                                                         new XAttribute("color", "0x" + annot.Color.ToString().Substring(3)), // Color.ToString() return #AARRGGBB and we keep only 0xRRGGBB
                                                         new XAttribute("src", ""),
                                                         new XElement("title", annot.GestureType),
                                                         new XElement("abstract"),
                                                         new XElement("audio"),
                                                         new XElement("tags"),
                                                         new XElement("gestureType", annot.GestureType)));
                }
                annotContent.Add(cutNode);
            }

            d.Declaration = new XDeclaration("1.0", "utf-8", "true");
            //Console.WriteLine(d);
            d.Save(_mainviewmodel.Project.Name + ".ldt");

        }


        //On Tag Visualisation Mute all the other Players
        private void Panel_OnTagVisualisation(object sender, EventArgs e)
        {
            UserControlUserPanel PanelMaster = (UserControlUserPanel)sender;
            if (Panel1 != null)
            {
               if (!PanelMaster.Name.Equals(Panel1.Name))
                   Panel1.PlayerMute(true);
            }
            if (Panel2 != null)
            {
                if (!PanelMaster.Name.Equals(Panel2.Name))
                    Panel2.PlayerMute(true);
            }
            if (Panel3 != null)
            {
                if (!PanelMaster.Name.Equals(Panel3.Name))
                    Panel3.PlayerMute(true);
            }
            if (Panel4 != null)
            {
                if (!PanelMaster.Name.Equals(Panel4.Name))
                    Panel4.PlayerMute(true);
                
            }
        }

        private void CreditsButton_ContactDown(object sender, EventArgs e)
        {
            Console.WriteLine("CreditsButton_ContactDown");
            if(sender==CreditsButton1)
            {
                CreditsScroll1.Visibility = (CreditsScroll1.Visibility == Visibility.Hidden) ? Visibility.Visible : Visibility.Hidden;
            }
            else if (sender == CreditsButton2)
            {
                CreditsScroll2.Visibility = (CreditsScroll2.Visibility == Visibility.Hidden) ? Visibility.Visible : Visibility.Hidden;
            }
            else if (sender == CreditsButton3)
            {
                CreditsScroll3.Visibility = (CreditsScroll3.Visibility == Visibility.Hidden) ? Visibility.Visible : Visibility.Hidden;
            }
            else if (sender == CreditsButton4)
            {
                CreditsScroll4.Visibility = (CreditsScroll4.Visibility == Visibility.Hidden) ? Visibility.Visible : Visibility.Hidden;
            }
        }
    }
}