package de.ivu.elect.business.wahlvorschlag.control;

import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import de.ivu.elect.business.ergebnis.control.StimmenPoolFactory;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppeimgebiet.control.GruppeImGebietReihenfolgeVorsortierer;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

public class WahlvorschlagReihenfolgeVorsortierenComparator implements Comparator<Wahlvorschlag>, Serializable {

  private final Gebiet gebietFuerGruppeImGebiet;

  private final Comparator<GruppeImGebiet> comparator;

  public WahlvorschlagReihenfolgeVorsortierenComparator(GruppeImGebietReihenfolgeVorsortierer gruppeImGebietReihenfolgeVorsortierer, Collection<Wahlvorschlag> alleWahlvorschlaege, StimmenPoolFactory stimmenPoolFactory, Gebiet gebietFuerGruppeImGebiet) {
    this.gebietFuerGruppeImGebiet = gebietFuerGruppeImGebiet;
    comparator = gruppeImGebietReihenfolgeVorsortierer
        .getComparator(gebietFuerGruppeImGebiet.getWahl(), alleWahlvorschlaege, stimmenPoolFactory);
  }

  @Override
  public int compare(Wahlvorschlag o1, Wahlvorschlag o2) {
    return comparator.compare(bestimmeGruppeImGebiet(o1), bestimmeGruppeImGebiet(o2));
  }

  private Map<Wahlvorschlag, GruppeImGebiet> gigMap = new HashMap<>();

  private GruppeImGebiet bestimmeGruppeImGebiet(Wahlvorschlag wahlvorschlag) {
    if (wahlvorschlag.getGebiet().equals(gebietFuerGruppeImGebiet)) {
      return wahlvorschlag.getGruppeImGebiet();
    }
    if (!gigMap.containsKey(wahlvorschlag)) {
      gigMap.put(wahlvorschlag, bestimmeGruppeImGebietFuerGebiet(wahlvorschlag, gebietFuerGruppeImGebiet));
    }

    return gigMap.get(wahlvorschlag);

  }

  public static GruppeImGebiet bestimmeGruppeImGebietFuerGebiet(Wahlvorschlag wahlvorschlag, Gebiet gebiet) {
    for (GruppeImGebiet gruppeImGebiet : wahlvorschlag.getGruppe().getGruppenImGebiet()) {
      if (gruppeImGebiet.getGebiet().equals(gebiet)) {
        return gruppeImGebiet;
      }
    }
    throw new IllegalStateException("Keine GruppeImGebiet gefunden - wahlvorschlag:" + wahlvorschlag + ", gruppe: " + wahlvorschlag.getGruppe() + ", gebiet:" + gebiet);
  }
}
