/*
 * Aufgabe 18:
 * 
 * Ausnahme bei falscher ISBN
 */
class FalscheIsbnException extends Exception {
	
	public FalscheIsbnException(String text) {
		super(text);
	}
	
}
	
public class Buch extends Printmedium
		  implements Comparable {
	
	/*
	 * Aufgabe 7:
	 *
	 * Jedes Buch hat einen Titel und eine ISBN.
	 * Buecher sollen zudem Autoren, Erscheinungsjahr, einen Zustand
	 * und einen Aufbewahrungsort besitzen (entweder im Regal oder 
	 * ausgeliehen).
	 * 
	 * Alle Variablen sind private, dafür gibt es Getter- und Setter-Methoden.
	 */
	private String autor;
	private String isbn;
	
	// Konstruktoren
	public Buch(String titel, String isbn) 
	throws FalscheIsbnException { 
		this(null, titel, isbn);
	}
	
	public Buch(String autor, String titel, String isbn) 
	throws FalscheIsbnException { 
		this(autor, titel, isbn, 0);
	}
	
	public Buch(String autor, String titel, String isbn, int jahr) 
	throws FalscheIsbnException { 
		
		// setze Instanzvariablen
		this.autor = autor;
		this.titel = titel;
		this.jahr = jahr;
		
		// ISBN-Prüfung vor Setzen der Variable
		if (testISBN(isbn)) 
			this.isbn = isbn;
		else
			throw new FalscheIsbnException("Keine gültige ISBN: "+isbn);
		//	this.isbn = "0 000 00000 0";
		
		// Vorgaben für Zustand und Ort
		zustand = "Neuwertig";
		ort = "Regal";
	}
	
	public void ausleihen(String ort) {
		this.ort = ort;
	}
	
	public void zurueckbekommen() {
		this.ort= "Regal";
		zustand = zustand.equals("Neuwertig") ? "Gebraucht" : "Altpapier";		
	}

	/*
	 * toString() liefert eine formattierte Beschreibung des Objekts
	 * (überschreibt toString() aus der Klasse Object)
	 */
	public String toString() {
		String ausgabe = new String();
		
		if (titel != null)
			ausgabe += "'"+titel+"'";
		if (jahr > 0)
			ausgabe += " ("+jahr+")";
		if (autor != null)
			ausgabe += " von "+autor;
		if (isbn != null)
			ausgabe += ". ISBN "+isbn;
		if (zustand != null)
			ausgabe += ". "+zustand;
		if (ort != null && ort.equals("Regal"))
			ausgabe += ". Steht im Regal";
		else if (ort != null)
			ausgabe += ". An "+ort+" ausgeliehen";
		else 
			ausgabe += ". Standort ist unbekannt";
		return ausgabe + ".";
	}
	
	/*
	 * Test auf Gleichheit : 
	 *   -- zwei Bücher gelten als gleich, wenn sie die gleiche ISN besitzen
	 * (überschreibt equals(Object a) aus der Klasse Object)
	 */
	public boolean equals(Object a) {
		boolean test = false;
		if(a instanceof Buch)
		{
			Buch b = (Buch) a;
			if(this.isbn.equals(b.isbn))
				test = true;
		}
		return test;
	}
	
	// Getter-Methoden
	public String getAutor() {
		return this.autor;
	}
	
	public String getISBN() {
		return this.isbn;
	}
	
	// Setter-Methoden
	public void setAutor(String autor) {
		this.autor = autor;
	}
	
	public void setISBN(String isbn) {
		if(testISBN(isbn))
			this.isbn = isbn;
	}
	
	// Hilfsmethode zum Prüfen von ISBNs
	static public boolean testISBN(String isbn) {
		boolean isISBN = false;
		boolean lengthOK = false;
		if(isbn.length() == 13) {
			isbn = isbn.replaceAll(" ", "");
			if(isbn.length() ==10)
				lengthOK = true;
			else if(isbn.length() == 13)
			{
				isbn = isbn.replaceAll("-","");
				if(isbn.length() ==10)
					lengthOK = true;
			}
		}
		
		if(lengthOK == true){
			int zahl = Integer.parseInt(isbn.substring(0,1)) *10;
			zahl += Integer.parseInt(isbn.substring(1,2)) *9; 
			zahl += Integer.parseInt(isbn.substring(2,3)) *8; 
			zahl += Integer.parseInt(isbn.substring(3,4)) *7; 
			zahl += Integer.parseInt(isbn.substring(4,5)) *6; 
			zahl += Integer.parseInt(isbn.substring(5,6)) *5; 
			zahl += Integer.parseInt(isbn.substring(6,7)) *4; 
			zahl += Integer.parseInt(isbn.substring(7,8)) *3; 
			zahl += Integer.parseInt(isbn.substring(8,9)) *2; 
			if(isbn.endsWith("X"))
				zahl += 10;
			else
				zahl += Integer.parseInt(isbn.substring(9,10)) *1;
			if(zahl % 11 ==0)
				isISBN = true;
		}
		return isISBN;
	}
	
	/*
	 * Aufgabe 15
	 * implementiert compareTo(Object o) aus Comparable
	 * -- vergleicht Bücher zunächst nach Autor, dann Jahr, dann Titel
	 */
	public int compareTo(Object o) {
		
		Buch b;
		if (o instanceof Buch)
			b = (Buch)o;
		else
			return 0;
			
		if (this.autor == null && b.autor == null )
			if (this.titel.compareToIgnoreCase(b.titel) <0)
				return -1;
			else if (this.titel.compareToIgnoreCase(b.titel) == 0)
				return 0;
			else 
				return 1;
		else if (this.autor == null)
			return -1;
		else if (b.autor == null)
			return 1;
 		else if (this.autor.compareTo(b.autor) < 0)
			return -1;
		else if (this.autor.compareTo(b.autor) == 0)
			if (this.jahr < b.jahr)
				return -1;
			else if  (this.jahr == b.jahr)
				if (this.titel.compareTo(b.titel) < 0)
					return -1;
				else if (this.titel.equals(b.titel))
					return 0;
				else 
					return 1;
			else 
				return 1;
		else
			return 1;
		
	}
	
	public static void main(String[] args) {
		
		try {
			Buch buchOhneAutor = new Buch("GNU Emacs - kurz & gut","3-89721-211-0");
			Buch buchMitAutor  = new Buch("Cameron, Debra","GNU Emacs - kurz & gut","3-89721-211-0");
		
			System.out.println(buchOhneAutor);
			System.out.println(buchMitAutor);
		
			buchOhneAutor.ausleihen("Mark");
			System.out.println(buchOhneAutor);
			buchOhneAutor.zurueckbekommen();
			System.out.println(buchOhneAutor);
			buchOhneAutor.ausleihen("Eva");
			buchOhneAutor.zurueckbekommen();
			System.out.println(buchOhneAutor);
		
			if (buchOhneAutor.equals(buchMitAutor))
				System.out.println("Die beiden Exemplare sind Exemplare des selben Buchs.");
		
			Buch buchAwk = new Buch("Robbins, Arnold", "Effective awk Programming", "0-596-00070-7", 1996);
			Buch buchSql = new Buch("Kline, Kevin und Daniel", "SQL in a Nutshell", "1-56592-744-3", 2001);
		
			if (buchAwk.compareTo(buchSql) < 0)
				System.out.println(buchAwk.getTitel()+" gehört vor "+buchSql.getTitel());
			else if (buchAwk.compareTo(buchSql) > 0)
				System.out.println(buchAwk.getTitel()+" gehört hinter "+buchSql.getTitel());
		} catch (FalscheIsbnException e) {
		}
	}
	
}
