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

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

import javax.inject.Inject;
import javax.inject.Named;

import de.ivu.elect.business.ergebnis.boundary.ErgebnisSessionSelect;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.kandidatur.boundary.KandidaturGewaehltSearch;
import de.ivu.elect.business.kandidatur.entity.KandidaturGewaehlt;
import de.ivu.elect.business.sitzberechnung.control.Sitzberechnungsalgorithmus;
import de.ivu.elect.business.sitzberechnung.control.SitzberechnungsalgorithmusFinder;
import de.ivu.elect.jee.presentation.dynamictable.AbstractColumnBuilder;
import de.ivu.elect.jee.presentation.dynamictable.ColumnEntry;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import de.ivu.elect.presentation.table.AbstractColumnEntry;

@Named(KandidaturGewaehltColumnBuilder.COMPONENT_NAME)
public class KandidaturGewaehltColumnBuilder extends AbstractColumnBuilder<KandidaturGewaehlt> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "kandidaturGewaehltColumnBuilder";

  @Inject
  protected transient GebietSessionSelect gebietSessionSelect;

  @Inject
  protected transient ErgebnisSessionSelect ergebnisSessionSelect;

  @Inject
  protected transient KandidaturGewaehltSearch kandidaturGewaehltSearch;

  @Inject
  protected transient SitzberechnungsalgorithmusFinder sitzberechnungsalgorithmusFinder;

  @Inject
  protected transient GebietNummerFormatter gebietNummerFormatter;

  protected AbstractColumnEntry<KandidaturGewaehlt> gewaehltGewaehltStatusColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> gewaehltRangColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> stimmenAnzahlColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> wahlvorschlagColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> kandidaturFamiliennameColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> kandidaturRufnameColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> kandidaturGeburtsdatumColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> kandidaturGebietNameColumn;

  protected AbstractColumnEntry<KandidaturGewaehlt> kandidaturStimmzettelPositionColumn;

  public KandidaturGewaehltColumnBuilder() {
    super();
  }

  @Override
  protected void initColumns() {
    gewaehltGewaehltStatusColumn = new KandidaturGewaehltGewaehltGewaehltStatusColumn(getMessages(), getIcons());
    gewaehltRangColumn = new KandidaturGewaehltGewaehltRangColumn(getSelectedGebiet(), getMessages());

    stimmenAnzahlColumn = new KandidaturGewaehltStimmenAnzahlColumn(getMessages());

    wahlvorschlagColumn = new KandidaturGewaehltKandidaturWahlvorschlagColumn(getMessages());

    kandidaturFamiliennameColumn = new KandidaturGewaehltKandidaturFamiliennameColumn(getMessages());
    kandidaturRufnameColumn = new KandidaturGewaehltKandidaturRufnameColumn(getMessages());
    kandidaturGeburtsdatumColumn = new KandidaturGewaehltKandidaturGeburtsdatumColumn(getMessages());
    kandidaturGebietNameColumn = new KandidaturGewaehltKandidaturGebietNameColumn(getMessages(), gebietNummerFormatter);
    kandidaturStimmzettelPositionColumn = new KandidaturGewaehltStimmzettelPositionColumn(getMessages());
  }

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

    KandidaturGewaehltSitzberechnungsalgorithmusColumnBuilder sitzberechnungsalgorithmusColumnBuilder = getSitzberechnungsalgorithmusColumnBuilder(getSelectedErgebnis());

    result.add(kandidaturGebietNameColumn);

    result.add(wahlvorschlagColumn);

    sitzberechnungsalgorithmusColumnBuilder.addGewaehltKandidaturColumnEntries(result, kandidaturFamiliennameColumn, kandidaturRufnameColumn, kandidaturGeburtsdatumColumn);

    sitzberechnungsalgorithmusColumnBuilder.addGewaehltGewaehltStatusColumnEntries(result, gewaehltGewaehltStatusColumn);

    // Reihenfolge Stimmen/Rang/Stimmzettelposition, cf. DirektkandidaturKumulierteStimmenColumnBuilder#getColumnEntriesSorted, ListenkandidaturKumulierteStimmenColumnBuilder#getColumnEntriesSorted!
    if (isBerechneStimmen()) {
      result.add(stimmenAnzahlColumn);
    }

    sitzberechnungsalgorithmusColumnBuilder.addGewaehltRangColumnEntries(result, gewaehltRangColumn);

    result.add(kandidaturStimmzettelPositionColumn);

    return result;
  }

  protected boolean isBerechneStimmen() {
    return kandidaturGewaehltSearch.isBerechneStimmen();
  }

  protected Gebiet getSelectedGebiet() {
    return gebietSessionSelect.getEntity();
  }

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

  protected KandidaturGewaehltSitzberechnungsalgorithmusColumnBuilder getSitzberechnungsalgorithmusColumnBuilder(Ergebnis ergebnis) {
    return getSitzberechnungsalgorithmus(ergebnis).getKandidaturGewaehltColumnBuilder(getMessages());
  }

  protected Sitzberechnungsalgorithmus< ? > getSitzberechnungsalgorithmus(Ergebnis ergebnis) {
    if (ergebnis == null) {
      return sitzberechnungsalgorithmusFinder.getKeinSitzberechnungsalgorithmus();
    }

    return sitzberechnungsalgorithmusFinder.getSitzberechnungsalgorithmus(ergebnis.getSitzberechnungsalgorithmus());
  }
}
