#pragma once

#include <list>
#include <SDL3/SDL.h>
#include "../Core.h"

struct TSnakeSegment
{
	TVector2d m_Position;
	TSnakeSegment(int x, int y) : m_Position(x, y) {}
};

using TSnakeContainer = std::list<TSnakeSegment>;
enum class EDirection { None, Up, Down, Left, Right };


class TSnake
{
public:
	TSnake();
	void Update(float DeltaTime);
	void Move();
	void Render(SDL_Renderer* Renderer);
	void SetDirection(EDirection Direction);
	void GrowBy(int Amount)
	{
		m_GrowBy += Amount;
	}
	EDirection GetOppositeDirection(EDirection Direction);
	EDirection GetSnakePhysicalDirection()
	{
		if (m_SnakeBody.size() == 1) return m_Direction;
		return GetOppositeDirection(GetNextSegmentDirection(m_SnakeBody.begin()));
	}
	EDirection GetNextSegmentDirection(std::list<TSnakeSegment>::iterator CurrentSegment);
	SDL_AppResult HandleEvent(SDL_Event* event);
	bool IsOccupiedBySegment(int X, int Y);

protected:
	TSnakeContainer m_SnakeBody;
	int m_Size;
	EDirection m_Direction;
	float m_Speed{ 5.0f };
	float m_MoveDistance{};
	int m_GrowBy{ 10 };
	SDL_FRect m_DestinationRect;

	SDL_FRect HeadLeftRect{ GetRect(7, 4) };
	SDL_FRect HeadRightRect{ GetRect(7, 6) };
	SDL_FRect HeadUpRect{ GetRect(7, 3) };
	SDL_FRect HeadDownRect{ GetRect(7, 5) };

	SDL_FRect SegmentUpDownRect{ GetRect(0, 2) };
	SDL_FRect SegmentLeftRightRect{ GetRect(1, 2) };
	SDL_FRect SegmentLeftUpRect{ GetRect(2, 2) };
	SDL_FRect SegmentRightUpRect{ GetRect(3, 2) };
	SDL_FRect SegmentLeftDownRect{ GetRect(4, 2) };
	SDL_FRect SegmentRightDownRect{ GetRect(5, 2) };

	SDL_FRect SegmentTailUpRect{ GetRect(6, 2) };
	SDL_FRect SegmentTailLeftRect{ GetRect(7, 2) };
	SDL_FRect SegmentTailDownRect{ GetRect(8, 2) };
	SDL_FRect SegmentTailRightRect{ GetRect(9, 2) };
};
