/*
* This file is part of the TraKERS\Middleware package.
*
* (c) IRI <http://www.iri.centrepompidou.fr/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

/*
 * Projet : TraKERS
 * Module : MIDDLEWARE
 * Sous-Module : Debug
 * Classe : DebugWindow
 * 
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
 * 
 * Fonctionnalités : Reçoit des notifications des sous-modules Tracking, Communication et Exception.
 * Intéragit avec la fenêtre XAML de debug de façon à afficher un rendu visuel.
 */

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Drawing;
using Microsoft.Kinect;
using System.Resources;
using System.Reflection;
using System.Timers;
using System.Configuration;
using System.IO;
using System.Collections.Specialized;

namespace Trakers.Debug
{
    public partial class DebugWindow : Window
    {
        //Gestionnaire de ressources.
        private ResourceManager rm;

        //Paramètres du serveur TUIO.
        private OrderedDictionary config;

        //Images
        private String imgLocation;

        //Timer.
        private System.Timers.Timer _timer;
        //Membre permettant d'atteindre la classe KinectMain du sous-module Tracking.
        //private KinectMain kinectMain;
        //Tableau contenant une image en couleurs.
        private byte[] colorPixelData;
        //Indique si la kinect est allumée/éteinte.
        private bool on;
        //Indique si la fenêtre de debug est actuellement en cours de fermeture.
        private bool closing;
        //Indique si l'image doit être raffraichie.
        private Boolean refreshImage;

