#include "balloon_formations.h"
#include "balloon.h" // Para BALLOON_VELX_NEGATIVE, BALLOON_VELX_POSITIVE
#include "param.h"	 // Para param
#include "utils.h"	 // Para ParamGame, Param, Zone, BLOCK

void BalloonFormations::initBalloonFormations()
{
	constexpr int y4 = -BLOCK;
	const int x4_0 = param.game.play_area.rect.x;
	const int x4_100 = param.game.play_area.rect.w - BALLOON_SIZE[3];

	constexpr int y3 = -BLOCK;
	const int x3_0 = param.game.play_area.rect.x;
	const int x3_100 = param.game.play_area.rect.w - BALLOON_SIZE[2];

	constexpr int y2 = -BLOCK;
	const int x2_0 = param.game.play_area.rect.x;
	const int x2_100 = param.game.play_area.rect.w - BALLOON_SIZE[1];

	constexpr int y1 = -BLOCK;
	const int x1_0 = param.game.play_area.rect.x;
	const int x1_50 = param.game.play_area.center_x - (BALLOON_SIZE[0] / 2);
	const int x1_100 = param.game.play_area.rect.w - BALLOON_SIZE[0];

	balloon_formation_.reserve(NUMBER_OF_BALLOON_FORMATIONS);

	constexpr int CREATION_TIME = 300;

	// #00 - Dos enemigos BALLOON4 uno a cada extremo
	{
		std::vector<BalloonFormationParams> init_params = {
			BalloonFormationParams(x4_0, y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME),
			BalloonFormationParams(x4_100, y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME)};
		balloon_formation_.emplace_back(2, init_params);
	}

	// #01 - Dos enemigos BALLOON4 uno a cada cuarto. Ambos van hacia el centro
	{
		std::vector<BalloonFormationParams> init_params = {
			BalloonFormationParams(param.game.play_area.first_quarter_x - (BALLOON_SIZE[3] / 2), y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME),
			BalloonFormationParams(param.game.play_area.third_quarter_x - (BALLOON_SIZE[3] / 2), y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME)};
		balloon_formation_.emplace_back(2, init_params);
	}

	// #02 - Cuatro enemigos BALLOON2 uno detrás del otro. A la izquierda y hacia el centro
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 4; ++i)
		{
			init_params.emplace_back(x2_0 + (i * (BALLOON_SIZE[1] + 1)), y2, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE2, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(4, init_params);
	}

	// #03 - Cuatro enemigos BALLOON2 uno detrás del otro. A la derecha y hacia el centro
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 4; ++i)
		{
			init_params.emplace_back(x2_100 - (i * (BALLOON_SIZE[1] + 1)), y2, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE2, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(4, init_params);
	}

	// #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 3; ++i)
		{
			init_params.emplace_back(x3_0 + (i * (BALLOON_SIZE[2] * 2)), y3, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(3, init_params);
	}

	// #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 3; ++i)
		{
			init_params.emplace_back(x3_100 - (i * (BALLOON_SIZE[2] * 2)), y3, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(3, init_params);
	}

	// #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 3; ++i)
		{
			init_params.emplace_back(x3_0 + (i * (BALLOON_SIZE[2] + 1)), y3, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(3, init_params);
	}

	// #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 3; ++i)
		{
			init_params.emplace_back(x3_100 - (i * (BALLOON_SIZE[2] + 1)), y3, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(3, init_params);
	}

	// #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 6; ++i)
		{
			init_params.emplace_back(x1_0 + (i * (BALLOON_SIZE[0] + 1)), y1, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(6, init_params);
	}

	// #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 6; ++i)
		{
			init_params.emplace_back(x1_100 - (i * (BALLOON_SIZE[0] + 1)), y1, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(6, init_params);
	}

	// #10 - Tres enemigos BALLOON4 seguidos desde la izquierda. Hacia la derecha
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 3; ++i)
		{
			init_params.emplace_back(x4_0 + (i * (BALLOON_SIZE[3] + 1)), y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME - (15 * i));
		}
		balloon_formation_.emplace_back(3, init_params);
	}

	// #11 - Tres enemigos BALLOON4 seguidos desde la derecha. Hacia la izquierda
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 3; ++i)
		{
			init_params.emplace_back(x4_100 - (i * (BALLOON_SIZE[3] + 1)), y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME - (15 * i));
		}
		balloon_formation_.emplace_back(3, init_params);
	}

	// #12 - Seis enemigos BALLOON2 uno detrás del otro. A la izquierda y hacia el centro
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 6; ++i)
		{
			init_params.emplace_back(x2_0 + (i * (BALLOON_SIZE[1] + 1)), y2, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE2, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(6, init_params);
	}

	// #13 - Seis enemigos BALLOON2 uno detrás del otro. A la derecha y hacia el centro
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 6; ++i)
		{
			init_params.emplace_back(x2_100 - (i * (BALLOON_SIZE[1] + 1)), y2, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE2, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(6, init_params);
	}

	// #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 5; ++i)
		{
			init_params.emplace_back(x3_0 + (i * (BALLOON_SIZE[2] * 2)), y3, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(5, init_params);
	}

	// #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 5; ++i)
		{
			init_params.emplace_back(x3_100 - (i * (BALLOON_SIZE[2] * 2)), y3, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(5, init_params);
	}

	// #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 5; ++i)
		{
			init_params.emplace_back(x3_0 + (i * (BALLOON_SIZE[2] + 1)), y3, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(5, init_params);
	}

	// #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 5; ++i)
		{
			init_params.emplace_back(x3_100 - (i * (BALLOON_SIZE[2] + 1)), y3, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(5, init_params);
	}

	// #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 12; ++i)
		{
			init_params.emplace_back(x1_0 + (i * (BALLOON_SIZE[0] + 1)), y1, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(12, init_params);
	}

	// #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < 12; ++i)
		{
			init_params.emplace_back(x1_100 - (i * (BALLOON_SIZE[0] + 1)), y1, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME - (10 * i));
		}
		balloon_formation_.emplace_back(12, init_params);
	}

	// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 4 / 2;
		for (int i = 0; i < 4; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x4_0 + (i * (BALLOON_SIZE[3] + 1)), y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME + (0 * i));
			}
			else
			{
				init_params.emplace_back(x4_100 - ((i - half) * (BALLOON_SIZE[3] + 1)), y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME + (0 * i));
			}
		}
		balloon_formation_.emplace_back(4, init_params);
	}

	// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 4 / 2;
		for (int i = 0; i < 4; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x4_0 + (i * (BALLOON_SIZE[3] + 1)), y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME + (0 * i));
			}
			else
			{
				init_params.emplace_back(x4_100 - ((i - half) * (BALLOON_SIZE[3] + 1)), y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME + (0 * i));
			}
		}
		balloon_formation_.emplace_back(4, init_params);
	}

	// #21 - Diez enemigos BALLOON2 uno detrás del otro. Izquierda/derecha. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 10 / 2;
		for (int i = 0; i < 10; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x2_0 + (i * (BALLOON_SIZE[1] + 1)), y2, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE2, CREATION_TIME - (3 * i));
			}
			else
			{
				init_params.emplace_back(x2_100 - ((i - half) * (BALLOON_SIZE[1] + 1)), y2, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE2, CREATION_TIME - (3 * (i - half)));
			}
		}
		balloon_formation_.emplace_back(10, init_params);
	}

	// #22 - Diez enemigos BALLOON3. Hacia la derecha/izquierda. Separados. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 10 / 2;
		for (int i = 0; i < 10; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x3_0 + (i * (BALLOON_SIZE[2] * 2)), y3, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
			}
			else
			{
				init_params.emplace_back(x3_100 - ((i - half) * (BALLOON_SIZE[2] * 2)), y3, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * (i - half)));
			}
		}
		balloon_formation_.emplace_back(10, init_params);
	}

	// #23 - Diez enemigos BALLOON3. Hacia la derecha. Juntos. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 10 / 2;
		for (int i = 0; i < 10; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x3_0 + (i * (BALLOON_SIZE[2] + 1)), y3, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * i));
			}
			else
			{
				init_params.emplace_back(x3_100 - ((i - half) * (BALLOON_SIZE[2] + 1)), y3, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE3, CREATION_TIME - (10 * (i - half)));
			}
		}
		balloon_formation_.emplace_back(10, init_params);
	}

	// #24 - Treinta enemigos BALLOON1. Del centro hacia los extremos. Juntos. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 30 / 2;
		for (int i = 0; i < 30; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x1_50, y1, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME + (5 * i));
			}
			else
			{
				init_params.emplace_back(x1_50, y1, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME + (5 * (i - half)));
			}
		}
		balloon_formation_.emplace_back(30, init_params);
	}

	// #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simétricos
	{
		std::vector<BalloonFormationParams> init_params;
		const int half = 30 / 2;
		for (int i = 0; i < 30; ++i)
		{
			if (i < half)
			{
				init_params.emplace_back(x1_50 + 20, y1, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME - (5 * i));
			}
			else
			{
				init_params.emplace_back(x1_50 - 20, y1, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE1, CREATION_TIME - (5 * (i - half)));
			}
		}
		balloon_formation_.emplace_back(30, init_params);
	}

	// Reservar espacio para el vector
	balloon_formation_.resize(100);

	// Crea las mismas formaciones pero con hexágonos a partir de la posición 50 del vector
	for (int k = 0; k < 50; k++)
	{
		std::vector<BalloonFormationParams> init_params;
		for (int i = 0; i < balloon_formation_.at(k).number_of_balloons; i++)
		{
			init_params.emplace_back(
				balloon_formation_.at(k).init.at(i).x,
				balloon_formation_.at(k).init.at(i).y,
				balloon_formation_.at(k).init.at(i).vel_x,
				BalloonType::FLOATER,
				balloon_formation_.at(k).init.at(i).size,
				balloon_formation_.at(k).init.at(i).creation_counter);
		}
		balloon_formation_.at(k + 50) = BalloonFormationUnit(balloon_formation_.at(k).number_of_balloons, init_params);
	}

	// TEST
	std::vector<BalloonFormationParams> test_params = {
		{10, y1, 0, BalloonType::FLOATER, BalloonSize::SIZE1, 200},
		{50, y1, 0, BalloonType::FLOATER, BalloonSize::SIZE2, 200},
		{90, y1, 0, BalloonType::FLOATER, BalloonSize::SIZE3, 200},
		{140, y1, 0, BalloonType::FLOATER, BalloonSize::SIZE4, 200}};

	balloon_formation_.at(99) = BalloonFormationUnit(4, test_params);
}

