// Copyright (c) 2022 Yevhen Babiichuk (DustDFG), <dfgdust@gmail.com>.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "Board.h"

#include "Screen.h"
#include "Sprite.h"

#include "Data.h"
#include <cstdint>

#include <SDL_render.h>
#include <SDL_rect.h>
#include <SDL_events.h>

Board::Board(Screen* screen) : Sprite(screen)
{
	//bounds
	float boundsSize = screen->width / 12 * 10;

	this->bounds = {
		(screen->width - boundsSize) / 2,   //x
		(screen->height - boundsSize) / 2,  //y
		boundsSize,                         //w
		boundsSize,                         //h
	};

	//shadow bounds
	float offsetSize = boundsSize / 100;

	this->shadowBounds = {
		this->bounds.x - offsetSize,        //x
		this->bounds.y - offsetSize,        //y
		this->bounds.w + (2 * offsetSize),  //w
		this->bounds.h + (2 * offsetSize),  //h
	};

	this->cellSize = this->bounds.w / this->data->getSize();
}

void Board::drawShadow()
{
	SDL_SetRenderDrawColor(this->screen->renderer, 0x00, 0x00, 0x00, 0xff);
	SDL_RenderFillRectF(this->screen->renderer, &this->shadowBounds);
}

void Board::drawCellContent(SDL_FRect* bounds, uint8_t contentCode)
{
	if(contentCode == 255)
	{
		this->screen->drawRect(bounds, 0x00, 0x80, 0x00, 0xff);
	}
	else if(contentCode > 0)
	{
		this->screen->drawRect(bounds, 0x80, 0x00, 0x00, 0xff);
	}
}

void Board::draw()
{
	this->drawShadow();

	SDL_FRect cellBounds;

	cellBounds.w = this->cellSize;
	cellBounds.h = this->cellSize;

	for(uint8_t i = 0; i < this->data->getSize(); i++)
	{
		for(uint8_t j = 0; j < this->data->getSize(); j++)
		{
			//Draw cell background
			if((i + j) % 2 == 0)
			{
				SDL_SetRenderDrawColor(this->screen->renderer, 240, 217, 181, 255);
			}
			else
			{
				SDL_SetRenderDrawColor(this->screen->renderer, 181, 136, 99, 255);
			}

			cellBounds.x = (cellBounds.w * i) + this->bounds.x;
			cellBounds.y = (cellBounds.h * j) + this->bounds.y;

			//Draw cell content
			SDL_RenderFillRectF(this->screen->renderer, &cellBounds);

			float offsetSize = this->cellSize / 20;

			SDL_FRect contentBounds = {
				cellBounds.x + offsetSize,         //x
				cellBounds.y + offsetSize,         //y
				cellBounds.w - (2 * offsetSize),   //w
				cellBounds.h - (2 * offsetSize),   //h
			};


			this->drawCellContent(&contentBounds, this->data->getContentCode(i, j));
		}
	}
}

void Board::onBoundsClick(SDL_MouseButtonEvent event)
{
	SDL_FPoint coords;

	//Local board coords
	coords.x = event.x - this->bounds.x;
	coords.y = event.y - this->bounds.y;

	//Cell coords
	uint8_t cellX = coords.x / this->cellSize;
	uint8_t cellY = coords.y / this->cellSize;

	if(this->data->isPossibleStep(cellX, cellY))
	{
		this->data->doStep(cellX, cellY);
	}
}
