//-----------------------------------------------------
// Name, first name: Hoet, Guntran
// Group: 1DAE3
//-----------------------------------------------------

//---------------------------
// Includes
//---------------------------
#include "BlockList.h"

//---------------------------
// Defines
//---------------------------
#define GAME_ENGINE (GameEngine::GetSingleton())
#define ENTITY_LIST	(EntityList::GetSingleton())
#define MARIO		(Mario::GetSingleton())
BlockList* BlockList::m_BlockListPtr=nullptr;
//---------------------------
// Constructor & Destructor
//---------------------------
BlockList::BlockList()
	:m_BmpBlocksPtr(nullptr)
{
	// Bitmap
	m_BmpBlocksPtr = new Bitmap("Resources/Images/Blocks.bmp");
	m_BmpBlocksPtr->SetTransparencyColor(255,0,255);
	//m_BmpBlocksPtr->SetOpacity(.5);		// make them half opac to see where items starts spawning

	// Blocks
	CreateBlocks();
}

BlockList::~BlockList()
{
	// delete bitmap
	delete m_BmpBlocksPtr;
	m_BmpBlocksPtr = nullptr;

	// delete all blocks
	for (int i = 0; i < NR_OF_BLOCKS; ++i)
	{
		delete m_BlockPtrArr[i];
		m_BlockPtrArr[i] = nullptr;
	}
}

BlockList* BlockList::GetSingleton()
{
	if (m_BlockListPtr == nullptr)
	{
		m_BlockListPtr = new BlockList();
	}
	return m_BlockListPtr;
}

//---------------------------
// Methods - Member functions
//---------------------------

void BlockList::Tick(double deltaTime)
{
	for (int i = 0; i < NR_OF_BLOCKS; ++i)
	{
		m_BlockPtrArr[i]->Tick(deltaTime);
	}
}

void BlockList::Paint(MATRIX3X2 matView)
{
	for (int i = 0; i < NR_OF_BLOCKS; ++i)
	{
		m_BlockPtrArr[i]->Paint(matView);
	}
}

