package vettore_ordinabile;

public abstract class VettoreOrdinabile {
	
	// Variabili di istanza
	private Object[] vettore;		// Vettore dove memorizzare i dati
	private int dimensioneMassima;
	private int dimensioneCorrente;
	
	// Costruttore
	public VettoreOrdinabile(int dimensioneMassima) {
		if (dimensioneMassima < 0) throw new IllegalArgumentException("La dimensione non può essere negativa");
		this.dimensioneMassima = dimensioneMassima;
	}
	
	// FUNZIONI DI ISTANZA
	
	/**
	 * Funzione aggiungi.
	 * Permette di aggiungere un elemento se la dimensione lo permette.
	 */
	public boolean aggiungi(Object elemento) {
		if (elemento != null && dimensioneCorrente < dimensioneMassima) {
			vettore[dimensioneCorrente] = elemento;
			dimensioneCorrente++;
			return true;
		} else return false;
	}
	
	/**
	 * Funzione leggi.
	 * Permette di leggere un elemento ad una determinata posizione.
	 */
	public Object leggi(int indice) {
		if (indice >= 0 && indice < dimensioneCorrente) {
			return vettore[indice];
		} else return null;
	}
	
	/**
	 * Funzione che restituisce la dimensione corrente
	 */
	public int dimensione() {
		return dimensioneCorrente;
	}
	
	/**
	 * Funzione che visualizza l'array
	 */
	public void visualizza() {
		this.ordina();
		for (int i = 0; i < this.dimensioneMassima; i++) {
			System.out.println(leggi(i));
		}
	}
	
	/**
	 * Funzione che ordina l'array
	 */
	public void ordina() {
		for (int i = 0; i < dimensioneCorrente; i++) {
			int minimo = i;
			int j;
			for (j = i+1; j < dimensioneCorrente; j++) {
				if (confronta(vettore[minimo], vettore[j]) > 0) minimo = j;
			}
			Object temp = vettore[minimo];
			vettore[minimo] = vettore[j];
			vettore[j] = temp;
		}
	}
	
	// FUNZIONI ASTRATTE
	
	/**
	 * Funzione che restituisce il valore della comparazione
	 */
	protected abstract int confronta(Object elemento1, Object elemento2);
}
