public class StudenteTypeSafe extends StudenteBase implements Comparable<StudenteTypeSafe>{

	public StudenteTypeSafe(String string) {
		super(string);
	}

	/**
	 * Confronta l'oggetto di invocazione con l'oggetto passato come parametro.
	 * Ritorna un intero negativo/positivo/nullo se l'oggetto di invocazione e' 
	 * minore/maggiore/uguale di o 
	 * <p>
	 * Uno studente s1 e': 
	 * minore di s2 se s1.media < s2.media
	 * maggiore di s2 se s1.media > s2.media
	 * <p>
	 * Se s1.media==s2.media: s1 < s2 se s1.matricola < s2.matricola, e s1 > s2 se s1.matricola > s2.matricola
	 * L'ordine tra le matricole e' quello lessicografico. 
	 * Due studenti sono uguali se hanno stessa media stessa mtaricola.
	 * 	
	 * @param o l'oggetto con cui voglio confrontare l'oggetto di invocazione
	 * @retrun un intero negativo/positivo/nullo se l'oggetto di invocazione e' 
	 * minore/maggiore/uguale di o 
	 * */	
	public int compareTo(StudenteTypeSafe s) {
			if (getMedia() == s.getMedia()){
				return getMatricola().compareTo(s.getMatricola());
			}
			return (getMedia() > s.getMedia())?1:-1;
	}

	
	@Override
	public String toString() {
		return "[mat: "+getMatricola()+" media :"+getMedia()+"]";
	}

	/**
	 * Confronta le informazioni rilevanti per l'oggetto di invocazione con 
	 * l'oggetto passato come parametro.
	 * Ritorna true se tali informazioni sono uguali, false altrimenti
	 * <p>
	 * Due studenti sono considerati uguali se hanno la stessa matricola e la stessa media
	 * NOTA: questa implementazione non usa un parametro di tipo Object ed il downcast ma un parametro StudenteTypeSafe. Se all'equals viene passato un oggetto diverso da StudenteTypeSafe non viene chiamato questo equals ma quello delle classi superori (al limite quello di Object).
	 * 
	 * @param obj l'oggetto con cui voglio verificare l'uguaglianza dell'oggetto di invocazione
	 * @retrun true se obj e' di tipo Studente e se le informazioni rilevanti per 
	 * obj e per l'oggetto di invocazione sono uguali. 
	 * */	
	public boolean equals(StudenteTypeSafe s) {
			System.out.println("StudenteTypeSafe::equals");
			return (getMedia()==s.getMedia() && getMatricola().equals(s.getMatricola())); 
	}

/**
	implementazione equals "standard" (prende come prametro un oggetto generico)
*/
/*	public boolean equals(Object obj) {
		if (obj instanceof StudenteBase) {
			StudenteBase s = (StudenteBase) obj;
			return (getMedia()==s.getMedia() && getMatricola().equals(s.getMatricola())); 
		}
		return false;
	}
*/

	public static void main(String[] args) {
		StudenteTypeSafe s1 = new StudenteTypeSafe(new String("VR0001"));
		StudenteTypeSafe s2 = new StudenteTypeSafe(new String("VR0001"));

		//test equals
		System.out.println("**********TEST EQUALS*************"); 
		System.out.println("Studente s1 = "+s1); 
		System.out.println("Studente s2 = "+s2); 

		System.out.println("s1 == s2 : "+(s1==s2)); 
		System.out.println("s1.equals(s2) : "+(s1.equals(s2))); 

		System.out.println("equals tra oggetti diversi s1.equals(ciao) : "+(s1.equals("ciao"))); 

		
		s1 = s2;
		
		System.out.println("Studente s1 = "+s1); 
		System.out.println("Studente s2 = "+s2); 
		System.out.println("s1 == s2 : "+(s1==s2));
		System.out.println("s1.equals(s2) : "+(s1.equals(s2)));		
		
		
		//test massimo 
		System.out.println("**********TEST MASSIMO STUDENTI (classe UtilComparable)*************"); 
		StudenteTypeSafe s3 = new StudenteTypeSafe("VR0003");
		s1.setMedia(30);
		s3.setMedia(30);
		System.out.println("Studente s1 = "+s1); 
		System.out.println("Studente s3 = "+s3); 
		StudenteTypeSafe m = (StudenteTypeSafe) UtilComparable.massimo(s1,s3);
		System.out.println("massimo tra s1 ed s3 = "+m);
			
	}


}
