
package de.ivu.elect.presentation.ergebnis.dokumente.gesamtergebnis;

import static de.ivu.elect.dokumente.DokumentFormatter.formatNumber;
import static de.ivu.elect.dokumente.DokumentFormatter.formatProzent;

import java.math.BigDecimal;

import javax.annotation.Nullable;

import de.ivu.document.generator.template.BaseDocument;
import de.ivu.document.generator.template.annotations.DocumentSimpleField;
import de.ivu.elect.dokumente.BaseElectContext;
import de.ivu.elect.was.exchange.internet.velocity.PolitischeGruppeProzentGewinnVerlust;
import de.ivu.elect.was.exchange.internet.velocity.SystemGruppeProzentGewinnVerlust;

public class GruppenStimmen extends BaseDocument {

  private static final long serialVersionUID = 1L;

  @DocumentSimpleField("Anzahl-Stimmen")
  public final Long anzahlStimmen;

  @DocumentSimpleField("Anzahl-Stimmen-Formatiert")
  public final String anzahlStimmenFormatiert;

  @DocumentSimpleField("Anzahl-Stimmen-Nur-Urnenwahl")
  public final Long anzahlStimmenNurUrnenwahl;

  @DocumentSimpleField("Anzahl-Stimmen-Nur-Urnenwahl-Formatiert")
  public final String anzahlStimmenNurUrnenwahlFormatiert;

  @DocumentSimpleField("Anzahl-Stimmen-Nur-Briefwahl")
  public final Long anzahlStimmenNurBriefwahl;

  @DocumentSimpleField("Anzahl-Stimmen-Nur-Briefwahl-Formatiert")
  public final String anzahlStimmenNurBriefwahlFormatiert;

  @DocumentSimpleField("Anteil-Stimmen")
  public final BigDecimal prozent;

  @DocumentSimpleField("Anteil-Stimmen-Formatiert")
  public final String prozentFormatiert;

  @DocumentSimpleField("Anzahl-Stimmen-Vorperiode")
  public final Long anzahlStimmenVorperiode;

  @DocumentSimpleField("Anzahl-Stimmen-Vorperiode-Formatiert")
  public final String anzahlStimmenVorperiodeFormatiert;

  @DocumentSimpleField("GewinnVerlust-Anzahl-Stimmen")
  public final Long anzahlStimmenGewinnVerlust;

  @DocumentSimpleField("GewinnVerlust-Anzahl-Stimmen-Formatiert")
  public final String anzahlStimmenGewinnVerlustFormatiert;

  @DocumentSimpleField("GewinnVerlust-Anteil-Stimmen")
  public final BigDecimal gewinnVerlust;

  @DocumentSimpleField("GewinnVerlust-Anteil-Stimmen-Formatiert")
  public final String gewinnVerlustFormatiert;

  public GruppenStimmen(BaseElectContext baseElectContext, @Nullable PolitischeGruppeProzentGewinnVerlust stimmen) {
    super();

    if (stimmen == null) {
      this.anzahlStimmen = null;
      this.anzahlStimmenNurUrnenwahl = null;
      this.anzahlStimmenNurBriefwahl = null;

      this.prozent = null;

      this.anzahlStimmenVorperiode = null;

      this.anzahlStimmenGewinnVerlust = null;
      this.gewinnVerlust = null;
    } else {
      this.anzahlStimmen = stimmen.getAnzahl();
      this.anzahlStimmenNurUrnenwahl = stimmen.getAnzahlNurUrnenwahl();
      this.anzahlStimmenNurBriefwahl = stimmen.getAnzahlNurBriefwahl();

      this.prozent = stimmen.getAnteil();

      this.anzahlStimmenVorperiode = stimmen.getAnzahlVorperiode();

      this.anzahlStimmenGewinnVerlust = subtrahiere(stimmen.getAnzahl(), stimmen.getAnzahlVorperiode());
      this.gewinnVerlust = stimmen.getGewinnVerlust();
    }

    this.anzahlStimmenFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmen);
    this.anzahlStimmenNurUrnenwahlFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenNurUrnenwahl);
    this.anzahlStimmenNurBriefwahlFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenNurBriefwahl);

    this.prozentFormatiert = formatAnteilStimmen(baseElectContext, this.prozent);

    this.anzahlStimmenVorperiodeFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenVorperiode);

    this.anzahlStimmenGewinnVerlustFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenGewinnVerlust);
    this.gewinnVerlustFormatiert = formatAnteilStimmen(baseElectContext, this.gewinnVerlust);
  }

  public GruppenStimmen(BaseElectContext baseElectContext, SystemGruppeProzentGewinnVerlust stimmen) {
    super();

    if (stimmen == null) {
      this.anzahlStimmen = null;
      this.anzahlStimmenNurUrnenwahl = null;
      this.anzahlStimmenNurBriefwahl = null;

      this.prozent = null;

      this.anzahlStimmenVorperiode = null;

      this.anzahlStimmenGewinnVerlust = null;
      this.gewinnVerlust = null;
    } else {
      this.anzahlStimmen = stimmen.getAnzahl();
      this.anzahlStimmenNurUrnenwahl = stimmen.getAnzahlNurUrnenwahl();
      this.anzahlStimmenNurBriefwahl = stimmen.getAnzahlNurBriefwahl();

      this.prozent = stimmen.getAnteil();

      this.anzahlStimmenVorperiode = stimmen.getAnzahlVorperiode();

      this.anzahlStimmenGewinnVerlust = subtrahiere(stimmen.getAnzahl(), stimmen.getAnzahlVorperiode());
      this.gewinnVerlust = stimmen.getGewinnVerlust();
    }

    this.anzahlStimmenFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmen);
    this.anzahlStimmenNurUrnenwahlFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenNurUrnenwahl);
    this.anzahlStimmenNurBriefwahlFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenNurBriefwahl);

    this.prozentFormatiert = formatAnteilStimmen(baseElectContext, this.prozent);

    this.anzahlStimmenVorperiodeFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenVorperiode);

    this.anzahlStimmenGewinnVerlustFormatiert = formatAnzahlStimmen(baseElectContext, this.anzahlStimmenGewinnVerlust);
    this.gewinnVerlustFormatiert = formatAnteilStimmen(baseElectContext, this.gewinnVerlust);
  }

  @Nullable // ELECTKOM-517
  static Long subtrahiere(Long minuend, Long subtrahend) {
    if (minuend == null || subtrahend == null) {
      if (minuend == null) {
        if (subtrahend == null) {
          return null;
        }

        return -subtrahend;
      } else {
        return minuend;
      }
    }

    return minuend - subtrahend;
  }

  private static String formatAnzahlStimmen(BaseElectContext baseElectContext, Long anzahlStimmen) {
    return formatNumber(anzahlStimmen, baseElectContext.getLocale());
  }

  private static String formatAnteilStimmen(BaseElectContext baseElectContext, BigDecimal anteilStimmen) {
    return formatProzent(anteilStimmen, baseElectContext.getLocale());
  }
}