void BlockList::CreateBlocks()
{
	///// info /////
	// block numbers are located on "World1-1_SKETCH.jpg" in the resource folder
	// standard block is BRICK_DEFAULT with a condition (CND) of 1
	// CND value represents the amount of 'head bumps' the block can handle before turning to steel or breaking
	// (depents on previous block state)
	///// info end /////

	int blockSize = 16;
	int upper = 72;		// stands for the upper row of blocks in the world
	int lower = 136;	// stands for the 
	int i = 0;

	// part 1-7	
	m_BlockPtrArr[i++] = new Block(256, lower, m_BmpBlocksPtr, 1);

	m_BlockPtrArr[i++] = new Block(320, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(320+blockSize, lower, m_BmpBlocksPtr, 1, 1, 3);
	m_BlockPtrArr[i++] = new Block(320+2*blockSize, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(320+3*blockSize, lower, m_BmpBlocksPtr, 1);
	m_BlockPtrArr[i++] = new Block(320+4*blockSize, lower, m_BmpBlocksPtr);

	m_BlockPtrArr[i++] = new Block(352, upper, m_BmpBlocksPtr, 1);

	m_BlockPtrArr[i++] = new Block(1016,lower, m_BmpBlocksPtr,4,1,3,1);			// hidden block ...

	// part 8-18
	m_BlockPtrArr[i++] = new Block(1232, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1232+blockSize, lower, m_BmpBlocksPtr, 1,1,3);
	m_BlockPtrArr[i++] = new Block(1232+2*blockSize, lower, m_BmpBlocksPtr);

	m_BlockPtrArr[i++] = new Block(1280, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+2*blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+3*blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+4*blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+5*blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+6*blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1280+7*blockSize, upper, m_BmpBlocksPtr);

	// part 19-29
	m_BlockPtrArr[i++] = new Block(1456, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1456+blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1456+2*blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1456+3*blockSize, upper, m_BmpBlocksPtr, 1);

	m_BlockPtrArr[i++] = new Block(1504, lower, m_BmpBlocksPtr,0,11,1);			// 11 coins out of a normal brick

	m_BlockPtrArr[i++] = new Block(1600, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1600+blockSize, lower, m_BmpBlocksPtr,4,1,4);

	int spacing = 48;
	m_BlockPtrArr[i++] = new Block(1696, lower, m_BmpBlocksPtr, 1);
	m_BlockPtrArr[i++] = new Block(1696+spacing, lower, m_BmpBlocksPtr, 1);
	m_BlockPtrArr[i++] = new Block(1696+2*spacing, lower, m_BmpBlocksPtr, 1);

	m_BlockPtrArr[i++] = new Block(1696+spacing, upper, m_BmpBlocksPtr, 1,1,3);

	// part 30-39
	m_BlockPtrArr[i++] = new Block(1888, lower, m_BmpBlocksPtr);

	m_BlockPtrArr[i++] = new Block(1936, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1936+blockSize, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(1936+2*blockSize, upper, m_BmpBlocksPtr);

	m_BlockPtrArr[i++] = new Block(2064, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(2064+blockSize, lower, m_BmpBlocksPtr);

	m_BlockPtrArr[i++] = new Block(2048, upper, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(2048+blockSize, upper, m_BmpBlocksPtr, 1);
	m_BlockPtrArr[i++] = new Block(2048+2*blockSize, upper, m_BmpBlocksPtr, 1);
	m_BlockPtrArr[i++] = new Block(2048+3*blockSize, upper, m_BmpBlocksPtr);

	// part 40 - 43
	m_BlockPtrArr[i++] = new Block(2688, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(2688+blockSize, lower, m_BmpBlocksPtr);
	m_BlockPtrArr[i++] = new Block(2688+2*blockSize, lower, m_BmpBlocksPtr, 1);
	m_BlockPtrArr[i++] = new Block(2688+3*blockSize, lower, m_BmpBlocksPtr);

}

int BlockList::GetNrOfBlocks()
{
	return NR_OF_BLOCKS;
}

RECT2 BlockList::GetAABBRect(int index)
{
	return m_BlockPtrArr[index]->GetAABBRect();
}

Block *BlockList::GetBlock(int index)
{
	return m_BlockPtrArr[index];
}

void BlockList::BounceUp(int index)
{
	m_BlockPtrArr[index]->BounceUp();

	if (m_BlockPtrArr[index]->GetBlockType() != 3)
	{
		DOUBLE2 pos (m_BlockPtrArr[index]->GetPos().x, m_BlockPtrArr[index]->GetPos().y);
		int item = m_BlockPtrArr[index]->GetItemType();

		// check what state mario is in, so mushrooms and flowers spawn according to the pickup needed to 'power up'
		if ( m_BlockPtrArr[index]->GetMushroomType() == 0 && ( item == 2 || item == 3) )		// change item if the item is a NORMAL mushroom or a flower. (the 1 UP mushroom will be unchanged)
		{
			int state = MARIO->GetFormState();
			if (state == 0)
				item = 3;	// mushroom if mario is small
			else if (state == 1 || state == 2)
				item = 2;	// flower if mario is big or fire
		}

		switch (item)
		{
		case 1:			// coin
			ENTITY_LIST->AddNewEntity(pos, item);
			break;

		case 2:			// flower
			ENTITY_LIST->AddNewEntity(pos, item);
			break;

		case 3:			// mushroom
			ENTITY_LIST->AddNewEntity(pos, item, m_BlockPtrArr[index]->GetMushroomType());
			break;

		case 4:			// star
			ENTITY_LIST->AddNewEntity(pos, item);
			break;

		default:
			break;
		}
	}
}

void BlockList::TakeDamageToCondition(int index)
{
	m_BlockPtrArr[index]->TakeDamageToCondition();
}

void BlockList::PaintHitRegions(MATRIX3X2 matView)
{
	for (int i = 0; i < NR_OF_BLOCKS; ++i)
	{
		m_BlockPtrArr[i]->PaintHitregions(matView);
	}
}

void BlockList::CheckBlockIfDestroyed(int index)
{
	for (int i = 0; i < NR_OF_BLOCKS; ++i)
	{
		m_BlockPtrArr[i]->CheckBlockIfDestroyed();
	}
}

int BlockList::GetBlockType(int index)
{
	return m_BlockPtrArr[index]->GetBlockType();
}

DOUBLE2 BlockList::GetPosition(int index)
{
	return m_BlockPtrArr[index]->GetPos();
}