        /*
        * Constructeur : Affiche la fenêtre de debug en lui passant en paramètre une instanciation de la
        * classe KinectMain.
        * Au départ, la kinect est éteinte.
        */
        public DebugWindow()//KinectMain main)
        {
            InitializeComponent();

            imgLocation = "Imgs";

            config = new OrderedDictionary();

            //On fait appel au gestionnaire de ressources.
            rm = new ResourceManager("Trakers.Debug.Properties.Resources", Assembly.GetExecutingAssembly());
            //On tente de charger les paramètres du fichier params.ini.
            //Si on n'y arrive pas, on affiche une erreur et on charge les paramètres par défaut.
            if (!loadParameters())
            {
                ExceptionLbl.Content = rm.GetString("loadParametersFail");
                config.Clear();
                //Distances de détection des mains par défaut pour la recherche (ici de 1m à 2m de la Kinect).
                config.Add("minDistHands", 1.0f);
                config.Add("maxDistHands", 1.5f);
                config.Add("minDist", 1.0f);
                config.Add("maxDist", 4.0f);
                config.Add("zeroPoint", 1.7f);
                config.Add("tuioConnexionHost", "127.0.0.1");
                config.Add("tuioConnexionPort", 80);
                config.Add("wsConnexionHost", "127.0.0.1");
                config.Add("wsConnexionPort", 81);
                config.Add("tuioTimerElapsing", 1000);
                config.Add("wsTimerElapsing", 1000);
                config.Add("imagesToShow", 20);
                config.Add("takenPoints", 10);
                config.Add("directionChangeTresholdXY", 10);
                config.Add("directionChangeTresholdZ", 0.01f);
                //Chemins des readme et doc.
                config.Add("readmeMiddleware", "..\\readme - Middleware.txt");
                config.Add("readmeFrontProcessing", "..\\readme - Front Processing.txt");
                config.Add("docFrontProcessing", "..\\tutorial front processing.html");
                config.Add("readmeFrontJS", "..\\readme - Front Web.txt");
                config.Add("docFrontJS", "..\\tutorial front js et wamp.html");
                //Chemins des exemples processing.
                config.Add("exPFMPS", "..\\Front Processing\\src\\Fluid_manipulation\\Fluid_manipulation.pde");
                config.Add("exPFMExe", "..\\Front Processing\\src\\Fluid_manipulation\\application.windows\\Fluid_manipulation.exe");
                config.Add("exPSMPS", "..\\Front Processing\\src\\Smoke_manipulation\\Smoke_manipulation.pde");
                config.Add("exPSMExe", "..\\Front Processing\\src\\Smoke_manipulation\\application.windows\\Smoke_manipulation.exe");
                config.Add("exPTPS", "..\\Front Processing\\src\\Trakers\\Trakers.pde");
                config.Add("exPTExe", "..\\Front Processing\\src\\Trakers\\application.windows\\Trakers.exe");
                config.Add("exPTGPS", "..\\Front Processing\\src\\Trakers_gestures\\Trakers_gestures.pde");
                config.Add("exPTGExe", "..\\Front Processing\\src\\Trakers_gestures\\application.windows\\Trakers_gestures.exe");
                config.Add("exPIEHand1DPS", "..\\Front Processing\\src\\Interaction_examples\\Hands_1D\\Hands_1D.pde");
                config.Add("exPIEHand1DExe", "..\\Front Processing\\src\\Interaction_examples\\Hands_1D\\application.windows\\Hands_1D.exe");
                config.Add("exPIEHand2DPS", "..\\Front Processing\\src\\Interaction_examples\\Hands_2D\\Hands_2D.pde");
                config.Add("exPIEHand2DExe", "..\\Front Processing\\src\\Interaction_examples\\Hands_2D\\application.windows\\Hands_2D.exe");
                config.Add("exPIEHandPressPS", "..\\Front Processing\\src\\Interaction_examples\\Hand_press\\Hand_press.pde");
                config.Add("exPIEHandPressExe", "..\\Front Processing\\src\\Interaction_examples\\Hand_press\\application.windows\\Hand_press.exe");
                config.Add("exPIEHandSignalPS", "..\\Front Processing\\src\\Interaction_examples\\Hand_signal\\Hand_signal.pde");
                config.Add("exPIEHandSignalExe", "..\\Front Processing\\src\\Interaction_examples\\Hand_signal\\application.windows\\Hand_signal.exe");
                //Chemins des exemples web.
                config.Add("exWPointersPS", "C:\\wamp\\www\\Front JS\\pointers\\");
                config.Add("exWPointersExe", "http://localhost/Front%20JS/pointers/");
                config.Add("exWGesturesPS", "C:\\wamp\\www\\Front JS\\pointers\\");
                config.Add("exWGesturesExe", "http://localhost/Front%20JS/gestures/");
            }

            //On donne les noms des éléments du menu.
            FileMenu.Header = rm.GetString("menuFile");
            ReadmeMiddlewareMenu.Header = rm.GetString("menuReadmeMiddleware");
            ReadmeFrontProcessingMenu.Header = rm.GetString("menuReadmeFrontProcessing");
            DocumentationFrontProcessingMenu.Header = rm.GetString("menuDocFrontP");
            ReadmeFrontJSMenu.Header = rm.GetString("menuReadmeFrontJS");
            DocumentationFrontJSMenu.Header = rm.GetString("menuDocFrontJS");
            QuitMenu.Header = rm.GetString("menuQuit");
            ConfigMenu.Header = rm.GetString("menuConfig");
            ParamMenu.Header = rm.GetString("menuParam");
            ParamMenuReboot.Header = rm.GetString("menuParamReboot");
            ExamplesMenu.Header = rm.GetString("menuEx");
            ProcessingMenu.Header = rm.GetString("menuExP");
            ProcessingMenuFM.Header = rm.GetString("menuExPFluid");
            ProcessingMenuFMPS.Header = rm.GetString("menuExSource");
            ProcessingMenuFMExe.Header = rm.GetString("menuExExe");
            ProcessingMenuSM.Header = rm.GetString("menuExPSmoke");
            ProcessingMenuSMPS.Header = rm.GetString("menuExSource");
            ProcessingMenuSMExe.Header = rm.GetString("menuExExe");
            ProcessingMenuIE.Header = rm.GetString("menuExPIE");
            ProcessingMenuIEHand1D.Header = rm.GetString("menuExPIEHand1D");
            ProcessingMenuIEHand1DPS.Header = rm.GetString("menuExSource");
            ProcessingMenuIEHand1DExe.Header = rm.GetString("menuExExe");
            ProcessingMenuIEHand2D.Header = rm.GetString("menuExPIEHand2D");
            ProcessingMenuIEHand2DPS.Header = rm.GetString("menuExSource");
            ProcessingMenuIEHand2DExe.Header = rm.GetString("menuExExe");
            ProcessingMenuIEHandPress.Header = rm.GetString("menuExPIEHandPress");
            ProcessingMenuIEHandPressPS.Header = rm.GetString("menuExSource");
            ProcessingMenuIEHandPressExe.Header = rm.GetString("menuExExe");
            ProcessingMenuIEHandSignal.Header = rm.GetString("menuExPIEHandSignal");
            ProcessingMenuIEHandSignalPS.Header = rm.GetString("menuExSource");
            ProcessingMenuIEHandSignalExe.Header = rm.GetString("menuExExe");
            ProcessingMenuT.Header = rm.GetString("menuExPT");
            ProcessingMenuTPS.Header = rm.GetString("menuExSource");
            ProcessingMenuTExe.Header = rm.GetString("menuExExe");
            ProcessingMenuTG.Header = rm.GetString("menuExPTG");
            ProcessingMenuTGPS.Header = rm.GetString("menuExSource");
            ProcessingMenuTGExe.Header = rm.GetString("menuExExe");
            WebMenu.Header = rm.GetString("menuExW");
            WebMenuPointers.Header = rm.GetString("menuExWPointers");
            WebMenuPointersPS.Header = rm.GetString("menuExSource");
            WebMenuPointersExe.Header = rm.GetString("menuExExe");
            WebMenuGestures.Header = rm.GetString("menuExWGestures");
            WebMenuGesturesPS.Header = rm.GetString("menuExSource");
            WebMenuGesturesExe.Header = rm.GetString("menuExExe");

            //kinectMain = main;
            on = true;
            closing = false;
            refreshImage = true;
            try
            {
                //On instancie les timers à N ms.
                _timer = new System.Timers.Timer((int)config["tuioTimerElapsing"]);
                //Dès que le timer est expiré, on appelle _timer_Elapsed.
                _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
            }
            catch (Exception){}
        }

        /*
         * Méthode d'effacement du label d'exceptions.
         */
        public void NoException()
        {
            ExceptionLbl.Content = "";
        }

        /*
         * Méthode d'affichage des exceptions dans le label d'exceptions.
         */
        public void ShowException(String reference)
        {
            ExceptionLbl.Content = rm.GetString(reference);
        }

