package speiger.src.coreengine.math;

import speiger.src.coreengine.math.vector.ints.Vec2i;

public class BitUtil
{
	public static long toLong(long firstShort, long secondShort)
	{
		return (firstShort << 32) | (secondShort & 0xFFFFFFFFL);
	}
	
	public static int toFirstInt(long value)
	{
		return (int)((value >> 32) & 0xFFFFFFFFL);
	}
	
	public static int toSecondInt(long value)
	{
		return (int)(value & 0xFFFFFFFFL);
	}
	
	public static long addToLong(long value, long x, long z)
	{
		return ((x + toFirstInt(value)) & 0xFFFFFFFFL) << 32 | (((z + toSecondInt(value)) & 0xFFFFFFFFL));
	}
	
	public static int toInt(int firstShort, int secondShort)
	{
		return (firstShort & 0xFFFF) << 16 | (secondShort & 0xFFFF);
	}
	
	public static int toFirstShort(int value)
	{
		return (short)(value >> 16 & 0xFFFF);
	}
	
	public static int toSecondShort(int value)
	{
		return (short)(value & 0xFFFF);
	}
	
	public static int addToInt(int value, int x, int z)
	{
		return ((x + toFirstShort(value)) & 0xFFFF) << 16 | ((z + toSecondShort(value)) & 0xFFFF);
	}
	
	public static int addToInt(int value, Vec2i offset)
	{
		return ((offset.getX() + toFirstShort(value)) & 0xFFFF) << 16 | ((offset.getY() + toSecondShort(value)) & 0xFFFF);
	}
	
	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);
	}
}
