package multinomad.individuals;

import java.util.ArrayList;
import java.util.Iterator;

import multinomad.config.Configuration;

public class Population implements Iterable<DoubleIndividual>{
	private ArrayList<DoubleIndividual> p;
	
	public Population(boolean initialize) {
		p = new ArrayList<DoubleIndividual>();
		
		if(initialize) {
			for (int i=0;i<Configuration.Psize;i++) {
				DoubleIndividual ind = new DoubleIndividual();
				//ind.setFitness(Configuration.f.evaluate(ind.getChr().asdouble()));
				p.add(ind);
			}
			
			double [] fitnesses = Configuration.f.evaluateAPopulation(this);
			for (int i=0;i<Configuration.Psize;i++) {
				p.get(i).setFitness(fitnesses[i]);
			}	
		}
	}
	
	public Population() {
		p = new ArrayList<DoubleIndividual>();
		
		double lowerD1 = Configuration.f.getBounds().get(0).getLower();
		double upperD1 = Configuration.f.getBounds().get(0).getUpper();

		double lowerD2 = Configuration.f.getBounds().get(1).getLower();
		double upperD2 = Configuration.f.getBounds().get(1).getUpper();
		
		int steps = (int) Math.sqrt(Configuration.Psize);
		double intervalD1 = ((upperD1 - lowerD1)) / (steps-1);
		double intervalD2 = ((upperD2 - lowerD2)) / (steps-1);
			
		
		int indexD1 = 0;
		int indexD2 = -1;
		for (int i=0;i<Configuration.Psize;i++) {

			if ((i%steps)==0) {
				indexD1 = 0;
				indexD2 ++;
			}
			
			double [] x = new double[2];
			x[0] = lowerD1 + (indexD1*intervalD1);
			x[1] = lowerD2 + (indexD2*intervalD2);

			indexD1++;
			DoubleIndividual ind = new DoubleIndividual(x);
			ind.setFitness(Configuration.f.evaluate(ind.getChr().asdouble()));
			System.out.println("Contour:\t\t"+ ind.asString());
			p.add(ind);
		}			
	}
	
	public ArrayList<DoubleIndividual> getP() {
		return p;
	}
	
	public int size() {
		return p.size();
	}
	
	public void add(DoubleIndividual ind) {
		boolean noduplicate = true;
		for (DoubleIndividual i : p) {
			if (i.equals(ind)) {
				noduplicate = false;
				break;
			}
		}
		if (noduplicate)
			p.add(ind);
	}
	
	public String asPyNomadString() {
		String str="";
		
		double [] gens = p.get(0).getChr().asdouble();
		str += gens[0];
		for (int i=1;i<gens.length;i++)
			str += ","+gens[i];
		
		for (int j=1;j<p.size();j++) {
			gens = p.get(j).getChr().asdouble();
			str += ":"+gens[0];
			for (int i=1;i<gens.length;i++)
				str += ","+gens[i];
		}
		
		return str;
	}

	public Iterator<DoubleIndividual> iterator() {
		return p.iterator();
	}

}
