/**
 * 
 */
package mixconfig.tools.dataretention.smartcard.commands;

import com.sun.javacard.apduio.Apdu;

import mixconfig.tools.dataretention.smartcard.ApduConstants;
import mixconfig.tools.dataretention.smartcard.Helpers;

/**
 * @author christoph
 * 
 */
public class StartDataTransmissionCommand extends AbstractCommand {

	/**
	 * If the value is any higher, it causes a ArrayOutOfBoundsException in
	 * {@link Apdu#getCommandApduBytes()}. Probably due to a cast from signed
	 * integer to signed byte.
	 */
	public static final byte bytesPerStartDataTransmisionCommand = 127;

	/**
	 * @param instructionToPerform
	 *            The
	 * @param data
	 *            The data, which is to be send during the while data
	 *            transmission
	 */
	public StartDataTransmissionCommand(byte instructionToPerform, byte[] data) {
		super();

		this.instruction = ApduConstants.INSTRUCTION_START_DATA_TRANSMISSION;
		this.p1 = instructionToPerform;
		this.p2 = getNumberOfPackages(data.length);
		this.arguments = Helpers.copyOfRange(data, 0, bytesPerStartDataTransmisionCommand);
	}

	/**
	 * Returns the number of needed Commands (StartDataTransmissionCommands and
	 * DataTransmissionCommands) executed to transmit the data.
	 * 
	 * @param numberOfBytesToSend
	 *            - maximal 127*127
	 * @return a positive byte
	 * @throws IllegalArgumentException
	 *             if numbersIfBytesToSend is too big.
	 */
	public static byte getNumberOfPackages(int numberOfBytesToSend) {
		double numberOfDataPackages = (double) numberOfBytesToSend / DataTransmissionCommand.bytesPerDataTransmisionCommand;
		if ((int) numberOfDataPackages != numberOfDataPackages) {
			numberOfDataPackages++;
		}
		numberOfDataPackages = (int) numberOfDataPackages;
		if (numberOfDataPackages == 0) {
			numberOfDataPackages++;
		}
		if (numberOfDataPackages > 127) {
			throw new IllegalArgumentException("numberOfBytesToSend is too big (max 127*255=" + 127 * 256 + ")");
		} else {
			return (byte) numberOfDataPackages;
		}
	}

}
