using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
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_052_006_problématique_6_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
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*********************  VERSION SYNCHRONE   *******************************************************************************/
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            DisplayPrimeCounts();
        }

        int GetPrimesCount(int start, int count)
        {
            return Enumerable.Range(start, count).Count(n =>
                Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0));
        }

        void DisplayPrimeCounts()
        {
            for (int i = 0; i < 10; i++)
            {
                mTextBlockSynchrone.Text += string.Format("{0} primes between {1} and {2}",
                                GetPrimesCount(i * 1000000 + 2, 1000000),
                                i * 1000000,
                                (i + 1) * 1000000 - 1) + Environment.NewLine;
            }
            mTextBlockSynchrone.Text += "Done !";
        }


        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*********************  VERSION ASYNCHRONE   ******************************************************************************/
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private async void Button_Click_2(object sender, RoutedEventArgs e)
        {
            (sender as Button).IsEnabled = false;
            await DisplayPrimeCountsAsync();
            (sender as Button).IsEnabled = true;
        }

        Task<int> GetPrimesCountAsync(int start, int count)
        {
            return Task.Run(() => Enumerable.Range(start, count).Count(n =>
                Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0)));
        }

        async Task DisplayPrimeCountsAsync()
        {
            for (int i = 0; i < 10; i++)
            {
                mTextBlockAsynchrone.Text += string.Format("{0} primes between {1} and {2}",
                                await GetPrimesCountAsync(i * 1000000 + 2, 1000000),
                                i * 1000000,
                                (i + 1) * 1000000 - 1) + Environment.NewLine;
            }
            mTextBlockAsynchrone.Text += "Done !";
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*********************  VIEILLE SOLUTION   ********************************************************************************/
        /*********************  COURSE-GRAINED CONCURRENCY   **********************************************************************/
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            (sender as Button).IsEnabled = false;
            Task.Run(() => DisplayPrimeCountsCGC());
        }

        int GetPrimesCountCGC(int start, int count)
        {
            return Enumerable.Range(start, count).Count(n =>
                Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0));
        }

        async void DisplayPrimeCountsCGC()
        {
            for (int i = 0; i < 10; i++)
            {
                int temp = i;
                int result = GetPrimesCountCGC(temp * 1000000 + 2, 1000000);
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
                mTextBlockCourseGrainedConcurrency.Text += string.Format("{0} primes between {1} and {2}",
                                result,
                                temp * 1000000,
                                (temp + 1) * 1000000 - 1) + Environment.NewLine);
            }
            await Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.High, () =>
            {
                mTextBlockCourseGrainedConcurrency.Text += "Done !";
                mButtonCGC.IsEnabled = true;
            });

        }
    }
}
