/**
 *
 * Programmieraufgabe P-8 (Darlehen.java)
 *
 * @author Leonhard Fellermayr
 * @version 1.0
 */

/** Implementierung der Klasse Darlehen */

public class Darlehen {

	/** INSTANZVARIABLEN **/

	/**
	  *  Benštigte "magische Grš§en":
	  *  PERCENT_100 = Volle Prozentzahl
	  *  MONTH_COUNT = Anzahl Monate pro Jahr
	  *
	  */

	final int PERCENT_100 = 100;
	final int MONTH_COUNT = 12;

	/**
	  *  B = Darlehensbetrag
	  *  J = Effektiver Jahreszinssatz
	  *  T = AnfŠngliche Tilgungsrate
	  *  M = Monatlicher Zinssatz (wird durch calcMonatlichenZinssatz () berechnet)
	  *  R = Monatliche Tilgungsrate (wird durch calcMonatlicheRate () berechnet)
	  *  restschuld = Momentan noch verbleibende Restschuld. AnfŠnglich restschuld = B.
	  *  bankzinsen = Hier werden die an die Bank gezahlten Kreditzinsen aufaddiert. AnfŠnglich 0.
	  *
	  */

	private double B, J, T, M, R;
	private double restschuld, bankzinsen;

	/** PRIVATE-METHODEN **/

	/** calcMonatlichenZinssatz () - Monatlichen Zinssatz M gemŠ§ Formel berechnen.
	  *
	  * @return Monatlicher Zinssatz M (double)
	  *
	  */

	private double calcMonatlichenZinssatz () {

		return (PERCENT_100 * (Math.pow (1.0 + (this.J / PERCENT_100), 1.0 / MONTH_COUNT) - 1.0));

	}

	/** calcMonatlicheRate () - Monatliche Tilgungsrate R gemŠ§ Formel berechnen.
	  *
	  * @return Monatliche Tilgungsrate R (double)
	  *
	  */

	private double calcMonatlicheRate () {

		return (this.B * (1.0 / PERCENT_100) * (this.M + T / MONTH_COUNT));

	}

	/** PUBLIC-METHODEN **/

	/** getMonatlicheRate () - Gibt die monatliche Tilgungsrate R zurŸck.
	  *
	  * @return Monatliche Tilgungsrate R (double)
	  *
	  */

	public double getMonatlicheRate () {

		return (this.R);

	}

	/** getRestschuld () - Gibt die verbleibende Restschuld zurŸck.
	  *
	  * @return Verbleibende Restschuld (double)
	  *
	  */

	public double getRestschuld () {

		return (this.restschuld);

	}

	/** tilgeXMonate () - Simuliert eine monatliche Tilgung Ÿber X Monate.
	  *
	  * @param recursionCounter Anzahl Monate, Ÿber welche die Tilgung erfolgen soll.
	  * @return void
	  *
	  */

	public void tilgeXMonate (int recursionCounter) {

		double bz = (this.M / PERCENT_100) * this.restschuld;

		/* Bankzinsen */
		this.bankzinsen += bz;

		/* Tilgen */
		this.restschuld -= this.R - bz;

		/* Rekursion statt for-Schleife */
		if (recursionCounter > 1)
			tilgeXMonate (--recursionCounter);

	}

	/** tilgeMonat () - Simuliere Tilgung Ÿber 1 Monat via tilgeXMonate ()
	  *
	  * @return void
	  *
	  */

	public void tilgeMonat () {

		tilgeXMonate (1);

	}

	/** tilgeJahr () - Simuliere Tilgung Ÿber 1 Jahr (= 12 Monate) via tilgeXMonate ()
	  *
	  * @return void
	  *
	  */

	public void tilgeJahr () {

		tilgeXMonate (MONTH_COUNT);

	}

	/** getLaufzeit () - Gibt die Laufzeit des AnnuitŠtendarlehens in Monaten zurŸck.
	  * Benštigt fŸr die Berechnung der Skalierung im Applet.
	  *
	  * @return Laufzeit des Darlehens in Monaten
	  *
	  */

	public int getLaufzeit () {

		double kreditBetrag = this.B;
		int i = 0;

		/* Tilge komplettes Darlehen */

		while (kreditBetrag > 0) {
			kreditBetrag -= this.R - (this.M / PERCENT_100) * kreditBetrag;
			i++;
		}

		return (i);

	}


	/** KONSTRUKTOR der Klasse Darlehen **/

	/** @param B Angeforderter Darlehensbetrag
	  * @param J Effektiver Jahreszinssatz
	  * @param T AnfŠngliche Tilgungsrate
	  *
	  */

	public Darlehen (double B, double J, double T) {

		/** Eingabewerte Ÿbernehmen */

		this.B = B;
		this.J = J;
		this.T = T;

		/** Monatlichen Zinssatz und monatliche Tilgungsrate Ÿber die private-Methoden berechnen */

		this.M = calcMonatlichenZinssatz ();
		this.R = calcMonatlicheRate ();

		/** Die Restschuld entspricht zu Beginn dem Darlehensbetrag */

		this.restschuld = this.B;

		/** In bankzinsen werden die an die Bank gezahlten Kreditzinsen aufaddiert (Feature) */

		this.bankzinsen = 0;

	}

}
