using System;
using System.Collections.Generic;
using EvoBoat.EvoAlg;

namespace PlantDemo
{
    public class PlantZombSolutionFactory : SolutionFactory<PlantZombProblem, PlantZombSolution, IntVector>
    {
        public PlantZombSolutionFactory(PlantZombProblem problem, int seed = 0) : base(problem, seed)
        { }

        public override PlantZombSolution CreateEmpty()
        {
            return new PlantZombSolution() { Content = new IntVector(Problem.Dimension) };
        }

        public override PlantZombSolution CreateRandom()
        {
            double r = Rand.NextDouble();
            if (r < 0.5)
                return CreateRandomFeasibleSolution(Rand);
            else if (r < 0.7)
                return CreateRandomSolution1(Rand);
            else if (r < 0.9)
                return CreateRandomSolution2(Rand);
            else
                return CreateRandomSolution(Rand);
        }

        public PlantZombSolution CreateRandomSolution(Random rand)
        {
            return new PlantZombSolution(IntVector.CreateRandom(rand, Problem.Dimension, 0, Problem.PlantTypes.Length));
        }

        public PlantZombSolution CreateRandomFeasibleSolution(Random rand)
        {
            PlantZombSolution sol = this.CreateRandomSolution(rand);
            Problem.ComputeCost(sol);
            while (sol.TCost > Problem.TotalSun)
            {
                int i = rand.Next(sol.Content.Length);
                if (sol.Content[i] != 0)
                {
                    sol.TCost -= Problem.Prices[sol.Content[i]];
                    sol.Content[i] = 0;
                }
            }
            return sol;
        }

        public PlantZombSolution CreateRandomSolution1(Random rand)
        {
            PlantZombSolution sol = new PlantZombSolution() { Content = new IntVector(Problem.Dimension) };
            for (int d = 0; d < Problem.Dimension; d++)
            {
                if (rand.Next(4) != 0)
                {
                    sol.Content[d] = rand.Next(Problem.PlantTypes.Length);
                    sol.TCost += Problem.Prices[sol.Content[d]];
                    if (sol.TCost >= Problem.TotalSun)
                        break;
                }
            }
            return sol;
        }

        public PlantZombSolution CreateRandomSolution2(Random rand)
        {
            PlantZombSolution sol = new PlantZombSolution() { Content = new IntVector(Problem.Dimension) };
            for (int d = Problem.Dimension-1; d >= 0; d--)
            {
                if (rand.Next(4) != 0)
                {
                    sol.Content[d] = rand.Next(Problem.PlantTypes.Length);
                    sol.TCost += Problem.Prices[sol.Content[d]];
                    if (sol.TCost >= Problem.TotalSun)
                        break;
                }
            }
            return sol;
        }
    }
}
