package gotowe.p29_refleksja.klasy;

public class Konto {
	// final oznacza, że pole numer jest ustawiane w tworzonym obiekcie, a później się nie zmienia 
	private final int numer;
	private int saldo;
	private Osoba wlasciciel;
	
	public Konto(int numer, int saldo, Osoba wlasciciel) {
		if(saldo < 0) {
			throw new IllegalArgumentException("saldo nie może być ujemne");
		}
		if(wlasciciel == null) {
			throw new IllegalArgumentException("właściciel konta nie może być null");
		}
			
		this.numer = numer;
		this.saldo = saldo;
		this.wlasciciel = wlasciciel;
	}

	// "encapsulation" - "hermetyzacja"
	// Tworząc klasę ukrywamy pola tej klasy jako prywatne
	// i dajemy dostęp tylko w takim zakresie, jak chcemy.
	
	// Tutaj: odczyt wszystkich pól,
	// ale nie dajemy setterów do:
	// - numeru - bo "numer nigdy się nie zmienia"
	// - saldo - bo o zmianie salda decydują operacje biznesowe wykonywane na koncie (wplata/wyplata/przelew)

	public Osoba getWlasciciel() {
		return wlasciciel;
	}

	// Dzięki enkapsujacji mogę też pilnować, aby na zmiennych były wpisane poprawne wartości
	// Np.: nie dopuszczamy wlaściciela null
	// Dzięki wyjątkom mogę nie dopuścić do wykonania operacji, która zepsułaby wartość zmiennej w obiekcie
	public void setWlasciciel(Osoba wlasciciel) {
		if(wlasciciel == null) {
			throw new IllegalArgumentException("właściciel konta nie może być null");
		}
		this.wlasciciel = wlasciciel;
	}

	public int getNumer() {
		return numer;
	}

	public int getSaldo() {
		return saldo;
	}
	
	public void wplata(int kwota) {
		if(kwota < 0) {
			throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
		}
			
		saldo += kwota;
	}

	public void wyplata(int kwota) throws BrakSrodkow {
		if(kwota < 0) {
			throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
		}
		if(kwota > saldo) {
			throw new BrakSrodkow("Brak środków na koncie nr " + numer);
		}
		
		saldo -= kwota;
	}
	
	public void przelew(int kwota, Konto kontoDocelowe) throws BrakSrodkow {
		if(kwota < 0) {
			throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
		}
		if(kwota > this.saldo) {
			throw new BrakSrodkow("Brak środków na koncie nr " + numer);
		}
		
		this.saldo -= kwota;
		kontoDocelowe.saldo += kwota;
		// Obiekt ma dostęp do zmiennych prywatnych innych obiektów tej samej klasy
	}
	
	public String toString() {
		return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;			
	}
	
}
