/* ----------------------------------------
 * Origin  : GFI INFORMATIQUE 
 * Project : CDPP Propagation Tool 
 * ----------------------------------------
 * History 
 * Version : 06/11/2017 : SCA : V2.2.1 
 *  Redmine #5403 - DMPT3 - create 
 * ----------------------------------------
 */
package fr.tlse.irap.map;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

import jakarta.xml.bind.annotation.adapters.XmlAdapter;

public class FitsFloatAdapter extends XmlAdapter<byte[], float[]> {

	@Override
	public byte[] marshal(float[] fData) throws Exception {
		System.out.println("Start Marshalling "+new Date());
		// convert float array to byte array
		byte[] data = new byte[fData.length*4];
		int i = 0;
		for (float f : fData) {
			byte[] bytes = ByteBuffer.allocate(4).putFloat(f).array();
			for (byte b : bytes) {
				data[i++] = b;
			}
//			if (i > 4000000 && i <= 4000040) {
//				System.out.println("fData["+((i-4)/4)+"]="+f+" => data["+(i-4)+".."+(i-1)+"]="+data[(i-4)]+", "+data[(i-3)]+", "+data[(i-2)]+", "+data[(i-1)]);
//			}
		}
		Deflater deflater = new Deflater();  
		deflater.setInput(data);  

		ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);   

		deflater.finish();  
		byte[] buffer = new byte[1024];   
		while (!deflater.finished()) {  
			int count = deflater.deflate(buffer); // returns the generated code... index  
			outputStream.write(buffer, 0, count);   
		}  
		outputStream.close();  
		byte[] output = outputStream.toByteArray();  

		deflater.end();

		System.out.println("Original: " + data.length / 1024 + " Kb");  
		System.out.println("Compressed: " + output.length / 1024 + " Kb");  
		System.out.println("End Marshalling "+new Date());  
		return output;  		
	}

	@Override
	public float[] unmarshal(byte[] data) throws Exception {
		System.out.println("Start UnMarshalling "+new Date());
		
		Inflater inflater = new Inflater();   
		inflater.setInput(data);  

		ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);  
		byte[] buffer = new byte[1024];  
		while (!inflater.finished()) {  
			int count = inflater.inflate(buffer);  
			outputStream.write(buffer, 0, count);  
		}  
		outputStream.close();  
		byte[] bo = outputStream.toByteArray();  

		inflater.end();

		System.out.println("Original: " + data.length  / 1024 + " Kb");  
		System.out.println("Uncompressed: " + bo.length  / 1024 + " Kb");  

		// convert byte array to float array
		float[] output = new float[bo.length/4];
		for (int i=0; i<bo.length/4; i++) {
			int j = i*4;
			byte[] b = new byte[]{bo[j], bo[j+1], bo[j+2], bo[j+3]};
			output[i] =  ByteBuffer.wrap(b).getFloat();
//			if (i >= 1000000 && i < 1000010) {
//				System.out.println("bOut["+j+".."+(j+3)+"]="+bo[j]+", "+bo[(j+1)]+", "+bo[(j+2)]+", "+bo[(j+3)]+" => fOut["+i+"]="+output[i]);
//			}
		}
		System.out.println("End UnMarshalling "+new Date());  
		return output;  
	}

}
