package grid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import position.Position;

/**
 * Készítsünk egy másik, memóriatakarékos ábrázolást játéktáblára! Hozzuk létre
 * a grid csomagban a nyilvános SparseGrid osztályt, mely szintén kiterjeszti az
 * AbstractGrid osztályt ugyanazzal a típusparaméterrel.
 * @param <T> típussal paraméterezett
 */
public class SparseGrid<T> extends AbstractGrid<T> {

	/**
	 * Vegyünk fel egy rejtett, leképezést tartalmazó adattagot. Az adattag
	 * típusa legyen java.util.Map, amely két típusparamétert vár (a kulcs és a
	 * hozzárendelt érték típusa). Az adattag Position-ről a típusparaméterre
	 * képez le (ezeket kell tehát a Map-nak típusparaméterként megadni).
	 */
	private Map<Position, T> grid;

	/**
	 * Egy konstruktort, mely az egyetlen adattagot inicializáljuk egy üres
	 * leképezéssel (java.util.HashMap).
	 * @param rows paraméterül várja a sorok és oszlopok számát
	 * @param cols ezekkel meghívja a szülőosztály konstruktorát
	 */
	public SparseGrid(int rows, int cols) {
		super(rows, cols);
		grid = new HashMap<>();
	}

	/**
	 * A get metódus. Két eset lehetséges:<ul>
	 * <li>Ha a pozíció a táblán van (isValid), akkor adjuk vissza azt az
	 * elemet, amely a leképezésben a pozícióhoz van rendelve.</li>
	 * <li>Ha a pozíció nincs a táblán, úgy dobjunk IndexOutOfBoundsException-t
	 * a következő paraméterrel: "Invalid position: " melyet a pozíció
	 * követ.</li></ul>
	 * @param p Position-t vár
	 * @return visszaadja az ott tárolt elemet
	 */
	@Override
	public T get(Position p) {
		if (isValid(p)) {
			return grid.get(p);
		} else {
			throw new IndexOutOfBoundsException("Invalid position: " + p);
		}
	}

	/**
	 * A set metódus. Szintén két eset lehetséges:
	 * <ul>
	 * <li>Ha a pozíció a táblán van (isValid), akkor a leképezésben egyszerűen
	 * rendeljük a pozícióhoz a második paramétert.</li>
	 * <li>Ha a pozíció nincs a táblán, akkor dobjunk
	 * IndexOutOfBoundsException-t a következő paraméterrel: "Invalid position:
	 * " melyet a pozíció követ.</li></ul>
	 * @param p egy Position-t
	 * @param t és egy, a típusparaméternek megfelelő objektumot vár paraméterül
	 * @noreturn nincs visszatérési értéke
	 */
	@Override
	public void set(Position p, T t) {
		if (isValid(p)) {
			grid.put(p, t);
		} else {
			throw new IndexOutOfBoundsException("Invalid position: " + p);
		}
	}

}
