// drawscreen.cpp
#include <iostream>
#include <vector>
#include <ncurses.h>
#include "game.h"
#include "drawscreen.h"

DrawScreen::DrawScreen()
{
	initscr();				// initiate ncurses
	raw();					// no line buffering
	keypad(stdscr, TRUE);	// allows for F1, F2 etc..
	noecho();				// don't echo keypresses
}	

void DrawScreen::grabKeys()
{
	timeout(100);					// slow system down
	this->keyPressed = getch();		// get key presses
}

void DrawScreen::drawboard(std::vector<std::vector<Game>> & obj)
{
	// gather screensize and adjust accordingly
	int Ypoint, Xpoint, row, col;	
	getmaxyx(stdscr, row, col);
	setScreenYmax(row);
	setScreenXmax(col);
	
	// TEMP, initial screen clear- find a more efficent screen clear
	for(int y = 0; y < getScreenYmax(); ++y)
		for(int x = 0; x < getScreenXmax(); ++x)
			mvprintw(y, x, " ");
	
	// always follow x axis, y axis changes with platform and jumping...		
	setPlatformX(obj[getCameraSection()][getCameraObject()].getPosX());
	
	// setup lowest to highest displayed sections
	unsigned int lowSection, highSection;
	sectionLowTohigh(obj, lowSection, highSection);
	
	// scroll through sections
	for(unsigned int currentSection = lowSection; currentSection <= highSection; ++currentSection)
	{
		
		// scroll through objects within section
		for(unsigned int i = 0; i < obj[currentSection].size(); ++i)
		{
		
			// calculate center point for screen to focus on
			Ypoint = (getScreenYmax() / 2) - (getPlatformY() - obj[currentSection][i].getPosY());
			Xpoint = (getScreenXmax() / 2) - (getPlatformX() - obj[currentSection][i].getPosX());
		
			// if not within screen limits then dont try to display it
			if(Ypoint < 0  || Ypoint > getScreenYmax() ||
				Xpoint < 0 || Xpoint > getScreenXmax())
				continue;
			
			// which character are we drawing?
			switch(obj[currentSection][i].getCharacter())
			{
				case characterType::object:
					
					mvprintw(Ypoint, Xpoint, "*");
					break;
					
				case characterType::humanplayer:
					
					mvprintw(Ypoint - 3, Xpoint + 1, "O");
					mvprintw(Ypoint - 2, Xpoint, "---");
					mvprintw(Ypoint - 1, Xpoint, " | ");
					mvprintw(Ypoint - 0, Xpoint, "/ \\");
					break;
					
				case characterType::enemy:
					
					mvprintw(Ypoint - 3, Xpoint + 1, "O");
					mvprintw(Ypoint - 2, Xpoint, "===");
					mvprintw(Ypoint - 1, Xpoint, " | ");
					mvprintw(Ypoint - 0, Xpoint, "/ \\");
					
					mvprintw(Ypoint + 1, Xpoint - 3, "_________");					
					mvprintw(Ypoint + 2, Xpoint - 2, "o");
					mvprintw(Ypoint + 2, Xpoint + 4, "o");
					break;
				
				case characterType::editing:
					
					mvprintw(Ypoint, Xpoint, "X");
					break;
					
				default:
					break;
			}
		}
	
	}

	// print board stats to screen
	boardStats(obj);
	
}

void DrawScreen::boardStats(std::vector<std::vector<Game>> & obj)
{
	// setup lowest to highest displayed sections
	unsigned int lowSection, highSection;
	sectionLowTohigh(obj, lowSection, highSection);

	// overlay stats
	mvprintw(0, 0, "Board y: %d ", obj[getCameraSection()][getCameraObject()].getPosY());
	mvprintw(1, 0, "Board x: %d ", obj[getCameraSection()][getCameraObject()].getPosX());
	mvprintw(2, 0, "Section: %d ", getCameraSection());
	mvprintw(3, 0, "Object: %d ", getCameraObject());
	
	// print array sizes
	for(int j = 0, i = (getCameraSection() - 1 > 0 ? getCameraSection() - 1 : 0); i <= (getCameraSection() + 1 < static_cast<int>(obj.size()) ? getCameraSection() + 1 : getCameraSection()); ++j, ++i)
		mvprintw(4 + j, 0, "Ar Size[%d]: %d  ", i, obj[i].size());
	
	mvprintw(13, 0, "Disp Section: %d to %d ", lowSection, highSection);
	mvprintw(14, 0, "Sections: %d ", obj.size());
	mvprintw(15, 0, "Section Size: %d ", getSectionSize());
	
}

void DrawScreen::sectionLowTohigh(std::vector<std::vector<Game>> & obj, unsigned int &lowSection, unsigned int &highSection)
{
	// check for lowest section
	if (getCameraSection() - getSectionRange() >= 0)
		lowSection = getCameraSection() - getSectionRange();
	else
		lowSection = 0;
	
	// check highest section
	if (getCameraSection() + getSectionRange() < static_cast<int>(obj.size())) // < getSectionTotal()
		highSection = getCameraSection() + getSectionRange();
	else
		highSection = obj.size() - 1; //getSectionTotal() - 1;
	
	// below code needed to fix bug
	highSection = obj.size() - 1;
	lowSection = 0;
}
