/*
 * Copyright (c) 2014-2021 by Wen Yu
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License, v. 2.0 are satisfied: GNU General Public License, version 2
 * or any later version.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
 */

package pixy.io;

import java.io.IOException;
import java.io.OutputStream;

/**
 * @author Wen Yu, yuwen_66@yahoo.com
 * @version 1.0 01/29/2013
 */
public class WriteStrategyII implements WriteStrategy {

	private static final WriteStrategyII instance = new WriteStrategyII();	
	 
	public static WriteStrategyII getInstance() 
	{
		return instance;
	}
	 
	private WriteStrategyII(){}
	
	public void writeInt(byte[] buf, int start_idx, int value)
			throws IOException {
		
		byte[] tmp = {(byte)value, (byte)(value>>>8), (byte)(value>>>16), (byte)(value>>>24)};

		System.arraycopy(tmp, 0, buf, start_idx, 4);
	}

	public void writeInt(OutputStream os, int value) throws IOException {
		os.write(new byte[] {
	        (byte)value,
	        (byte)(value>>>8),
	        (byte)(value>>>16),
	        (byte)(value>>>24)});
	}
	
	public void writeLong(byte[] buf, int start_idx, long value)
			throws IOException {
		
		byte[] tmp = {(byte)value, (byte)(value>>>8), (byte)(value>>>16),
		           (byte)(value>>>24), (byte)(value>>>32), (byte)(value>>>40),
			       (byte)(value>>>48), (byte)(value>>>56)};
		
		System.arraycopy(tmp, 0, buf, start_idx, 8);
	}

	public void writeLong(OutputStream os, long value) throws IOException {
		os.write(new byte[] {
	        (byte)value, (byte)(value>>>8),
	        (byte)(value>>>16), (byte)(value>>>24),
	        (byte)(value>>>32), (byte)(value>>>40),
		    (byte)(value>>>48), (byte)(value>>>56)});
	}
	
	public void writeS15Fixed16Number(byte[] buf, int start_idx, float value)
			throws IOException {
		// Check range
		if((value < -32768.0f)||(value >= (32767 + (65535/65536.0f)))||Float.isNaN(value)) {
			throw new IllegalArgumentException(value + " is not a valid S15Fixed16Number");
		}
		
		if(value == 0.0f) {
			writeInt(buf, start_idx, 0);
		}
		else if(value > 0.0f) {
			writeU16Fixed16Number(buf, start_idx, value);
		}
		else {
			int s15 = (int)Math.floor(value);
			int fixed16 = (int)((value - s15)*65536.0f);
			buf[start_idx++] = (byte)s15;
			buf[start_idx++] = (byte)(s15>>>8);
			buf[start_idx++] = (byte)fixed16;
			buf[start_idx] = (byte)(fixed16>>>8);
		}			
	}

	public void writeS15Fixed16Number(OutputStream os, float value) throws IOException {
		// Check range
		if((value < -32768.0f)||(value >= (32767 + (65535/65536.0f)))||Float.isNaN(value)) {
			throw new IllegalArgumentException(value + " is not a valid S15Fixed16Number");
		}
		
		if(value == 0.0f) {
			writeInt(os, 0);
		}
		else if(value > 0.0f) {
			writeU16Fixed16Number(os, value);
		}
		else {
			int s15 = (int)Math.floor(value);
			int fixed16 = (int)((value - s15)*65536.0f);
			
			os.write(new byte[] {
				  (byte)s15,
				  (byte)(s15 >>> 8),
				  (byte)fixed16,
				  (byte)(fixed16>>>8)
				  });
		}
	}
	
	public void writeShort(byte[] buf, int start_idx, int value)
			throws IOException {
		buf[start_idx] = (byte)value;
		buf[start_idx + 1] = (byte)(value>>>8);
	}

	public void writeShort(OutputStream os, int value) throws IOException {
		os.write(new byte[] {
			  (byte)value,
			  (byte)(value >>> 8)
			  });
	}

	public void writeU16Fixed16Number(byte[] buf, int start_idx, float value)
			throws IOException {
		// Check range
		if((value < 0.0f)||(value >= (65535 + (65535/65536.0f)))||Float.isNaN(value)) {
			throw new IllegalArgumentException(value + " is not a valid U16Fixed16Number");
		}
		if(value == 0.0f) {
			writeInt(buf, start_idx, 0);
		}
		else {
			int s15 = (int)value;
			int fixed16 = (int)((value - s15)*65536.0f);
			buf[start_idx++] = (byte)s15;
			buf[start_idx++] = (byte)(s15>>>8);
			buf[start_idx++] = (byte)fixed16;
			buf[start_idx] = (byte)(fixed16>>>8);
		}
	}

	public void writeU16Fixed16Number(OutputStream os, float value) throws IOException {
		// Check range
		if((value < 0.0f)||(value >= (65535 + (65535/65536.0f)))||Float.isNaN(value)) {
			throw new IllegalArgumentException(value + " is not a valid U16Fixed16Number");
		}
		
		if(value == 0.0f) {
			writeInt(os, 0);
		}
		else {
			int s15 = (int)value;
			int fixed16 = (int)((value - s15)*65536.0f);
			
			os.write(new byte[] {
				  (byte)s15,
				  (byte)(s15 >>> 8),
				  (byte)fixed16,
				  (byte)(fixed16>>>8)
				  });
		}
	}

	public void writeU8Fixed8Number(byte[] buf, int start_idx, float value)
			throws IOException {
		// Check range
		if((value < 0.0f)||(value >= (255 + (255/256.0f)))||Float.isNaN(value)) {
			throw new IllegalArgumentException(value + " is not a valid U8ixed8Number");
		}
		if(value == 0.0f) {
			writeShort(buf, start_idx, 0);
		}
		else {
			int u8 = (int)value;
			int fixed8 = (int)((value - u8)*256.0f);
			buf[start_idx++] = (byte)u8;
			buf[start_idx] = (byte)fixed8;
		}
	}

	public void writeU8Fixed8Number(OutputStream os, float value) throws IOException {
		// Check range
		if((value < 0.0f)||(value >= (255 + (255/256.0f)))||Float.isNaN(value)) {
			throw new IllegalArgumentException(value + " is not a valid U8Fixed8Number");
		}
		
		if(value == 0.0f) {
			writeShort(os, 0);
		}
		else {
			int u8 = (int)value;
			int fixed8 = (int)((value - u8)*256.0f);
			
			os.write(new byte[] {
				  (byte)u8,
				  (byte)fixed8
				  });
		}
	}
}
