package projectEQ2440.QRcode.ReedSolomon;

import projectEQ2440.QRcode.ReedSolomon.GaloisField.*;

/**
 * <b>public class RSencoder</b><br/>
 * The Reed-Solomon Encoder
 */
public class RSencoder {
	
	private int nbr_err_corr_word;
	
	private Galois[] polynom_generator;
	
	/**
	 * <b>public RSencoder(int necw)</b><br/>
	 * Constructor
	 * 
	 * @param necw : Number of error codeblocks 
	 */
	public RSencoder(int necw) {
		nbr_err_corr_word = necw;
		generate_polynom_generator();
	}
	
	/**
	 * <b>private void generate_polynom_generator()</b><br/>
	 * Generation of the polynom generator using the classes Polynom & Galois
	 */
	private void generate_polynom_generator() {
		polynom_generator = Polynom.zeros(nbr_err_corr_word+1);
		Galois[] tmp = Polynom.zeros(nbr_err_corr_word+1);
		
		polynom_generator[0] = new Galois((byte) 0x01);
		int k;
		for (k=0; k<=nbr_err_corr_word-1; k++) {
			Polynom.copy(tmp, polynom_generator, k+1);
			Polynom.addSS(polynom_generator, tmp, Galois.pow(k), -1, k+1);
		}
	}
	
	/**
	 * <b>public Galois[] polynom_generator()</b><br/>
	 * Return the polynom generator
	 * 
	 * @return The polynom generator
	 */
	public Galois[] polynom_generator() {
		return polynom_generator;
	}
	
	/**
	 * <b>public byte[] encode(byte[] message)</b><br/>
	 * Apply the Reed-Solomon encoding and return the encoded message
	 * 
	 * @param message : message to encode
	 * @return The encoded message, prefix included
	 */
	public byte[] encode(byte[] message) {
		return encode(message, 0, -1);
	}

	/**
	 * <b>public byte[] encode(byte[] message, int start, int length)</b><br/>
	 * Apply the Reed-Solomon on the message starting at start and with the assign length (until the end if length too big)
	 * 
	 * @param message : message to encode
	 * @param start : starting point
	 * @param length : the length of the reading (-1 to read to the end)
	 * @return The encoded message, prefix included
	 */
	public byte[] encode(byte[] message, int start, int length) {
		if (length < 0 || length > message.length-start) length = message.length-start;
		
		Galois[] msg_ready = Polynom.byte2gal(message,start,length,nbr_err_corr_word);
		Polynom.rest_OP(msg_ready, polynom_generator);
		
		byte[] msg_end = Polynom.gal2byte(msg_ready);
		int k;
		for (k=0; k<length; k++) {
			msg_end[k] = message[k+start];
		}
		
		return msg_end;
	}
}
