package lab2;

import java.io.*;
import librairyMR.*;

/**
 * Classe Inverse du lab2 exercise 2
 * @author martin
Créez une classe Inverse qui contiendra un main qui lira un entier et qui l’affichera divisé en
séquence de chiffres individuels. Par exemple, l’entrée 12345 sera affichée : 1 2 3 4 5 et ensuite de
manière inversée : 5 4 3 2 1. Réfléchissez à la façon la plus simple d’effectuer cette manipulation.
 */
public class Inverse implements Affichable{
	/*properties*/
	private final int [] _seq;

	/*Constructor*/
	/**
	 * private constructor
	 * use static factory
	 * @param seq
	 * @param length
	 */
	private Inverse(final int [] seq, int length){
		//defensive copy, dont trust reference
		_seq = new int[length];
		for (int i=0;i<length;i++)
			_seq[i] = seq[i];
	}

	/*static factory*/
	/**
	 * build object from a int[]
	 * @param seq as int[]
	 * @return Inverse object
	 */
	public static Inverse fromSeq(final int [] seq){
		int [] tmp = new int[seq.length];

		for (int i=0;i<seq.length;i++)
			tmp[seq.length-i-1] = seq[i];

		return new Inverse(tmp, seq.length);
	}

	/**
	 * build object from a int that he will decompose all decimal into sequence
	 * @param val as int
	 * @return Inverse object
	 */
	public static Inverse fromIntToDecompose(int val){
		int [] tmp = new int[9]; 	//en java le int est toujours 32 bits, donc 9 chiffres max
		int length = 0;

		while(val>0){
			tmp[length] = val % 10;	//decimale par decimale
			val = val / 10;			//reduire le nombre transmit
			length = length + 1;    //et augmenter la taille
		}

		return new Inverse(tmp,length);
	}

	/**
	 * build object from another Inverse object
	 * @param s as Inverse
	 * @return Inverse object
	 */
	public static Inverse fromInverseToReverse(final Inverse s){
		return Inverse.fromSeq(s._seq);
	}

	/*getter*/
	/**
	 * return value at given index
	 * @param i as index
	 * @exception ArrayIndexOutOfBoundsException();
	 * @throws if i is bigger than seq size
	 * @return int at given index
	 */
	public int getAt(int i){
		if (i>=_seq.length)
			throw new ArrayIndexOutOfBoundsException();
		return _seq[i];
	}

	/**
	 * give size of the sequence
	 * @return size of the sequence
	 */
	public int getSize(){
		return _seq.length;
	}

	/*method*/
	/**
	 * exercise 3
	 * return sum of all number in sequence
	 * @return sum of all number in sequence
	 */
	public int somme(){
		int sum = 0;
		for (int i=0;i<getSize();i++)
			sum += getAt(i);
		return sum;
	}

	/**
	 * show sequence on screen
	 */
	public void affiche(){
		for (int i=0;i<_seq.length;i++){
			System.out.print(_seq[i]);
			System.out.print(" ");
		}
		System.out.println();
	}

	/*main*/
	public static void main(String [ ] args) throws IOException{
		//initialisation
		Inverse aLenvers = Inverse.fromIntToDecompose(ConsoleIO.getInt()),
				aLendroit = Inverse.fromInverseToReverse(aLenvers);
		//show them
		aLendroit.affiche();
		aLenvers.affiche();
		//show sum (exercise 3)
		System.out.print("somme : ");
		System.out.println(aLendroit.somme());

	}

}
