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

import java.io.Serializable;
import java.util.Comparator;

import de.ivu.elect.business.ergebnis.entity.Gewaehlt;
import de.ivu.elect.business.kandidatur.entity.KandidaturGewaehlt;
import de.ivu.elect.util.NullComparator;

public class KandidaturGewaehltByGewaehltAndStimmenAnzahlComparator implements Comparator<KandidaturGewaehlt>, Serializable {

  private static final long serialVersionUID = 1L;

  private static final Comparator<Object> NULL_COMPARATOR = NullComparator.NON_NULL_BEFORE_NULL_COMPARATOR;

  public KandidaturGewaehltByGewaehltAndStimmenAnzahlComparator() {
    super();
  }

  @Override
  public int compare(KandidaturGewaehlt one, KandidaturGewaehlt another) {
    if (one != null && another != null) {
      int comparedByGewaehlt = compare(one.getGewaehlt(), another.getGewaehlt());

      if (comparedByGewaehlt == 0) {
        return compareDesc(one.getStimmenAnzahl(), another.getStimmenAnzahl());
      }

      return comparedByGewaehlt;
    }

    return NULL_COMPARATOR.compare(one, another);
  }

  private int compare(Gewaehlt one, Gewaehlt another) {
    if (one != null && another != null) {
      if (one.getGewaehltStatus().isLosOffen()) {
        if (another.getGewaehltStatus().isLosOffen()) {
          return 0;
        }

        return -1;
      }

      if (another.getGewaehltStatus().isLosOffen()) {
        return 1;
      }

      int comparedByRang = compareRang(one.getRang(), another.getRang());

      if (comparedByRang == 0) {
        return one.getGewaehltStatus().compareTo(another.getGewaehltStatus());
      }

      return comparedByRang;
    }

    return NULL_COMPARATOR.compare(one, another);
  }

  private int compareRang(Long one, Long another) {
    if (one != null && another != null) {
      if (one == 0L && another > 0L) {
        return 1;
      }

      if (one > 0L && another == 0L) {
        return -1;
      }

      return one.compareTo(another);
    }

    return NULL_COMPARATOR.compare(one, another);
  }

  private int compareDesc(Long one, Long another) {
    if (one != null && another != null) {
      return another.compareTo(one);
    }

    return NULL_COMPARATOR.compare(one, another);
  }
}
