using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;

namespace ex_052_006_problématique_6
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            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));
        }

        void DisplayPrimeCountsCGC()
        {
            for (int i = 0; i < 10; i++)
            {
                int temp = i;
                int result = GetPrimesCountCGC(temp * 1000000 + 2, 1000000);
                Dispatcher.BeginInvoke(new Action(() =>
                mTextBlockCourseGrainedConcurrency.Text += string.Format("{0} primes between {1} and {2}",
                                result,
                                temp * 1000000,
                                (temp + 1) * 1000000 - 1) + Environment.NewLine));
            }
            Dispatcher.BeginInvoke(new Action(() =>
            {
                mTextBlockCourseGrainedConcurrency.Text += "Done !";
                mButtonCGC.IsEnabled = true;
            }));
            
        }
    }
}
