#ifndef _bitwise_h
#define _bitwise_h

#include <string.h>
#include <stdint.h>

/* Bit shifting for endianness of 16-bit numbers */
#define LSByte16(x) ((x) & 0xff)
#define MSByte16(x) (((x) >> 8) & 0xff)

/* Build a 16-bit integer out of two bytes */
#define BytesTo16(lsb, msb) (((lsb) & 0xff) | (((msb) & 0xff) << 8))

/* Same for 32bit */
#define IntByte1(x) ((x) & 0xff)
#define IntByte2(x) (((x) >> 8) & 0xff)
#define IntByte3(x) (((x) >> 16) & 0xff)
#define IntByte4(x) (((x) >> 24) & 0xff)

#define BytesToInt(b1, b2, b3, b4) (((b1) & 0xff) | (((b2) << 8) & 0xff) \
		| (((b3) << 16) & 0xff) | (((b4) & 0xff)))

/* Break apart a float. Sadly this is UB, but the "correct" way
 * to do this involves actually implementing
 * IEEE 754 in software to do so
 */
static inline uint8_t FloatByte1(float f)
{
	char arr[4];
	memcpy(arr, &f, 4);
	return arr[0];
}

static inline uint8_t FloatByte2(float f)
{
	char arr[4];
	memcpy(arr, &f, 4);
	return arr[1];
}

static inline uint8_t FloatByte3(float f)
{
	char arr[4];
	memcpy(arr, &f, 4);
	return arr[2];
}

static inline uint8_t FloatByte4(float f)
{
	char arr[4];
	memcpy(arr, &f, 4);
	return arr[3];
}

static inline float BytesToFloat(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
{
	char arr[4];
	arr[0] = b1;
	arr[1] = b2;
	arr[2] = b3;
	arr[3] = b4;

	float f;
	memcpy(&f, arr, 4);
	return f;
}
#endif