// Project Lab - NHTV IGAD
//////////////////////////////////////////
// Author: Yoshi van Belkom - 130118
//////////////////////////////////////////
// A Map of Hexagons with a static width and height.
//////////////////////////////////////////

#pragma once

#include "Engine/EngineTypes.h"
#include "HexMap.generated.h"

USTRUCT()
struct FHexMap
{
	GENERATED_BODY()
protected:
	//Get bit at position.
	bool GetBit( uint16 a_byte, int32 a_pos )
	{
		return ( a_byte >> a_pos ) & 0x1;
	}
	//Set bit at position.
	uint16 SetBit( uint16 a_byte, int32 a_pos, bool a_bit )
	{
		if ( a_bit )
			a_byte |= 1 << a_pos;
		else
			a_byte &= ~( 1 << a_pos );
		return a_byte;
	}
	//True if i is odd.
	bool IsOdd( uint16 a_i )
	{
		return ( a_i % 2 != 0 );
	}

	//Returns true if x and y are valid positions on the map.
	virtual bool IsPointValid( int32 a_x, int32 a_y )
	{
		bool result = !( a_x < 0 || a_x >= 13 || a_y < 0 || a_y >= 16 );
		if ( result && IsOdd( a_x ) )
			result = ( a_y < ( 15 ) );
		return result;
	}
public:
	UPROPERTY()
	uint16 rawdata[13];

	//Get the state of a hex at given position. Returns false if position is not valid.
	bool Get( int32 a_x, int32 a_y )
	{
		if ( !IsPointValid( a_x, a_y ) ) return false;
		return GetBit( rawdata[a_x], a_y );
	}
	//Set the state of a hex at given position.
	void Set( int32 a_x, int32 a_y, bool a_v )
	{
		if ( !IsPointValid( a_x, a_y ) ) return;
		rawdata[a_x] = SetBit( rawdata[a_x], a_y, a_v );
	}
	//Invert the state of a hex at a given position.
	void Invert( int32 a_x, int32 a_y )
	{
		if ( !IsPointValid( a_x, a_y ) ) return;
		unsigned short mask = 1 << a_y;
		rawdata[a_x] ^= mask;
	}

	FHexMap()
	{}

	FHexMap( FHexMap& a_v )
	{
		for ( int i = 0; i < 13; i++ ) rawdata[i] = a_v.rawdata[i];
	}

	virtual ~FHexMap() {}

};
