
package de.ivu.elect.dokumente;

import java.math.BigDecimal;

import de.ivu.document.generator.template.BaseDocument;
import de.ivu.document.generator.template.annotations.DocumentMethod;
import de.ivu.document.generator.template.annotations.DocumentParam;
import de.ivu.document.generator.template.annotations.DocumentSimpleField;
import de.ivu.elect.sitzberechnung.math.Fraction;
import de.ivu.elect.sitzberechnung.math.FractionConverter;

public class FractionDokument extends BaseDocument {

  private static final long serialVersionUID = 1L;

  private final DokumentFormatter formatter;

  private final Fraction fraction;

  private final BigDecimal fractionDecimal;

  @DocumentSimpleField("Zaehler")
  public final Long zaehler;

  @DocumentSimpleField("Zaehler-Formatiert")
  public final String zaehlerFormatiert;

  @DocumentSimpleField("Nenner-Formatiert")
  public final Long nenner;

  @DocumentSimpleField("Nenner")
  public final String nennerFormatiert;

  @DocumentSimpleField("Bruch-Formatiert-Gemein -> z/n")
  public final String bruchFormatiertGemein;

  @DocumentSimpleField("Bruch-Formatiert-Gemischt -> g z/n")
  public final String bruchFormatiertGemischt;

  @DocumentSimpleField("Bruch-Formatiert-Dezimal1Stellig")
  public final String bruchFormatiertDezimal1Stellig;

  @DocumentSimpleField("Bruch-Formatiert-Dezimal2Stellig")
  public final String bruchFormatiertDezimal2Stellig;

  @DocumentSimpleField("Bruch-Formatiert-Dezimal3Stellig")
  public final String bruchFormatiertDezimal3Stellig;

  @DocumentSimpleField("Bruch-Formatiert-Dezimal4Stellig")
  public final String bruchFormatiertDezimal4Stellig;

  @DocumentSimpleField("Bruch-Formatiert-Dezimal5Stellig")
  public final String bruchFormatiertDezimal5Stellig;

  @DocumentSimpleField("Bruch-Formatiert-Dezimal6Stellig")
  public final String bruchFormatiertDezimal6Stellig;

  public FractionDokument(BaseElectContext baseElectContext, Long zaehler, Long nenner) {
    this(baseElectContext, FractionConverter.convertingExakt().asFractionConverted(zaehler, nenner));
  }

  public FractionDokument(BaseElectContext baseElectContext, Fraction fraction) {
    super();

    this.formatter = new DokumentFormatter(baseElectContext.getLocale());

    this.fraction = fraction;
    this.fractionDecimal = BigDecimal.valueOf(fraction.doubleValue());

    this.zaehler = this.fraction.getNumerator();
    this.zaehlerFormatiert = formatter.formatZahl(this.zaehler);

    this.nenner = this.fraction.getDenominator();
    this.nennerFormatiert = formatter.formatZahl(this.nenner);

    long anteilGanzzahlig = this.fraction.getProperWhole();

    this.bruchFormatiertGemein = formatBruchGemein(this.zaehlerFormatiert, this.nennerFormatiert);
    this.bruchFormatiertGemischt = anteilGanzzahlig == 0 ? this.bruchFormatiertGemein : anteilGanzzahlig + " " + this.formatter.formatZahl(fraction.getProperNumerator()) + "/" + this.nennerFormatiert;

    this.bruchFormatiertDezimal1Stellig = this.formatter.formatBigDecimalKommastellen(this.fractionDecimal, 1);
    this.bruchFormatiertDezimal2Stellig = this.formatter.formatBigDecimalKommastellen(this.fractionDecimal, 2);
    this.bruchFormatiertDezimal3Stellig = this.formatter.formatBigDecimalKommastellen(this.fractionDecimal, 3);
    this.bruchFormatiertDezimal4Stellig = this.formatter.formatBigDecimalKommastellen(this.fractionDecimal, 4);
    this.bruchFormatiertDezimal5Stellig = this.formatter.formatBigDecimalKommastellen(this.fractionDecimal, 5);
    this.bruchFormatiertDezimal6Stellig = this.formatter.formatBigDecimalKommastellen(this.fractionDecimal, 6);
  }

  @DocumentMethod
  public String getBruchFormatiertDezimal(@DocumentParam("anzahlNachkommastellen") int anzahlNachkommastellen) {
    return formatter.formatBigDecimalKommastellen(fractionDecimal, anzahlNachkommastellen); // RoundingMode#HALF_UP, cf. DokumentFormatter#formatNumberStellenFix...
  }

  @DocumentMethod
  public String getBruchFormatiertGemein(Object zaehler, Object nenner) {
    return formatBruchGemein(zaehler, nenner);
  }

  public static String formatBruchGemein(Object zaehler, Object nenner) {
    return (zaehler == null ? "" : zaehler) + " / " + (nenner == null ? "" : nenner);
  }
}
