
package de.ivu.elect.presentation.kandidatur.table;

import static de.ivu.elect.jee.entity.EntityUtil.castTo;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import de.ivu.elect.business.ergebnis.boundary.ErgebnisSessionSelect;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.gebietsbaum.boundary.WahldurchfuehrungsgebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.kandidatur.entity.KandidaturKumulierteStimmen;
import de.ivu.elect.business.kandidatur.entity.WaehlerBenannteKandidaturen;
import de.ivu.elect.business.sitzberechnung.control.SitzberechnungsalgorithmusFinder;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeErfassenDescriptionResolver;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeStimmenartLabelGenerator;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.presentation.dynamictable.AbstractColumnBuilder;
import de.ivu.elect.jee.presentation.dynamictable.ColumnEntry;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;

public abstract class AbstractKandidaturKumulierteStimmenColumnBuilder<T extends KandidaturKumulierteStimmen> extends AbstractColumnBuilder<T> {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahldurchfuehrungsgebietSessionSelect wahldurchfuehrungsgebietSessionSelect;

  @Inject
  private transient ErgebnisSessionSelect ergebnisSessionSelect;

  @Inject
  private transient SitzberechnungsalgorithmusFinder sitzberechnungsalgorithmusFinder;

  @Inject
  private transient StimmeingabeErfassenDescriptionResolver stimmeingabeErfassenDescriptionResolver;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  protected KandidaturKumulierteStimmenGebietColumn kandidaturKumulierteStimmenGebietColumn;

  protected KandidaturKumulierteStimmenWahlvorschlagColumn kandidaturKumulierteStimmenWahlvorschlagColumn;

  protected KandidaturKumulierteStimmenNameColumn kandidaturKumulierteStimmenNameColumn;

  public AbstractKandidaturKumulierteStimmenColumnBuilder() {
    super();
  }

  @Override
  protected void initColumns() {
    kandidaturKumulierteStimmenGebietColumn = new KandidaturKumulierteStimmenGebietColumn(getMessages(), getGebietNummerFormatter());
    kandidaturKumulierteStimmenWahlvorschlagColumn = new KandidaturKumulierteStimmenWahlvorschlagColumn(getMessages());
    kandidaturKumulierteStimmenNameColumn = new KandidaturKumulierteStimmenNameColumn(getMessages(), getIcons());
  }

  @Override
  public List<ColumnEntry< ? super T>> getColumnEntriesSorted() {
    List<ColumnEntry< ? super T>> result = new ArrayList<>();

    result.add(kandidaturKumulierteStimmenGebietColumn);
    result.add(kandidaturKumulierteStimmenWahlvorschlagColumn);
    result.add(kandidaturKumulierteStimmenNameColumn);

    return result;
  }

  protected boolean isSitzberechnungsalgorithmusVergibtSitze() {
    Wahl wahl = getSelectedWahl();

    return wahl != null && wahl.isInstanceOf(Wahldurchfuehrung.class) && sitzberechnungsalgorithmusFinder.getSitzberechnungsalgorithmus(castTo(wahl, Wahldurchfuehrung.class)).isVergibtSitze();
  }

  protected StimmeingabeStimmenartLabelGenerator getStimmenartLabelGenerator(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return stimmeingabeErfassenDescriptionResolver.getStimmeingabeErfassenDescriptionByGebiet(wahldurchfuehrungsgebiet).getStimmeingabeGruppeStimmenErfassenLabelGenerator();
  }

  protected GebietNummerFormatter getGebietNummerFormatter() {
    return gebietNummerFormatter;
  }

  protected boolean isWaehlerBenannteKandidaturSonstige(T kandidaturKumulierteStimmen) {
    return kandidaturKumulierteStimmen != null && (WaehlerBenannteKandidaturen.isWaehlerBenannteDirektkandidaturSonstige(getMessages(), kandidaturKumulierteStimmen.getDirektkandidatur())
        || WaehlerBenannteKandidaturen.isWaehlerBenannteListenkandidaturSonstige(getMessages(), kandidaturKumulierteStimmen.getListenkandidatur()));
  }

  @Override
  public String getStyleClass(T kandidaturKumulierteStimmen) {
    String result = super.getStyleClass(kandidaturKumulierteStimmen);

    if (isWaehlerBenannteKandidaturSonstige(kandidaturKumulierteStimmen)) {
      result += AbstractKandidaturColumnBuilder.WAEHLER_BENANNTE_KANDIDATUR_SONSTIGE_STYLE_CLASS; // ELECT-9513, cf. AbstractKandidaturColumnBuilder!!!
    }

    return result;
  }

  protected boolean isWahlMitDirektwahlgebietenSelected() {
    Wahl wahl = getSelectedWahl();

    return wahl != null && wahl.isWahlMitDirektkandidatengebieten();
  }

  protected boolean isWahlMitListenwahlgebietenSelected() {
    Wahl wahl = getSelectedWahl();

    return wahl != null && wahl.isWahlMitListengebieten();
  }

  protected boolean isWahlMitGesamtstimmenauswertungSelected() {
    Wahl wahl = getSelectedWahl();

    return wahl != null && wahl.isWahlMitGesamtstimmenauswertung();
  }

  protected Wahl getSelectedWahl() {
    Ergebnis ergebnis = getSelectedErgebnis();

    if (ergebnis == null) {
      Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet = getSelectedGebiet();

      if (wahldurchfuehrungsgebiet == null) {
        return null;
      }

      return wahldurchfuehrungsgebiet.getWahl();
    }

    return ergebnis.getWahl();
  }

  protected boolean isGebietSelected() {
    return wahldurchfuehrungsgebietSessionSelect.isSelected();
  }

  protected Wahldurchfuehrungsgebiet getSelectedGebiet() {
    return wahldurchfuehrungsgebietSessionSelect.getEntity();
  }

  protected boolean isErgebnisSelected() {
    return getSelectedErgebnis() != null;
  }

  protected Ergebnis getSelectedErgebnis() {
    return ergebnisSessionSelect.getEntity();
  }
}
