package projectEQ2440.utils;

/**
 * <b>public class Type</b><br/>
 * Class containing static function to manage the type of the variables
 */
public class Type {
	
	/**
	 * <b>public static byte[] bit2byte(boolean[] bitArray)</b><br/>
	 * Function to transform an array of bit (boolean) into an array of byte (padding at the end)
	 * 
	 * @param bitArray : array of bit to transform
	 * @param begin : where beginning to read in the bit array
	 * @return the array of byte
	 */
	public static byte[] bit2byte(boolean[] bitArray, int begin) {
		int i, j, n = (bitArray.length-begin+7)/8;
		byte[] byteArray = new byte[n];
		
		for (i=0; i<n-1; i++) {
			byteArray[i] = (byte) 0x00;
			for (j=i*8+begin; j<i*8+begin+8; j++) {
				byteArray[i] = (byte) (byteArray[i] << 1);
				if (bitArray[j]) byteArray[i] = (byte) (byteArray[i] | 0x01);
			}
		}
		i = n-1;
		byteArray[i] = (byte) 0x00;
		for (j=8*i+begin; j<bitArray.length; j--) {
			byteArray[i] = (byte) (byteArray[i] << 1);
			if (bitArray[j]) byteArray[i] = (byte) (byteArray[i] | 0x01);
		}
		byteArray[i] = (byte) (byteArray[i] << (8*n-bitArray.length+begin));
		
		return byteArray;
	}

	/**
	 * <b>public static boolean[] byte2bit(byte[] byteArray)</b><br/>
	 * Function to transform an array of byte into an array of bit (boolean)
	 * 
	 * @param byteArray : array of byte to transform
	 * @param begin : where begin to write in the bit array
	 * @return the array of bit (boolean)
	 */
	public static boolean[] byte2bit(byte[] byteArray, int begin) {
		int i, j, a, n = byteArray.length*8+begin;
		boolean[] bitArray = new boolean[n];
		
		for (i=0; i<byteArray.length; i++) {
			a = 1;
			for (j=i*8+7+begin; j>=i*8+begin; j--) {
				bitArray[j] = (byteArray[i] & a) == a;
				a <<= 1;
			}
		}
		
		return bitArray;
	}
	
	/**
	 * <b>public static byte[] padding(byte[] code, int paddLeft, int length)</b><br/>
	 * make a left padding of bite on an array of byte to put information at the begining and padding also at the end
	 * 
	 * @param code : the byte array to pad
	 * @param paddLeft : the size of padding in number of bit
	 * @param length : the total final length
	 * @return the new byte array
	 */
	public static byte[] padding(byte[] code, int paddLeft, int length) {
		int k, m = (paddLeft+7)/8, r = paddLeft%8;
		int n = code.length + m;
		int tmp;
		if (n>length) return null;
		byte[] result = new byte[length];
		
		
		if (r == 0) 
			for (k=0; k<code.length; k++) 
				result[k+m] = code[k];
		else {
			result[m-1] = (byte) ((code[0] & 0xFF) >>> r);
			for (k=1; k<code.length; k++) {
				tmp = (code[k] & 0xFF) >>> r;
				result[m+k-1] = (byte) tmp;
				result[m+k-1] = (byte) (((code[k-1] & 0xFF) << (8-r)) & tmp);
			}
			result[m+code.length-1] = (byte) ((code[code.length-1] & 0xFF) << (8-r)); 
		}
		
		
		return result;
	}
	
	
}
