package lab2;

import librairyMR.Affichable;

/**
 * class Rectangle (immutable) lab 2 exercise 1
 * @author martin
Ajoutez une méthode surface à la
classe Rectangle qui retournera la valeur de la surface du
rectangle. Ajoutez les getteurs et setteurs nécessaires pour
cette classe, ainsi que la méthode affiche qui affiche la surface.
 */
public class Rectangle implements Affichable{
	/*Properties*/
	private final int _height,
	                  _length;
	/*Constructor*/
	/**
	 * private constructor
	 * plz use static facotry
	 * @param h as int Heigth
	 * @param l as int Length
	 */
	private Rectangle(int h, int l){
		_height = h;
		_length = l;
	}

	/*static factory
	 * permet de mettre des noms significatifs au différent
	 * constructeur, egalement permet d'optimiser certaines
	 * initialisations redondantes en tirant avantage des
	 * références*/
	private static Rectangle _null = new Rectangle(0,0);

	/**
	 * build object from height and length
	 * @param h as height
	 * @param l as length
	 * @return new SurfaceTest
	 */
	public static Rectangle fromHeightLength(int h, int l){
		if (h==0 && l==0)
			return _null;
		return new Rectangle(h,l);
	}

	/**
	 * build object from another surface with new heigth
	 * @param h as height
	 * @param l as length
	 * @return new SurfaceTest
	 */
	public static Rectangle fromHeightAndRect(int h, final Rectangle s){
		return Rectangle.fromHeightLength(h,s.length());
	}

	/**
	 * build object from another surface with new length
	 * @param h as height
	 * @param l as length
	 * @return new SurfaceTest
	 */
	public static Rectangle fromLengthAndRect(int l, final Rectangle s){
		return Rectangle.fromHeightLength(s.height(), l);
	}

	/*getter*/
	/**
	 * @return heigth of the surface
	 */
	public int height(){
		return _height;
	}

	/**
	 * @return length of the surface
	 */
	public int length(){
		return _length;
	}

	/*method*/
	/**
	 * @return area of the surface
	 */
	public int surface(){
		return _height * _length;
	}

	/*immutator (like setter but for immutable class)*/
	/**
	 * change the height
	 * @param h as heigth
	 * @return new surface with given heigth and current length
	 */
	Rectangle withHeight(int h){
		return Rectangle.fromHeightAndRect(h, this);
	}

	/**
	 * change the length
	 * @param l as length
	 * @return new surface with given length and current heigth
	 */
	Rectangle withLength(int l){
		return Rectangle.fromLengthAndRect(l, this);
	}

	/**
	 * show on console the height, length and the surface
	 */
	public void affiche(){
		System.out.print(_height);
		System.out.print(" x ");
		System.out.print(_length);
		System.out.print(" = ");
		System.out.println(surface());
	}
}