// Inicializa los conjuntos de formaciones
void BalloonFormations::initBalloonFormationPools()
{
	// Reserva espacio para cada pool de formaciones
	balloon_formation_pool_.resize(NUMBER_OF_SETS_PER_POOL);

	// Set #0
	balloon_formation_pool_.at(0) = {
		&balloon_formation_.at(0), &balloon_formation_.at(1), &balloon_formation_.at(2),
		&balloon_formation_.at(3), &balloon_formation_.at(4), &balloon_formation_.at(5),
		&balloon_formation_.at(6), &balloon_formation_.at(7), &balloon_formation_.at(8),
		&balloon_formation_.at(9)};

	// Set #1
	balloon_formation_pool_.at(1) = {
		&balloon_formation_.at(10), &balloon_formation_.at(11), &balloon_formation_.at(12),
		&balloon_formation_.at(13), &balloon_formation_.at(14), &balloon_formation_.at(15),
		&balloon_formation_.at(16), &balloon_formation_.at(17), &balloon_formation_.at(18),
		&balloon_formation_.at(19)};

	// Set #2
	balloon_formation_pool_.at(2) = {
		&balloon_formation_.at(0), &balloon_formation_.at(1), &balloon_formation_.at(2),
		&balloon_formation_.at(3), &balloon_formation_.at(4), &balloon_formation_.at(55),
		&balloon_formation_.at(56), &balloon_formation_.at(57), &balloon_formation_.at(58),
		&balloon_formation_.at(59)};

	// Set #3
	balloon_formation_pool_.at(3) = {
		&balloon_formation_.at(50), &balloon_formation_.at(51), &balloon_formation_.at(52),
		&balloon_formation_.at(53), &balloon_formation_.at(54), &balloon_formation_.at(5),
		&balloon_formation_.at(6), &balloon_formation_.at(7), &balloon_formation_.at(8),
		&balloon_formation_.at(9)};

	// Set #4
	balloon_formation_pool_.at(4) = {
		&balloon_formation_.at(60), &balloon_formation_.at(61), &balloon_formation_.at(62),
		&balloon_formation_.at(63), &balloon_formation_.at(64), &balloon_formation_.at(65),
		&balloon_formation_.at(66), &balloon_formation_.at(67), &balloon_formation_.at(68),
		&balloon_formation_.at(69)};

	// Set #5
	balloon_formation_pool_.at(5) = {
		&balloon_formation_.at(10), &balloon_formation_.at(61), &balloon_formation_.at(12),
		&balloon_formation_.at(63), &balloon_formation_.at(14), &balloon_formation_.at(65),
		&balloon_formation_.at(16), &balloon_formation_.at(67), &balloon_formation_.at(18),
		&balloon_formation_.at(69)};

	// Set #6
	balloon_formation_pool_.at(6) = {
		&balloon_formation_.at(60), &balloon_formation_.at(11), &balloon_formation_.at(62),
		&balloon_formation_.at(13), &balloon_formation_.at(64), &balloon_formation_.at(15),
		&balloon_formation_.at(66), &balloon_formation_.at(17), &balloon_formation_.at(68),
		&balloon_formation_.at(19)};

	// Set #7
	balloon_formation_pool_.at(7) = {
		&balloon_formation_.at(20), &balloon_formation_.at(21), &balloon_formation_.at(22),
		&balloon_formation_.at(23), &balloon_formation_.at(24), &balloon_formation_.at(65),
		&balloon_formation_.at(66), &balloon_formation_.at(67), &balloon_formation_.at(68),
		&balloon_formation_.at(69)};

	// Set #8
	balloon_formation_pool_.at(8) = {
		&balloon_formation_.at(70), &balloon_formation_.at(71), &balloon_formation_.at(72),
		&balloon_formation_.at(73), &balloon_formation_.at(74), &balloon_formation_.at(15),
		&balloon_formation_.at(16), &balloon_formation_.at(17), &balloon_formation_.at(18),
		&balloon_formation_.at(19)};

	// Set #9
	balloon_formation_pool_.at(9) = {
		&balloon_formation_.at(20), &balloon_formation_.at(21), &balloon_formation_.at(22),
		&balloon_formation_.at(23), &balloon_formation_.at(24), &balloon_formation_.at(70),
		&balloon_formation_.at(71), &balloon_formation_.at(72), &balloon_formation_.at(73),
		&balloon_formation_.at(74)};
}
