package speiger.src.coreengine.math.bits;

public class BitUtil {
	public static long toLong(long key, long value) {
		return (key << 32L) | (value & 0xFFFFFFFFL);
	}
	
	public static int intKey(long value) {
		return (int)((value >> 32) & 0xFFFFFFFFL);
	}
	
	public static int intValue(long value) {
		return (int)(value & 0xFFFFFFFFL);		
	}
		
	public static long intAdd(long source, long key, long value) {
		return toLong(key + intKey(source), value + intValue(source));
	}
	
	public static int toInt(int key, int value) {
		return (key & 0xFFFF) << 16 | (value & 0xFFFF);
	}
	
	public static int shortKey(int value) {
		return (short)(value >> 16 & 0xFFFF);
	}
	
	public static int shortValue(int value) {
		return (short)(value & 0xFFFF);
	}
	
	public static int shortAdd(int source, int key, int value) {
		return toInt(key + shortKey(source), value + shortValue(source));
	}
	
	public static int pack_2_10_10_10_int_rev(float x, float y, float z, float w) {
		return (Math.round(w * 3F) & 3) << 30 | (Math.round(((z * 0.5F) + 0.5F) * 1023F) & 1023) << 20 | (Math.round(((y * 0.5F) + 0.5F) * 1023F) & 1023) << 10 | (Math.round(((x * 0.5F) + 0.5F) * 1023F) & 1023);
	}
	
	public static int pack_10_10_10_2_int(float x, float y, float z, float w) {
		return (Math.round(((x * 0.5F) + 0.5F) * 1023F) & 1023) << 22 | (Math.round(((y * 0.5F) + 0.5F) * 1023F) & 1023) << 12 | (Math.round(((z * 0.5F) + 0.5F) * 1023F) & 1023) << 2 | (Math.round(w * 3F) & 3);
	}
}
