using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Collections;

namespace LINQ_to_Random
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /*
            ŹródłoLiczbLosowych zrodlo = new ŹródłoLiczbLosowych(10);
            //var zapytanie = from double liczba in zrodlo select liczba;
            var zapytanie = from double liczba in zrodlo where liczba > 0.5 orderby liczba select liczba;
            
            string s = "Liczby losowe:\n";
            foreach (double liczba in zapytanie) s += liczba.ToString() + "\n";
            MessageBox.Show(s);
            */

            ŹródłoLiczbLosowych<double> zrodloDouble = new ŹródłoLiczbLosowych<double>(10);
            var zapytanieDouble = from liczba in zrodloDouble
                                  where liczba > 0.5
                                  orderby liczba
                                  select liczba;

            string s = "Liczby losowe typu double z zakresu od 0 do 1:\n";
            foreach (var liczba in zapytanieDouble) s += liczba.ToString() + "\n";
            MessageBox.Show(s);

            //--------------------------------

            ŹródłoLiczbLosowych<int> zrodloInt = new ŹródłoLiczbLosowych<int>(10);
            var zapytanieInt = from liczba in zrodloInt
                               where liczba > int.MaxValue / 2
                               orderby liczba
                               select liczba;

            s = "Liczby losowe typu int z zakresu od 0 do " + int.MaxValue.ToString() + ":\n";
            foreach (var liczba in zapytanieInt) s += liczba.ToString() + "\n";
            MessageBox.Show(s);

        }
    }

    class ŹródłoLiczbLosowych<T> : IEnumerable, IEnumerable<T>
    {
        int size = 0;

        public ŹródłoLiczbLosowych(int size)
        {
            if (size < 1) throw new Exception("Rozmiar musi być liczbą większą od zera");
            else this.size = size;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return ((IEnumerable<T>)Execute()).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return Execute().GetEnumerator();
        }

        public IEnumerable<T> Execute()
        {
            if (typeof(T) == typeof(double)) return (IEnumerable<T>)ExecuteDouble();
            if (typeof(T) == typeof(int)) return (IEnumerable<T>)ExecuteInt();

            throw new Exception("Parametry typu innego niż double lub int nie są obsługiwane");
        }

        private List<double> ExecuteDouble()
        {
            Random random = new Random();
            List<double> lista = new List<double>(size);
            for (int i = 0; i < size; i++)
            {
                double liczba = random.NextDouble();
                lista.Add(liczba);
            }
            return lista;
        }

        private List<int> ExecuteInt()
        {
            Random random = new Random();
            List<int> lista = new List<int>(size);
            for (int i = 0; i < size; i++)
            {
                int liczba = random.Next();
                lista.Add(liczba);
            }
            return lista;
        }
    }
}
