/*
 * UINineSlice.cpp
 *
 *  Created on: May 31, 2020
 *      Author: ayoungblood
 */

#include "../ui/UINineSlice.h"
#include "../game/Game.hpp"
#include "../ecs/ECS.h"
#include "../ecs/Components.h"
#include "string.h"
#include <iostream>
#include <stdio.h>

extern Manager manager;

UINineSlice::UINineSlice(std::string texID)
{
	textureID = texID;
}

UINineSlice::~UINineSlice()
{

}

void UINineSlice::MakeSlices(std::string texture, int srcW, int srcH, int x0, int x1, int y0, int y1, SDL_Rect finalRect,int scale, Game::groupLabels group)
{
//  Note about the variables: The source texture is what everything is drawn from, with srcW and srcH defining the size of that texture and x0 x1 being the vertical slices position across the x axis, and the y0, y1 being the horizontal slices. This is also in the project readme with an ASCII art diagram. finalRect refers to the Rectangle that describes the area of the screen in which we want the 9-sliced source to appear in it's final in-game rendering.

	SDL_Rect srcRect;
	SDL_Rect destRect;
	int cols;
	int rows;
	int colsRemainder;
	int rowsRemainder;

	cols = ((finalRect.w-x0-(srcW-x1))/(x1-x0));
	rows = (finalRect.h-y0-(srcH-y1))/(y1-y0);
//	Calculate a remainders
	colsRemainder = ((finalRect.w-x0-(srcW-x1))%(x1-x0));
	rowsRemainder = ((finalRect.h-y0-(srcH-y1))%(y1-y0));

//	printf("\n\nColumns: %d\nRows: %d\nColumn Remainder: %d\nRow Remainder: %d\n\n",cols,rows,colsRemainder,rowsRemainder);

	finalRect.x = finalRect.x*scale;
	finalRect.y = finalRect.y*scale;
	finalRect.w = finalRect.w*scale;
	finalRect.h = finalRect.h*scale;

	for (int i=0; i<9; i++)
	{
		switch(i)
		{
		case 0:
			srcRect.x = 0;
			srcRect.y = 0;
			srcRect.w = x0;
			srcRect.h = y0;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 1:
			srcRect.x = x0;
			srcRect.y = 0;
			srcRect.w = x1-x0;
			srcRect.h = y0;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 2:
			srcRect.x = x1;
			srcRect.y = 0;
			srcRect.w = srcW-x1;
			srcRect.h = y0;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 3:
			srcRect.x = 0;
			srcRect.y = y0;
			srcRect.w = x0;
			srcRect.h = y1-y0;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 4:
			srcRect.x = x0;
			srcRect.y = y0;
			srcRect.w = x1-x0;
			srcRect.h = y1-y0;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 5:
			srcRect.x = x1;
			srcRect.y = y0;
			srcRect.w = srcW-x1;
			srcRect.h = y1-y0;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 6:
			srcRect.x = 0;
			srcRect.y = y1;
			srcRect.w = x0;
			srcRect.h = srcH-y1;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 7:
			srcRect.x = x0;
			srcRect.y = y1;
			srcRect.w = x1-x0;
			srcRect.h = srcH-y1;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		case 8:
			srcRect.x = x1;
			srcRect.y = y1;
			srcRect.w = srcW-x1;
			srcRect.h = srcH-y1;
			destRect.w = srcRect.w;
			destRect.h = srcRect.h;
			break;
		default:
			srcRect.x = 0;
			srcRect.y = 0;
			srcRect.w = 0;
			srcRect.h = 0;
			destRect.w = 0;
			destRect.h = 0;
		}

// 		Calculate where and how many tiles to place
// 			We only need one instance of each of these in each corner or slices 0,2,6,8
		if (i==0||i==2||i==6||i==8)
		{
			if (i==0)
			{
				destRect.x = finalRect.x;
				destRect.y = finalRect.y;
			}
			if (i==2)
			{
				destRect.x = finalRect.x+(finalRect.w-srcRect.w*scale);
				destRect.y = finalRect.y;
			}
			if (i==6)
			{
				destRect.x = finalRect.x;
				destRect.y = finalRect.y+(finalRect.h-srcRect.h*scale);
			}
			if (i==8)
			{
				destRect.x = finalRect.x+(finalRect.w-srcRect.w*scale);
				destRect.y = finalRect.y+(finalRect.h-srcRect.h*scale);
			}
			AddSlice(srcRect,destRect,scale,group);
		}
//		Slices 1,7 need to be repeated in a row
		if (i==1||i==7)
		{
			if (i==1)
			{
				for (int c=0;c<cols;c++)
				{
					destRect.x = finalRect.x+(x0*scale+c*(x1*scale-x0*scale));
					destRect.y = finalRect.y;
					AddSlice(srcRect,destRect,scale,group);
				}
				if (colsRemainder>0){
					destRect.x = finalRect.x+(x0*scale+cols*(x1*scale-x0*scale));
					destRect.y = finalRect.y;
					srcRect.w = colsRemainder;
					destRect.w = colsRemainder;
					AddSlice(srcRect,destRect,scale,group);
				}
			}
			if (i==7)
			{
				for (int c=0;c<cols;c++)
				{
					destRect.x = finalRect.x+(x0*scale+c*(x1*scale-x0*scale));
					destRect.y = finalRect.y+(finalRect.h-(srcH-y1)*scale);
					AddSlice(srcRect,destRect,scale,group);
				}
				if (colsRemainder>0){
					destRect.x = finalRect.x+(x0*scale+cols*(x1*scale-x0*scale));
					destRect.y = finalRect.y+(finalRect.h-(srcH-y1)*scale);
					srcRect.w = colsRemainder;
					destRect.w = colsRemainder;
					AddSlice(srcRect,destRect,scale,group);
				}
			}
		}
//		Slice 3,5 need to be repeated in a column
		if (i==3||i==5)
		{
			if (i==3)
			{
				for (int r=0;r<rows;r++)
				{
					destRect.x = finalRect.x;
					destRect.y = finalRect.y+(y0*scale+r*(y1-y0)*scale);
					AddSlice(srcRect,destRect,scale,group);
				}
				if (rowsRemainder>0){
					destRect.x = finalRect.x;
					destRect.y = finalRect.y+(y0*scale+rows*(y1-y0)*scale);
					srcRect.h = rowsRemainder;
					destRect.h = rowsRemainder;
					AddSlice(srcRect,destRect,scale,group);
				}
			}
			if (i==5)
			{
				for (int r=0;r<rows;r++)
				{
					destRect.x = finalRect.x+(finalRect.w-(srcW-x1)*scale);
					destRect.y = finalRect.y+(y0*scale+r*(y1-y0)*scale);
					AddSlice(srcRect,destRect,scale,group);
				}
				if (rowsRemainder>0){
					destRect.x = finalRect.x+(finalRect.w-(srcW-x1)*scale);
					destRect.y = finalRect.y+(y0*scale+rows*(y1-y0)*scale);
					srcRect.h = rowsRemainder;
					destRect.h = rowsRemainder;
					AddSlice(srcRect,destRect,scale,group);
				}
			}
		}
//		Slice 4 will need to be repeated in columns and rows
		if (i==4)
		{
			int rowY;
			for (int r=0;r<rows;r++)
			{
				rowY = r*(y1-y0);
				for (int c=0;c<cols;c++)
				{
					destRect.x = finalRect.x+(x0*scale+c*(x1-x0)*scale);
					destRect.y = finalRect.y+(y0*scale+rowY*scale);
					AddSlice(srcRect,destRect,scale,group);
				}
				if (colsRemainder>0)
				{
					destRect.x = finalRect.x+(x0*scale+cols*(x1-x0)*scale);
					destRect.y = finalRect.y+(y0*scale+rowY*scale);
					srcRect.w = colsRemainder;
					destRect.w = colsRemainder;
					AddSlice(srcRect,destRect,scale,group);
				}
			}
			if (rowsRemainder>0)
			{
				for (int c=0;c<cols;c++)
				{
					destRect.x = finalRect.x+(x0*scale+c*(x1-x0)*scale);
					destRect.y = finalRect.y+(y0*scale+rows*(y1-y0)*scale);
					srcRect.h = rowsRemainder;
					destRect.h = rowsRemainder;
					srcRect.w = (srcW-x0-(srcW-x1));
					destRect.w = (srcW-x0-(srcW-x1));
					AddSlice(srcRect,destRect,scale,group);
				}
			}
			if(rowsRemainder>0&&colsRemainder>0)
			{
				destRect.x = finalRect.x+(x0*scale+cols*(x1-x0)*scale);
				destRect.y = finalRect.y+(y0*scale+rows*(y1-y0)*scale);
				srcRect.w = colsRemainder;
				srcRect.h = rowsRemainder;
				destRect.w = colsRemainder;
				destRect.h = rowsRemainder;
				AddSlice(srcRect,destRect,scale,group);
			}
		}
	}
}

void UINineSlice::AddSlice(SDL_Rect srcRect, SDL_Rect destRect, int scale, Game::groupLabels group)
{
	auto& slice(manager.addEntity());
	SDL_Rect scaledRect = SDL_Rect();
	scaledRect.x = destRect.x;
	scaledRect.y = destRect.y;
	scaledRect.w = destRect.w*scale;
	scaledRect.h = destRect.h*scale;
	slice.addComponent<TransformComponent>(scaledRect.x, scaledRect.y, scaledRect.w, scaledRect.h, 1);
	slice.addComponent<SpriteComponent>("textBox",SpriteComponent::spriteUIL0,srcRect,scaledRect);
	slice.addGroup(group);
}
