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;

namespace island
{
    public partial class Form1 : Form
    {

        TGrass Grass;
        Animal Rabbit;
        Animal Wolf;

        int N = 10;// число популяций
        Generation Gen;
        List<Generation> Population;        

        public Form1()
        {
            InitializeComponent();            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Grass = new TGrass(
                Convert.ToInt16(textBox1.Text),
                Convert.ToDouble(textBox2.Text));
            Rabbit = new Animal(
                Convert.ToInt16(textBox3.Text),
                Convert.ToDouble(textBox4.Text),
                Convert.ToDouble(textBox5.Text),
                Convert.ToDouble(textBox6.Text)                                
                );
            Wolf = new Animal(
                Convert.ToInt16(textBox7.Text),
                Convert.ToDouble(textBox8.Text),
                Convert.ToDouble(textBox9.Text),
                Convert.ToDouble(textBox10.Text)
           );

            richTextBox1.Text += Grass.ToString() + "\n";
            richTextBox1.Text += Rabbit.ToString() + "\n";
            richTextBox1.Text += Wolf.ToString() + "\n";

            Gen = new Generation();
            richTextBox1.Text += Gen.ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // 1.
            Grass.Grow();
            // 2.
            Rabbit.Dead();
            // 3.
            Grass.Count = Rabbit.Eat(Grass.Count);
            // 4.
            Rabbit.Born();
            // 5.
            Rabbit.Count = Wolf.Eat(Rabbit.Count);
            // 6.
            Wolf.Born();
            // 7.
            Wolf.Dead();

            //richTextBox1.Text += Grass.ToString() + "\n";
            //richTextBox1.Text += Rabbit.ToString() + "\n";
            //richTextBox1.Text += Wolf.ToString() + "\n";
        }
        int PesentTheBest = 20;
        int PesentCross = 50;
        int PesentMut = 30;
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int bestGenerationCount =0;
            while (bestGenerationCount<10)
            {
            bool flag = true;
            while (flag) {
                int k = 0;
                foreach (Generation g in Population)
                {
                    if (g.CheckGeneration() > 0)
                    {
                        g.Life();
                        k++;
                    }
                    if (k == 0) 
                        flag = false;
                }
            }
            // 1 сохраняем лучших представителей
            int max = -1;
            int nomer = 0;
            for (int i = 0; i < N-1; i++)
            {
                // поиск максиммального элемента среди неотсортированных
                max = -1;
                for (int j = i+1; j < N; j++)
                {
                    Generation g = Population[j];
                    if (max < g.GenerationCount)
                    {
                        max = g.GenerationCount;
                        nomer = j;
                    }
                }
                //меняем элементы местами
                Generation k = Population[i];
                Population[i] = Population[nomer];
                Population[nomer] = k;                
            }
            // так потому что мы только что отсортировали наш список по убыванию
            bestGenerationCount = Population[0].GenerationCount; // 
            // формируем новый список шаг 1 добавляем лучших представителей
            List<Generation> newPopulation = new List<Generation>();
            for (int i = 0; i < Math.Round((N * PesentTheBest) / 100.0); i++)
            {
                newPopulation.Add(Population[i]);
            }
            // 2 оператор "коросовер" - скрешиваем разных представителей прошлой 
            // популяции для получения потомства
            for (int i = 0; i < Math.Round((N * PesentCross) / 100.0); i++)
            {
                Random rnd = new Random();
                int k = rnd.Next(N-2);
                Generation father = Population[k];
                Generation mover = Population[k+1];
                Generation kid = new Generation();
                // гены получаемые от отца
                kid.Grass = father.Grass;
                // гены получаемые от матери
                kid.Rabbit = mover.Rabbit;
                kid.Wolf = mover.Wolf;

                newPopulation.Add(kid);
            }
            // 3 оператор мутация. случайным образом меняем набор 
            // генов и добавляем полученный элемент в популяцию
            for (int i = 0; i < Math.Round((N * PesentMut) / 100.0); i++)
            {
                Generation g = new Generation();
                newPopulation.Add(g); // -- вот и все изначально мы так и сделали что 
                // новая популяция создается со случайным набором генов
            }
            Population = newPopulation; // перезаписываем начальные условия
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {            
            foreach (Generation g in Population)
            {
                richTextBox1.Text += g.ToStringInit() + "\n";
                richTextBox1.Text += "+++++++++++++++\n";
                richTextBox1.Text += "N="+g.GenerationCount.ToString() + "\n";
                richTextBox1.Text += g.Grass.ToString() + "\n";
                richTextBox1.Text += g.Rabbit.ToString() + "\n";
                richTextBox1.Text += g.Wolf.ToString() + "\n";
                richTextBox1.Text += "-------------\n";                
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //backgroundWorker1.RunWorkerAsync();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Gen.Life();
            richTextBox1.Text += Gen.ToString();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            Population = new List<Generation>();
            for (int i = 0; i < N; i++)
            {
                Generation g = new Generation();
 
                //richTextBox1.Text += g.Grass.ToString() + "\n";
                //richTextBox1.Text += g.Rabbit.ToString() + "\n";
                //richTextBox1.Text += g.Wolf.ToString() + "\n";
                richTextBox1.Text += g.ToString() + "\n";
                richTextBox1.Text += "***************\n"; 
                Population.Add(g);
            }
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }



    }
}
