ratenrechner = function() {

  function parseMonetaryAmount(s) {
    var result = Number(s.replace(/\./, "").replace(/,/, ".").replace(/\s+EUR/,""));
    result = Math.round(result * 100);
    return result;
  }

  function formatMonetaryAmount(ma) {
    if (ma < 0) return "-" + formatMonetaryAmount(-ma);

    var result = "" + Math.floor(ma / 100.0) + ",";
    var cent = ma % 100;
    if (cent < 10)
      result += "0";
    result += cent;
    result += "\xA0EUR";
    return result;
  }

  function formatPercentage(num) {
    var result = "" + Math.floor(num) + ",";
    var frac = Math.floor(num * 100);
    if (frac < 10)
      result += "0";
    result += frac;
    result += "\xA0%";
    return result;
  }

  function berechnen(warenwert, laufzeit, mitZahlpause) {
    return berechnenIntern(warenwert, laufzeit, mitZahlpause, ratenrechnerData.regular.aufschlaege[laufzeit], (mitZahlpause ? ratenrechnerData.regular.effektiverJZMitZahlpause[laufzeit] : ratenrechnerData.regular.effektiverJZ[laufzeit]));
  }

  function berechnenSpecial(warenwert, laufzeit, mitZahlpause) {
    return berechnenIntern(warenwert, laufzeit, mitZahlpause, ratenrechnerData.special.aufschlaege[laufzeit], (mitZahlpause ? ratenrechnerData.special.effektiverJZMitZahlpause[laufzeit] : ratenrechnerData.special.effektiverJZ[laufzeit]));
  }

  function berechnenIntern(warenwert, laufzeit, mitZahlpause, aufschlagProMonat, effektiverJZ) {
    warenwert = parseMonetaryAmount(warenwert);
    laufzeit = "" + laufzeit;
    var aufschlag = warenwert * aufschlagProMonat / 10000.0 * Number(laufzeit);
    if (mitZahlpause) {
      aufschlag += warenwert * 0.024;
    }
    aufschlag = Math.round(aufschlag);

    var gesamt = warenwert + aufschlag;
    var rate = Math.round(gesamt / laufzeit / 5.0) * 5;
    var ersteRate = gesamt - (laufzeit - 1) * rate;

    return {
      "aufschlag": formatMonetaryAmount(aufschlag),
      "aufschlagProMonat": formatPercentage(aufschlagProMonat / 100.0),
      "gesamtpreis": formatMonetaryAmount(gesamt),
      "ersteRate": formatMonetaryAmount(ersteRate),
      "rate": formatMonetaryAmount(rate),
      "effektiverJahreszins": effektiverJZ
    };
  }

  return {
    "berechnen": berechnen,
    "berechnenSpecial": berechnenSpecial
  };
}();
