#include "stdafx.h"
#include "Core/GcArray.h"

static void printBitmap(GcArray<Nat> *array) {
	for (size_t i = 0; i < array->count(); i++) {
		PLN(L"Pos " << i << L": " << array->bitmapGet(i));
	}
}

static Nat bitmapSummary(GcArray<Nat> *array) {
	Nat result = 0;
	for (size_t i = 0; i < array->count(); i++) {
		if (array->bitmapGet(i))
			result |= Nat(1) << i;
	}
	return result;
}

BEGIN_TEST(ArrayBitmapTest, Core) {
	Engine &e = gEngine();

	Nat count = 20;
	GcArray<Nat> *bitmapArray = runtime::allocArray<Nat>(e, &natArrayType, count, true);

	// PVAR(storm::fmt::size(bitmapArray));
	// PVAR(storm::fmt::size(runtime::allocArray<Nat>(e, &natArrayType, count)));
	// PVAR(storm::fmt::sizeArrayBitmap(count));

	CHECK(bitmapArray->hasBitmap());
	Bool ok1 = true;
	for (Nat i = 0; i < count; i++) {
		ok1 &= !bitmapArray->bitmapGet(i);
		bitmapArray->bitmapSet(i, true);
	}
	CHECK(ok1);

	Bool ok2 = true;
	for (Nat i = 0; i < count; i++) {
		ok2 &= bitmapArray->bitmapGet(i);
	}
	CHECK(ok2);

	Bool ok3 = true;
	for (Nat i = 0; i < count; i++) {
		ok3 &= arrayBitmapGet(bitmapArray, &natArrayType, i);
		arrayBitmapSet(bitmapArray, &natArrayType, i, false);
	}
	CHECK(ok3);

	Bool ok4 = true;
	for (Nat i = 0; i < count; i++) {
		ok4 &= !arrayBitmapGet(bitmapArray, &natArrayType, i);
	}
	CHECK(ok4);

	arrayBitmapClear(bitmapArray, &natArrayType);
	arrayBitmapSet(bitmapArray, &natArrayType, 2, 4, true);
	// printBitmap(bitmapArray);
	CHECK_EQ(bitmapSummary(bitmapArray), 0x1C);

	arrayBitmapClear(bitmapArray, &natArrayType);
	arrayBitmapSet(bitmapArray, &natArrayType, 3, 10, true);
	// printBitmap(bitmapArray);
	CHECK_EQ(bitmapSummary(bitmapArray), 0x07F8);

	arrayBitmapClear(bitmapArray, &natArrayType);
	arrayBitmapSet(bitmapArray, &natArrayType, 3, 18, true);
	// printBitmap(bitmapArray);
	CHECK_EQ(bitmapSummary(bitmapArray), 0x7FFF8);

} END_TEST
