using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// Pour plus d'informations sur le modèle d'élément Page vierge, consultez la page https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace ex_050_010_Threading_en_UWP
{
    /// <summary>
    /// Une page vide peut être utilisée seule ou constituer une page de destination au sein d'un frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        //contexte de synchronisation
        //utile que pour le 3ème exemple
        SynchronizationContext mSynchroContext;

        public object DispatcherHandler { get; private set; }

        public MainPage()
        {
            InitializeComponent();

            //utile que pour le 3ème exemple
            //récypère le contexte de synchronisation du UI thread
            mSynchroContext = SynchronizationContext.Current;
        }

        ////////////////////////////////////////////
        /* MAUVAISE METHODE : BLOQUE LE UI THREAD */
        ////////////////////////////////////////////

        //simulation de travail
        //met à jour de 10% la progressBar toutes les demi-secondes
        void Travaille(ProgressBar pb)
        {
            for (int i = 0; i < 10; i++)
            {
                Task.Delay(500).Wait();
                pb.Value++;
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            //lance la simulation de travail dans le UI thread (thread principal de l'application, ayant accès aux contrôles)
            Travaille(mProgressBar);
            //donne le même résultat ici, si on appelle Travaille2 à la place
        }

        /////////////////////////////////////////////////////////////////
        /* BONNE METHODE N°1 : MARSHALING AVEC DISPATCHER DU UI THREAD */
        /////////////////////////////////////////////////////////////////

        //simulation de travail
        //met à jour de 10% la progressBar toutes les demi-secondes
        async Task Travaille2(ProgressBar pb)
        {
            for (int i = 0; i < 10; i++)
            {
                await Task.Delay(500);
                Action action = () => pb.Value++;
                //permet d'envoyer la requête de modification d'une mise à jour de l'UI sur le UI Thread
                //Cette opération s'appelle : marshaling
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, ()=>action());
            }
        }

        private async void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //lance la simulation de travail dans un "worker" thread
            await Travaille2(mProgressBar2);
        }

        /////////////////////////////////////////////////////////////////////
        /* BONNE METHODE N°2 : MARSHALING AVEC CONTEXTE DE SYNCHRONISATION */
        /////////////////////////////////////////////////////////////////////

        //simulation de travail
        //met à jour de 10% la progressBar toutes les demi-secondes
        async Task Travaille3(ProgressBar pb)
        {
            for (int i = 0; i < 10; i++)
            {
                await Task.Delay(500);
                //permet d'envoyer la requête de modification d'une mise à jour de l'UI sur le UI Thread
                //Cette opération s'appelle : marshaling
                mSynchroContext.Post(_ => pb.Value++, null);
                //Post remplace BeginInvoke
                //Send remplace Invoke
            }
        }

        private async void Button_Click_3(object sender, RoutedEventArgs e)
        {
            await Travaille3(mProgressBar3);
        }
    }
}
