///Licensed under Creative Commons Attribution 4.0 License, Written by Clemens Winter and Vladislav Nachev
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Exploitation
{
    /// <summary>
    /// Methods for generating a table of resources from behavioral output of agents
    /// </summary>
    class FlowerManager : RessourceManager
    {
        SimpleRNG rnd = new SimpleRNG();

        Flower[] flowers;

        public FlowerManager(Flower[] flowers)
        {
            this.flowers = flowers;
        }

        public override Ressource[] Ressources
        {
            get { return flowers; }
        }

        /// <summary>
        /// Create next generation of flowers (resources), using stochastic universal sampling (SUS)
        /// </summary>
        /// <returns>a resource table of the same size as the resource table in the previous generation</returns>
        public override Ressource[] CreateNewGeneration()
        {
            //Stochastic Universal Sampling:
            //1. Sort genotypes by frequencies
            PPO.Instance.SortbyFreq();

            string[] newGeneration = new string[flowers.Length];
            newGeneration = PPO.Instance.SUS(flowers.Length); //SUS select the needed number of new individuals store to an array of coded genotypes
            double meanConcSelected = PPO.Instance.MeanConc(newGeneration);
            double meanPotential = PPO.Instance.MeanPotential();
            double criterion = 0.3;
            int j = 0;

            while (Math.Abs(meanPotential - meanConcSelected) > criterion) //check to see if too much variance was introduced by SUS and repeat until criterion is met

            {
                j++;
                newGeneration = PPO.Instance.SUS(flowers.Length);
                meanConcSelected = PPO.Instance.MeanConc(newGeneration);
                if (j > 999)
                {
                    criterion += 0.1;
                    j = 0;
                }
            }


            bool ynAllele;
            //allele rescue in case an allele became extinct, it gets reintroduced to a random flower
            

            for (int g = 0; g < 4; g++)
            {
                ynAllele = false;


                for (int i = 1; i < flowers.Length; i++)
                {
                    if (flowers[i].Genotype.Substring(g) != flowers[i - 1].Genotype.Substring(g))
                    {
                        ynAllele = true;
                        break;
                    }
                }

                if (ynAllele == false)

                {

                    int r = rnd.GetInt(1, flowers.Length);
                    StringBuilder sb = new StringBuilder();
                    sb.Append(flowers[r-1].Genotype);
                    sb[g] = '1';
                    newGeneration[r - 1] = sb.ToString();
                    flowers[r-1].genotype = sb.ToString();
                }
            
            }

            for (int i = 0; i < flowers.Length; i++)
            {
                flowers[i] = flowers[i].SeedToFlower(newGeneration[i]);
            }
            return flowers;
        }

    }
}
