
package de.ivu.elect.dokumente.ergebnis.zusammenstellung;

import java.util.Objects;
import java.util.Optional;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;

public class ErgebnisTabellarischAufteilungBlatt {

  private final Nummerierung nummerierung;

  private final Stimmenart stimmenart;

  private final boolean erstesBlattMitStimmenart;

  private final ErgebnisTabellarischTabelle tabelle;

  private final Optional<ErgebnisTabellarischZeile> zeileUebertragsummen;

  public ErgebnisTabellarischAufteilungBlatt(int nummerHorizontal, int nummerHorizontalMax, int nummerVertikal, int nummerVertikalMax, boolean erstesBlattMitStimmenart, Stimmenart stimmenart,
      ErgebnisTabellarischTabelle tabelle, Optional<ErgebnisTabellarischZeile> zeileUebertragsummen) {
    this(new Nummerierung(nummerHorizontal, nummerHorizontalMax, nummerVertikal, nummerVertikalMax), erstesBlattMitStimmenart, stimmenart, tabelle, zeileUebertragsummen);
  }

  private ErgebnisTabellarischAufteilungBlatt(Nummerierung nummerierung, boolean erstesBlattMitStimmenart, Stimmenart stimmenart, ErgebnisTabellarischTabelle tabelle,
      Optional<ErgebnisTabellarischZeile> zeileUebertragsummen) {
    super();

    this.nummerierung = nummerierung;

    this.stimmenart = stimmenart;
    this.erstesBlattMitStimmenart = erstesBlattMitStimmenart;

    this.tabelle = tabelle;

    this.zeileUebertragsummen = zeileUebertragsummen;
  }

  public Nummerierung getNummerierung() {
    return nummerierung;
  }

  public boolean isErstesBlattMitStimmenart() {
    return erstesBlattMitStimmenart;
  }

  public Stimmenart getStimmenart() {
    return stimmenart;
  }

  public ErgebnisTabellarischTabelle getTabelle() {
    return tabelle;
  }

  public Optional<ErgebnisTabellarischZeile> getZeileUebertragsummen() {
    return zeileUebertragsummen;
  }

  public static class Nummerierung implements Comparable<Nummerierung> {

    private final int nummerHorizontal;

    private final int nummerHorizontalMax;

    private final int nummerVertikal;

    private final int nummerVertikalMax;

    public Nummerierung(int nummerHorizontal, int nummerHorizontalMax, int nummerVertikal, int nummerVertikalMax) {
      super();

      this.nummerHorizontal = nummerHorizontal;
      this.nummerHorizontalMax = nummerHorizontalMax;

      this.nummerVertikal = nummerVertikal;
      this.nummerVertikalMax = nummerVertikalMax;
    }

    public boolean isWeitereNummerHorizontalVorhanden() {
      return getNummerHorizontal() < getNummerHorizontalMax();
    }

    public int getNummerHorizontal() {
      return nummerHorizontal;
    }

    public int getNummerHorizontalInitial() {
      return ErgebnisTabellarischAufteilung.NUMMER_HORIZONTAL_INITIAL;
    }

    public int getNummerHorizontalFortsetzung() {
      return Math.min(getNummerHorizontal() + 1, getNummerHorizontalMax());
    }

    public int getNummerHorizontalMax() {
      return nummerHorizontalMax;
    }

    public boolean isWeitereNummerVertikalVorhanden() {
      return getNummerVertikal() < getNummerVertikalMax();
    }

    public int getNummerVertikal() {
      return nummerVertikal;
    }

    public int getNummerVertikalInitial() {
      return ErgebnisTabellarischAufteilung.NUMMER_VERTIKAL_INITIAL;
    }

    public int getNummerVertikalFortsetzung() {
      return Math.min(getNummerVertikal() + 1, getNummerVertikalMax());
    }

    public int getNummerVertikalMax() {
      return nummerVertikalMax;
    }

    @Override
    public int compareTo(Nummerierung another) {
      int comparedByTeilNummer = Integer.compare(getNummerVertikal(), another.getNummerVertikal());

      if (comparedByTeilNummer == 0) {
        return Integer.compare(getNummerHorizontal(), another.getNummerHorizontal());
      }

      return comparedByTeilNummer;
    }

    /*
     * AUTO-GENERATED
     */

    @Override
    public int hashCode() {
      return Objects.hash(nummerHorizontal, nummerHorizontalMax, nummerVertikal, nummerVertikalMax);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }

      if (obj == null) {
        return false;
      }

      if (getClass() != obj.getClass()) {
        return false;
      }

      Nummerierung other = (Nummerierung) obj;

      return nummerHorizontal == other.nummerHorizontal && nummerHorizontalMax == other.nummerHorizontalMax && nummerVertikal == other.nummerVertikal && nummerVertikalMax == other.nummerVertikalMax;
    }
  }
}