        /*
         * Méthode de fermeture de l'interface.
         */
        public void ShutDownInterface()
        {
            DebugImage.Source = null;
            ExceptionLbl.Content = "";
        }

        /*
         * Méthode appelée à l'expiration du timer ws pour les gestures et modes.
         */
        public void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //On débloque le raffraichissement de l'image.
            refreshImage = true;
            //On arrête le timer.
            _timer.Stop();
        }

        /*
        * Getter pour le membre indiquant la fermeture de la fenêtre de debug.
        */
        public bool isClosing()
        {
            return closing;
        }

        /*
         * Est appelé lors de la fermeture du Middleware par le menu.
         */
        private void QuitMenu_Click(object sender, RoutedEventArgs e)
        {
            closing = true;
            Application.Current.Shutdown();
        }

        /*
        * Est appelée à la fermeture de la fenêtre.
        */
        public void Window_Closed(object sender, EventArgs e)
        {
            closing = true;
        }

        /*
        * Bouton ON/OFF.
        */
        private void Switch_Click(object sender, RoutedEventArgs e)
        {
            //S'il valait faux, il vaut vrai maintenant et inversement.
            on = !on;
            //Si la kinect est allumée.
            if (on)
            {
                //Il affiche OFF (pour éteindre la kinect).
                Switch.Content = "OFF";
                //On vide le label des exceptions.
                ExceptionLbl.Content = "";
            }
            else
            {
                //Il affiche ON (pour allumer la kinect).
                Switch.Content = "ON";
                //On remet à zéro tous les éléments du retour visuel.
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                DistanceLbl.Content = "Distance :";
                LeftHand.Background = System.Windows.Media.Brushes.DarkGray;
                LeftHand.Content = "";
                RightHand.Background = System.Windows.Media.Brushes.DarkGray;
                RightHand.Content = "";
                DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1);
            }
        }

        /*
        *  Récupère le flux video et met à jour le rendu visuel de debug.
        */
        public void RefreshVideo(AllFramesReadyEventArgs e)
        {
            if (refreshImage)
            {
                bool receivedData = false;
                ColorImageFrame colorImageFrameData;
                using (colorImageFrameData = e.OpenColorImageFrame())
                {
                    //Si on ne reçoit pas de trames de la kinect.
                    if (colorImageFrameData == null)
                    {
                        //L'image est supprimée.
                        DebugImage.Source = null;
                    }
                    //Si le tableau stockant l'image en cours est nul.
                    if (colorPixelData == null)
                        //On alloue un nouveau tableau.
                        colorPixelData = new byte[colorImageFrameData.PixelDataLength];
                    else
                    {
                        try
                        {
                            //Sinon on met à jour le tableau en copiant le contenu de la trame dans le tableau.
                            colorImageFrameData.CopyPixelDataTo(colorPixelData);
                            receivedData = true;
                        }
                        catch (Exception) { }
                    }
                }
                //Si on a des données dans le tableau et que la kinect est allumée.
                if (receivedData && on)
                {
                    //On met à jour l'image de la caméra.
                    DebugImage.Source = BitmapSource.Create(colorImageFrameData.Width, colorImageFrameData.Height, 96, 96, PixelFormats.Bgr32, null, colorPixelData, colorImageFrameData.Width * colorImageFrameData.BytesPerPixel);
                    DebugImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                    DebugImage.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    DebugImage.Stretch = Stretch.Fill;
                    //On annule l'image associée aux gestures.
                    Gestures.Source = null;
                }
            }
        }

        /*
        * Affiche la distance de l'utilisateur dans le rendu visuel.
        * Sous forme de nombre en m et de rectangles changeant de couleur en fonction de la distance.
        */
        public void showDistance(float proximity)
        {
            DistanceLbl.Content = "Proximity : " + proximity + "%";

            if (proximity == 0)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
                R6.Fill = System.Windows.Media.Brushes.DarkGray;
                R7.Fill = System.Windows.Media.Brushes.DarkGray;
                R8.Fill = System.Windows.Media.Brushes.DarkGray;
                R9.Fill = System.Windows.Media.Brushes.DarkGray;
                R10.Fill = System.Windows.Media.Brushes.DarkGray;
            }
            else if (proximity > 0 && proximity < 10)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
                R6.Fill = System.Windows.Media.Brushes.DarkGray;
                R7.Fill = System.Windows.Media.Brushes.DarkGray;
                R8.Fill = System.Windows.Media.Brushes.DarkGray;
                R9.Fill = System.Windows.Media.Brushes.DarkGray;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 10 && proximity < 20)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
                R6.Fill = System.Windows.Media.Brushes.DarkGray;
                R7.Fill = System.Windows.Media.Brushes.DarkGray;
                R8.Fill = System.Windows.Media.Brushes.DarkGray;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 20 && proximity < 30)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
                R6.Fill = System.Windows.Media.Brushes.DarkGray;
                R7.Fill = System.Windows.Media.Brushes.DarkGray;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 30 && proximity < 40)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
                R6.Fill = System.Windows.Media.Brushes.DarkGray;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 40 && proximity < 50)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 50 && proximity < 60)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                R5.Fill = System.Windows.Media.Brushes.Orange;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 60 && proximity < 70)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.Yellow;
                R5.Fill = System.Windows.Media.Brushes.Orange;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 70 && proximity < 80)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.Yellow;
                R4.Fill = System.Windows.Media.Brushes.Yellow;
                R5.Fill = System.Windows.Media.Brushes.Orange;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 80 && proximity < 90)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.Yellow;
                R3.Fill = System.Windows.Media.Brushes.Yellow;
                R4.Fill = System.Windows.Media.Brushes.Yellow;
                R5.Fill = System.Windows.Media.Brushes.Orange;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity > 90 && proximity < 100)
            {
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
                R1.Fill = System.Windows.Media.Brushes.Yellow;
                R2.Fill = System.Windows.Media.Brushes.Yellow;
                R3.Fill = System.Windows.Media.Brushes.Yellow;
                R4.Fill = System.Windows.Media.Brushes.Yellow;
                R5.Fill = System.Windows.Media.Brushes.Orange;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
            else if (proximity == 100)
            {
                R0.Fill = System.Windows.Media.Brushes.Green;
                R1.Fill = System.Windows.Media.Brushes.Yellow;
                R2.Fill = System.Windows.Media.Brushes.Yellow;
                R3.Fill = System.Windows.Media.Brushes.Yellow;
                R4.Fill = System.Windows.Media.Brushes.Yellow;
                R5.Fill = System.Windows.Media.Brushes.Orange;
                R6.Fill = System.Windows.Media.Brushes.Orange;
                R7.Fill = System.Windows.Media.Brushes.Orange;
                R8.Fill = System.Windows.Media.Brushes.Red;
                R9.Fill = System.Windows.Media.Brushes.Red;
                R10.Fill = System.Windows.Media.Brushes.Red;
            }
        }

        /*
        * Affiche la détection de la main droite via un label.
        */
        public void showRightHandRect(bool show)
        {
            if (show)
                RightHand.Background = System.Windows.Media.Brushes.Blue;
            else
                RightHand.Background = System.Windows.Media.Brushes.DarkGray;
        }

        /*
        * Affiche la détection de la main gauche via un label.
        */
        public void showLeftHandRect(bool show)
        {
            if (show)
                LeftHand.Background = System.Windows.Media.Brushes.Blue;
            else
                LeftHand.Background = System.Windows.Media.Brushes.DarkGray;
        }

        /*
        * Dessine les noeuds du squelette dans le rendu visuel.
        */
        public void drawJoints(JointCollection joints, Skeleton first)
        {
            if (refreshImage)
            {
                //On enlève tout élément du Canvas à part l'image, de manière à mettre à jour la position du squelette. 
                DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1);

                //Pour chaque noeud.
                foreach (Joint joint in first.Joints)
                {
                    //On crée une ellipse de taille 20 et de largeur 20.
                    Ellipse node = new Ellipse();
                    node.Height = 20;
                    node.Width = 20;

                    //S'il s'agit d'un noeud de tête, on le colorie en rouge, sinon en bleu.
                    if (joint.JointType == JointType.Head)
                        node.Fill = System.Windows.Media.Brushes.Red;
                    else if (joint.JointType == JointType.ShoulderCenter)
                        node.Fill = System.Windows.Media.Brushes.Green;
                    else if (joint.JointType == JointType.HipCenter)
                        node.Fill = System.Windows.Media.Brushes.Green;
                    else if (joint.JointType == JointType.HandRight)
                        node.Fill = System.Windows.Media.Brushes.Red;
                    else
                        node.Fill = System.Windows.Media.Brushes.Blue;

                    //On met à la bonne échelle les coordonnées des positions des noeuds.
                    Joint scaledJoint = Coding4Fun.Kinect.Wpf.SkeletalExtensions.ScaleTo(joint, 600, 400, 0.75f, 0.75f);

                    //On positionne le noeud dans le Canvas, et on l'ajoute.
                    Canvas.SetLeft(node, scaledJoint.Position.X);
                    Canvas.SetTop(node, scaledJoint.Position.Y);
                    DebugCanvas.Children.Add(node);
                }
            }
        }

        /*
        * Dessine un os, en ayant en paramètres deux noeuds.
        */
        public void drawBone(Joint j1, Joint j2)
        {
            //On crée une nouvelle ligne verte d'épaisseur 8 entre les deux noeuds et on l'ajoute au Canvas.
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Green;
            line.X1 = j1.Position.X;
            line.X2 = j2.Position.X;
            line.Y1 = j1.Position.Y;
            line.Y2 = j2.Position.Y;
            line.StrokeThickness = 8;
            DebugCanvas.Children.Add(line);
        }

        /*
        * Dessine le squelette (ensemble des os), en ayant en paramètres tous les noeuds.
        */
        public void showSkeleton(Joint hipCenter, Joint spine, Joint shoulderCenter, Joint head, Joint shoulderLeft, Joint elbowLeft, Joint wristLeft, Joint handLeft, Joint shoulderRight, Joint elbowRight, Joint wristRight, Joint handRight, Joint hipLeft, Joint kneeLeft, Joint ankleLeft, Joint footLeft, Joint hipRight, Joint kneeRight, Joint ankleRight, Joint footRight)
        {
            if (refreshImage)
            {
                //On met les noeuds deux par deux en fonction de leur position dans le squelette.
                drawBone(head, shoulderCenter);
                drawBone(shoulderCenter, shoulderLeft);
                drawBone(shoulderLeft, elbowLeft);
                drawBone(elbowLeft, wristLeft);
                drawBone(wristLeft, handLeft);
                drawBone(shoulderCenter, shoulderRight);
                drawBone(shoulderRight, elbowRight);
                drawBone(elbowRight, wristRight);
                drawBone(wristRight, handRight);
                drawBone(shoulderCenter, spine);
                drawBone(spine, hipCenter);
                drawBone(hipCenter, hipLeft);
                drawBone(hipLeft, kneeLeft);
                drawBone(kneeLeft, ankleLeft);
                drawBone(ankleLeft, footLeft);
                drawBone(hipCenter, hipRight);
                drawBone(hipRight, kneeRight);
                drawBone(kneeRight, ankleRight);
                drawBone(ankleRight, footRight);
            }
        }

        /*
        * Cache le squelette et le reste de l'interface à part l'image.
        */
        public void hideSkeleton()
        {
            //On vide le canvas mais en gardant l'image.
            if(DebugCanvas.Children.Count > 1)
                DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1);
            //On colore en gris tous les indicateurs.
            R0.Fill = System.Windows.Media.Brushes.DarkGray;
            R1.Fill = System.Windows.Media.Brushes.DarkGray;
            R2.Fill = System.Windows.Media.Brushes.DarkGray;
            R3.Fill = System.Windows.Media.Brushes.DarkGray;
            R4.Fill = System.Windows.Media.Brushes.DarkGray;
            R5.Fill = System.Windows.Media.Brushes.DarkGray;
            R6.Fill = System.Windows.Media.Brushes.DarkGray;
            R7.Fill = System.Windows.Media.Brushes.DarkGray;
            R8.Fill = System.Windows.Media.Brushes.DarkGray;
            R9.Fill = System.Windows.Media.Brushes.DarkGray;
            R10.Fill = System.Windows.Media.Brushes.DarkGray;
        }

        /*
        * Affiche la position de la main gauche dans le rendu visuel.
        */
        public void showLeftHandCoord(String coord)
        {
            LeftHand.Content = coord;
        }

        /*
        * Affiche la position de la main gauche dans le rendu visuel.
        */
        public void showRightHandCoord(String coord)
        {
            RightHand.Content = coord;
        }

        /*
         * Méthode associée à l'événement : Quitter via le menu.
         */
        public void Quit_Click(object sender, RoutedEventArgs e)
        {
            closing = true;
            //On éteint la Kinect (pour éviter qu'elle reste allumée même lorsque le programme est éteint).
 
            Application.Current.Shutdown();
        }

        /*
         * Permet d'initialiser la Kinect dès que la fenêtre est lancée.
         */
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //kinectMain.KinectInitialization();
        }

        /*
         * Permet d'obtenir l'image associée à l'emplacement des images si celle-ci existe.
         */
        public Bitmap getImage(String location)
        {
            try
            {
                return new Bitmap(location);
            }
            catch (Exception)
            {
                return (Bitmap)rm.GetObject("_404");
            }
        }

        /*
         * Méthode d'affichage des gestures.
         */
        public void showGesture(String gesture)
        {
            if (refreshImage)
            {
                refreshImage = false;
                _timer.Start();
                Bitmap bitmap = null;
                //S'il s'agit de telle ou telle gesture, on prend l'image correspondante dans les ressources,
                //on la convertit et on l'affiche.

                switch (gesture)
                {
                    case "SWIPE-LEFT": bitmap = getImage(imgLocation + "\\swipe_left.png");
                        break;
                    case "SWIPE-RIGHT": bitmap = getImage(imgLocation + "\\swipe_right.png");
                        break;
                    case "PUSH-RIGHT": bitmap = getImage(imgLocation + "\\push_right.png");
                        break;
                    case "PUSH-LEFT": bitmap = getImage(imgLocation + "\\push_left.png");
                        break;
                    case "PUSH-BOTH": bitmap = getImage(imgLocation + "\\push_both.png");
                        break;
                    case "PULL-RIGHT": bitmap = getImage(imgLocation + "\\pull_right.png");
                        break;
                    case "PULL-LEFT": bitmap = getImage(imgLocation + "\\pull_left.png");
                        break;
                    case "PULL-BOTH": bitmap = getImage(imgLocation + "\\pull_both.png");
                        break;
                    case "WAVE": bitmap = getImage(imgLocation + "\\hello.png");
                        break;
                    case "BEND": bitmap = getImage(imgLocation + "\\bend.png");
                        break;
                    case "KNEE-UP": bitmap = getImage(imgLocation + "\\knee_up.png");
                        break;
                    case "JUMP": bitmap = getImage(imgLocation + "\\jump.png");
                        break;
                    case "FALL": bitmap = getImage(imgLocation + "\\fall.png");
                        break;
                }
                Gestures.Source = CreateBitmapSourceFromBitmap(bitmap);
            }

            DebugImage.Source = null;
            hideSkeleton();
        }

        /*
         * Méthode d'indication de raffraichissement de l'image ("on la raffraichit ou pas ?").
         */
        public void setRefreshImage(bool refresh)
        {
            refreshImage = refresh;
        }

        /*
         * Méthode de conversion de Bitmap (des ressources) en BitmapSource (du debug).
         */
        public static BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
        {
            if (bitmap == null)
                return null;

            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                bitmap.GetHbitmap(),
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());
        }

        /*
         * Méthode de chargement des paramètres via le fichier de configuration.
         */
        public bool loadParameters()
        {
            try
            {
                //On lit le fichier de config.
                String[] lines = System.IO.File.ReadAllLines("config.txt");

                //On repère les paramètres supposés être des int ou float de manière à les parser.
                String[] ints = { "tuioConnexionPort", "wsConnexionPort", "takenPoints", "tuioTimerElapsing", "wsTimerElapsing", "directionChangeTresholdXY", "imagesToShow" };
                String[] floats = { "minDistHands", "minDist", "maxDistHands", "maxDist", "zeroPoint", "directionChangeTresholdZ" };

                //Indique si on a affecté le paramètre actuel.
                bool goToNextParam = false;

                //Pour chaque ligne du fichier de config.
                for (int i = 0 ; i < lines.Length ; i++)
                {
                    //On récupère la clé et la valeur.
                    String key = lines[i].Split(':')[0];
                    int keyLength = key.Length;
                    String value = lines[i].Substring((keyLength + 1), (lines[i].Length - keyLength - 1));
                    //String value = lines[i].Substring(keyLength, lines[i].Length - keyLength - 1);

                    Console.WriteLine("PARAMS ======= " + key + " " + value);

                    //Si c'est un int on le parse.
                    for (int j = 0 ; j < ints.Length ; j++)
                    {
                        if (ints[j] == key)
                        {
                            config.Add(key, int.Parse(value));
                            goToNextParam = true;
                        }
                    }

                    //Si il n'était pas un int.
                    if (!goToNextParam)
                    {
                        //Si c'est un float on le parse.
                        for (int j = 0; j < floats.Length; j++)
                        {
                            if (floats[j] == key)
                            {
                                config.Add(key, float.Parse(value));
                                goToNextParam = true;
                            }
                        }

                        //Si c'était en fait un string.
                        if (!goToNextParam)
                        {
                            config.Add(key, value);
                        }
                    }
                    goToNextParam = false;
                }
            }
            //S'il s'est passé un problème durant la lecture du fichier de config.
            catch (Exception e)
            {
                //On génère un fichier qui va afficher l'erreur.
                StreamWriter SW;
                try
                {
                    SW = File.CreateText("ErrorFile.txt");
                    SW.WriteLine(e.Message);
                    SW.Close();
                }
                catch { }

                return false;
            }

            //Si l'extraction s'est bien passé mais que les paramètres sont incohérents.
            if ((float)config["maxDistHands"] <= 0f || (float)config["minDistHands"] <= 0f || (float)config["maxDistHands"] > (float)config["maxDist"] || (float)config["minDistHands"] > (float)config["maxDist"] ||
                (float)config["minDistHands"] >= (float)config["maxDistHands"] || (float)config["zeroPoint"] < (float)config["maxDistHands"] || (float)config["minDistHands"] > (float)config["minDist"] ||
                (float)config["zeroPoint"] >= (float)config["maxDist"] || (int)config["tuioConnexionPort"] < 0 || (int)config["wsConnexionPort"] < 0 || (int)config["tuioTimerElapsing"] < 0 || (int)config["wsTimerElapsing"] < 0 || (int)config["imagesToShow"] < 1 ||
                (int)config["takenPoints"] <= 0 || (int)config["directionChangeTresholdXY"] < 0 || (float)config["directionChangeTresholdZ"] < 0)
            {
                ExceptionLbl.Content = rm.GetString("loadParametersIncorrect");

                StreamWriter SW;
                try
                {
                    //On indique les incohérences trouvées dans le fichier.
                    SW = File.CreateText("ErrorFile.txt");
                    if ((float)config["maxDistHands"] <= 0f) { SW.WriteLine("searchMaxDistance <= 0"); }
                    if ((float)config["minDistHands"] <= 0f) { SW.WriteLine("minDistance <= 0"); }
                    if ((float)config["maxDistHands"] > (float)config["maxDist"]) { SW.WriteLine("searchMaxDistance > maxDistance"); }
                    if ((float)config["minDistHands"] > (float)config["maxDist"]) { SW.WriteLine("searchMinDistance > maxDistance"); }
                    if ((float)config["minDistHands"] >= (float)config["maxDistHands"]) { SW.WriteLine("searchMinDistance >= searchMaxDistance"); }
                    if ((float)config["zeroPoint"] < (float)config["maxDistHands"]) { SW.WriteLine("zeroPoint < searchMaxDistance"); }
                    if ((float)config["minDistHands"] > (float)config["minDist"]) { SW.WriteLine("searchMinDistance > minDistance"); }
                    if ((float)config["zeroPoint"] >= (float)config["maxDist"]) { SW.WriteLine("zeroPoint >= maxDistance"); }
                    if ((int)config["tuioConnexionPort"] < 0) { SW.WriteLine("tuioConnexionPort < 0"); }
                    if ((int)config["wsConnexionPort"] < 0) { SW.WriteLine("wsConnexionPort < 0"); }
                    if ((int)config["tuioTimerElapsing"] < 0) { SW.WriteLine("tuioTimerElapsing < 0"); }
                    if ((int)config["wsTimerElapsing"] < 0) { SW.WriteLine("wsTimerElapsing < 0"); }
                    if ((int)config["imagesToShow"] < 1) { SW.WriteLine("imagesToShow < 1"); }
                    if ((int)config["takenPoints"] <= 0) { SW.WriteLine("takenPoints <= 0"); }
                    if ((int)config["directionChangeTresholdXY"] < 0) { SW.WriteLine("directionChangeTresholdXY < 0"); }
                    if ((float)config["directionChangeTresholdZ"] < 0) { SW.WriteLine("directionChangeTresholdZ < 0"); }
                    SW.Close();
                    Console.WriteLine("Error File Created SucacessFully");
                }
                catch (Exception){}

                return false;
            }
            return true;
        }

        /*
         * Getters et setters des paramètres du Middleware.
         */
        public void setMinDistHands(float min)
        {
            config["minDistHands"] = min;
        }
        public void setMaxDistHands(float max)
        {
            config["maxDistHands"] = max;
        }
        public void setMinDist(float min)
        {
            config["minDist"] = min;
        }
        public void setMaxDist(float max)
        {
            config["maxDist"] = max;
        }
        public void setZeroPoint(float zero)
        {
            config["zeroPoint"] = zero;
        }
        public void setTuioConnexionHost(String host)
        {
            config["tuioConnexionHost"] = host;
        }
        public void setTuioConnexionPort(int port)
        {
            config["tuioConnexionPort"] = port;
        }
        public void setWsConnexionHost(String host)
        {
            config["wsConnexionHost"] = host;
        }
        public void setWsConnexionPort(int port)
        {
            config["wsConnexionPort"] = port;
        }
        public void setTuioTimerElapsing(int time)
        {
            config["tuioTimerElapsing"] = time;
        }
        public void setWsTimerElapsing(int time)
        {
            config["wsTimerElapsing"] = time;
        }
        public void setImagesToShow(int _imagesToShow)
        {
            config["imagesToShow"] = _imagesToShow;
        }
        public void setTakenPoints(int _takenPoints)
        {
            config["takenPoints"] = _takenPoints;
        }
        public void setDirectionChangeTresholdXY(int _directionChangeTresholdXY)
        {
            config["directionChangeTresholdXY"] = _directionChangeTresholdXY;
        }
        public void setDirectionChangeTresholdZ(float _directionChangeTresholdZ)
        {
            config["directionChangeTresholdZ"] = _directionChangeTresholdZ;
        }
        public void setSwitch(Button _switch)
        {
            Switch = _switch;
        }
        public void setOn(bool _on)
        {
            on = _on;
        }
        
        public float getMinDistHands()
        {
            return (float)config["minDistHands"];
        }
        public float getMaxDistHands()
        {
            return (float)config["maxDistHands"];
        }
        public float getMinDist()
        {
            return (float)config["minDist"];
        }
        public float getMaxDist()
        {
            return (float)config["maxDist"];
        }
        public float getZeroPoint()
        {
            return (float)config["zeroPoint"];
        }
        public String getTuioConnexionHost()
        {
            return (String)config["tuioConnexionHost"];
        }
        public int getTuioConnexionPort()
        {
            return (int)config["tuioConnexionPort"];
        }
        public int getTuioTimerElapsing()
        {
            return (int)config["tuioTimerElapsing"];
        }
        public String getWsConnexionHost()
        {
            return (String)config["wsConnexionHost"];
        }
        public int getWsConnexionPort()
        {
            return (int)config["wsConnexionPort"];
        }
        public int getWsTimerElapsing()
        {
            return (int)config["wsTimerElapsing"];
        }
        public int getImagesToShow()
        {
            return (int)config["imagesToShow"];
        }
        public int getTakenPoints()
        {
            return (int)config["takenPoints"];
        }
        public int getDirectionChangeTresholdXY()
        {
            return (int)config["directionChangeTresholdXY"];
        }
        public float getDirectionChangeTresholdZ()
        {
            return (float)config["directionChangeTresholdZ"];
        }
        public Button getSwitch()
        {
            return Switch;
        }
        public MenuItem getQuitMenu()
        {
            return QuitMenu;
        }
        
        public bool getOn()
        {
            return on;
        }

        public void onR0(bool b)
        {
            if(b)
                R0.Fill = System.Windows.Media.Brushes.Blue;
            else
                R0.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR1(bool b)
        {
            if (b)
                R1.Fill = System.Windows.Media.Brushes.Blue;
            else
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR2(bool b)
        {
            if (b)
                R2.Fill = System.Windows.Media.Brushes.Blue;
            else
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR3(bool b)
        {
            if (b)
                R3.Fill = System.Windows.Media.Brushes.Blue;
            else
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR4(bool b)
        {
            if (b)
                R4.Fill = System.Windows.Media.Brushes.Blue;
            else
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR5(bool b)
        {
            if (b)
                R5.Fill = System.Windows.Media.Brushes.Blue;
            else
                R5.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR6(bool b)
        {
            if (b)
                R6.Fill = System.Windows.Media.Brushes.Blue;
            else
                R6.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR7(bool b)
        {
            if (b)
                R7.Fill = System.Windows.Media.Brushes.Blue;
            else
                R7.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR8(bool b)
        {
            if (b)
                R8.Fill = System.Windows.Media.Brushes.Blue;
            else
                R8.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR9(bool b)
        {
            if (b)
                R9.Fill = System.Windows.Media.Brushes.Blue;
            else
                R9.Fill = System.Windows.Media.Brushes.DarkGray;
        }
        public void onR10(bool b)
        {
            if (b)
                R10.Fill = System.Windows.Media.Brushes.Blue;
            else
                R10.Fill = System.Windows.Media.Brushes.DarkGray;
        }

        /*
         * Ouvre un fichier selon son chemin.
         */
        public void OpenFile(String filePath)
        {
            try
            {
                System.Diagnostics.Process.Start(@filePath);
            }
            catch (Exception)
            {
                ExceptionLbl.Content = filePath + " : " + rm.GetString("fileNotFound");
            }
        }

        public void OpenFile(String program, String filePath)
        {
            try
            {
                System.Diagnostics.Process.Start(program, @filePath);
            }
            catch (Exception)
            {
                ExceptionLbl.Content = filePath + " : " + rm.GetString("fileNotFound");
            }
        }

        /*
         * Ouvre le readme du Middleware.
         */
        private void MiddlewareReadmeMenu_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["readmeMiddleware"]);
        }

        /*
         * Ouvre le readme du Front Processing.
         */
        private void FrontProcessingReadmeMenu_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["readmeFrontProcessing"]);
        }

        /*
         * Ouvre la documentation du Front Processing.
         */
        private void FrontProcessingDocumentationMenu_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["docFrontProcessing"]);
        }
        
        /*
         * Ouvre le readme du Front JS.
         */
        private void FrontJSReadmeMenu_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["readmeFrontJS"]);
        }

        /*
         * Ouvre la documentation du Front JS.
         */
        private void FrontJSDocumentationMenu_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["docFrontJS"]);
        }

        /*
         * Ouvre le fichier des paramètres.
         */
        private void ParamMenu_Click(object sender, RoutedEventArgs e)
        {
            OpenFile(".\\config.txt");
        }

        /*
         * Code de l'exemple processing de manipulation de fluide.
         */
        private void ProcessingMenuFMPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPFMPS"]);
        }
        
        //Exemple processing de manipulation de fluide.
        private void ProcessingMenuFMExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPFMExe"]);
        }

        /*
         * Code de l'exemple processing de manipulation de fumée.
         */
        private void ProcessingMenuSMPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPSMPS"]);
        }

        /*
         * Exemple processing de manipulation de fumée.
         */
        private void ProcessingMenuSMExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPSMExe"]);
        }

        /*
         * Code de l'exemple processing d'affichage des gestures.
         */
        private void ProcessingMenuTGPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPTGPS"]);
        }

        /*
         * Exemple processing d'affichage des gestures.
         */
        private void ProcessingMenuTGExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPTGExe"]);
        }

        /*
         * Code de l'exemple processing d'affichage des pointeurs.
         */
        private void ProcessingMenuTPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPTPS"]);
        }

        /*
         * Exemple processing d'affichage des pointeurs.
         */
        private void ProcessingMenuTExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPTExe"]);
        }

        /*
         * Code de l'exemple processing du press de la main.
         */
        private void ProcessingMenuIEHandPressPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHandPressPS"]);
        }

        /*
         * Exemple processing du press de la main.
         */
        private void ProcessingMenuIEHandPressExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHandPressExe"]);
        }

        /*
         * Code de l'exemple processing du signal de la main.
         */
        private void ProcessingMenuIEHandSignalPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHandSignalPS"]);
        }

        /*
         * Exemple processing du signal de la main.
         */
        private void ProcessingMenuIEHandSignalExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHandSignalExe"]);
        }

        /*
         * Code de l'exemple processing de la manipulation 1D de la main.
         */
        private void ProcessingMenuIEHand1DPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHand1DPS"]);
        }

        /*
         * Exemple processing de la manipulation 1D de la main.
         */
        private void ProcessingMenuIEHand1DExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHand1DExe"]);
        }

        /*
         * Code de l'exemple processing de la manipulation 2D de la main.
         */
        private void ProcessingMenuIEHand2DPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHand2DPS"]);
        }

        /*
         * Exemple processing de la manipulation 2D de la main.
         */
        private void ProcessingMenuIEHand2DExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exPIEHand2DExe"]);
        }

        /*
         * Code de l'exemple web de l'affichage des pointeurs.
         */
        private void WebMenuPointersPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exWPointersPS"]);
        }

        /*
         * Exemple web de l'affichage des pointeurs.
         */
        private void WebMenuPointersExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exWPointersExe"]);
        }

        /*
         * Code de l'exemple web de l'affichage des gestures.
         */
        private void WebMenuGesturesPS_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exWGesturesPS"]);
        }

        /*
         * Exemple web de l'affichage des gestures.
         */
        private void WebMenuGesturesExe_Click(object sender, RoutedEventArgs e)
        {
            OpenFile((String)config["exWGesturesExe"]);
        }
    }
}
