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

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

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;

public class ListeByPositionAufGebietComparator implements Comparator<Liste>, Serializable {

  private final Gebiet gebiet;

  private final Map<Gruppe, Collection<GruppeImGebiet>> gruppenImGebietNachGruppe;

  public ListeByPositionAufGebietComparator(Gebiet gebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    this.gebiet = gebiet;
    gruppenImGebietNachGruppe = new HashMap<>();
    for (GruppeImGebiet gruppeImGebiet : gruppenImGebiet) {
      if (!gruppenImGebietNachGruppe.containsKey(gruppeImGebiet.getGruppe())) {
        gruppenImGebietNachGruppe.put(gruppeImGebiet.getGruppe(), new ArrayList<GruppeImGebiet>());
      }
      gruppenImGebietNachGruppe.get(gruppeImGebiet.getGruppe()).add(gruppeImGebiet);
    }

  }

  @Override
  public int compare(Liste o1, Liste o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      }
      return -1;
    }
    if (o2 == null) {
      return 1;
    }
    Long position1 = getPostion(o1);
    Long position2 = getPostion(o2);
    int result = position1.compareTo(position2);
    if (result == 0) {
      result = o1.getPk().compareTo(o2.getPk());
    }
    return result;
  }

  private Long getPostion(Liste liste) {
    for (GruppeImGebiet gruppeImGebiet : gruppenImGebietNachGruppe.get(liste.getGruppe())) {
      if (gebiet.equals(gruppeImGebiet.getGebiet())) {
        Long positionAbgeleitet = gruppeImGebiet.getRelativePositionAbgeleitet();
        if (positionAbgeleitet != null) {
          return positionAbgeleitet;
        }
      }
    }
    return Long.MAX_VALUE;
  }
}
