//Player class body

#include"player.h"

Player::Player(int x,int y, int lvlH, SDL_Renderer* render){
    levelHeight = lvlH;

    posX = x;
    posY = y;

    szW = 40;
	szH = 40;
	rect.w = szW;
	rect.h = szH;
	power = 0;

	renderer = render;

	ply.setRenderer(renderer);
	loadMedia();

	ground = false;
};

int Player::print(int cameraX){
	oldPosX = posX;
	oldPosY = posY;

	rect.x = posX;
	rect.y = posY;

	SDL_Rect cameraFix = rect;
	cameraFix.x -= cameraX;

	SDL_SetRenderDrawColor(renderer,0xFF,0,0,0xFF);
	if(power == 0)ply.render(&cameraFix,&plyFrame[0]);
	else{
		ply.render(&cameraFix,&plyRun);
		power--;
	}
	if(ifRunning or power > 0)ply.render(&cameraFix,&plyFrame[1]);

	move();
	ground = false;
	topCollision = false;

    //Check if the player has fell out of the world (not horizontally, sadly).
    if(posY >= levelHeight) return 1;

    return 0;
};

void Player::loadMedia(){
	ply.loadTexture("textures/player.png");

	plyFrame[0].w = szW;
	plyFrame[0].h = szH;
	plyFrame[0].x = 0;
	plyFrame[0].y = 0;

	plyFrame[1].w = szW;
	plyFrame[1].h = szH;
	plyFrame[1].x = szW;
	plyFrame[1].y = 0;

	plyRun.w = szW;
	plyRun.h = szH;
	plyRun.x = szW*2;
	plyRun.y = 0;
};

int Player::intVelX(){
	return static_cast<int>(velocityX);
};

void Player::move(){
	//float dt = dTime.getDt();
	float dt = 0.016;

	//Set keyboard variable
	const Uint8* currentKeyStates = SDL_GetKeyboardState(NULL);

	//Intializing variables
	int direction = 0; //1 = right, 0 = idle/both, -1 = left
	int dur = 4; //Divide transition time
	int speed = 200; //Horizontal movement speed
	float run = 1.5; //Running speed multiplication
	ifRunning = false;
	//static bool isRunning = false;

	int gravity = 800; //Gravity force
	int jump = 500; //Jump force
	if(power > 0){
		jump = 700;
		speed = 250;
	}

	//Check keyboard current state
	if(currentKeyStates[SDL_SCANCODE_LEFT]) direction += -1;
	if(currentKeyStates[SDL_SCANCODE_RIGHT]) direction += 1;
	if(!currentKeyStates[SDL_SCANCODE_LSHIFT] and !isRunning){
		run = 1;
	}
	if(run!=1) dur /= 1;

	//Set velocity
	if(direction == 1 and intVelX() < speed){
		velocityX += speed * dt * dur;
		if(intVelX() > speed) velocityX = speed;
		}
	if(direction == -1 and intVelX() > -speed){
		velocityX -= speed * dt * dur;
		if(intVelX() < -speed) velocityX = -speed;
		}
	if(direction == 0 and velocityX != 0){
		if(intVelX() > 0){
			velocityX -= speed * dt * dur;
			if(intVelX() < 0) velocityX = 0;
		}
		else if(intVelX() < 0){
			velocityX += speed * dt * dur;
			if(intVelX() > 0) velocityX = 0;
		}
		else if(velocityX <= 1 or velocityX >= -1) velocityX = 0;
	}

	//Jump and gravity logic
	if(ground){
		isRunning = false;
		if(currentKeyStates[SDL_SCANCODE_SPACE] and !topCollision){
			velocityY = jump;
			if(currentKeyStates[SDL_SCANCODE_LSHIFT]){
				isRunning = true;
			}
		}
	}
	else{
		if(isRunning == false) run = 1;
	}

	if(run!=1) ifRunning = true;

	//Get the position and update the velY with gravity
	velocityY -= gravity * dt;
	float x = velocityX * dt * run;
	float y = velocityY * dt;

	//Convert and set new int position
	posX += static_cast<int>(x);
	posY -= static_cast<int>(y+0.5);


};

int Player::check(SDL_Rect rectA, int type){
	//Initialize and reset collision type
	int collision = 0;

	//Set B rectangle variables
	int bX = rectA.x;
	int bY = rectA.y;
	int b2X = rectA.x + rectA.w;
	int b2Y = rectA.y + rectA.h;

	//Float-ize the position
	float movX = posX, movY = posY;

	//Move the player out of the rectangle
	if(type == 1){
	while(((movX >= bX and movX < b2X)
	or (movX + szW > bX and movX + szW <= b2X)
	or (movX < bX and movX + szW > b2X))
	and ((movY > bY and movY < b2Y)
	or (movY + szH > bY and movY + szH < b2Y)
	or (movY < bY and movY + szH > b2Y))){
		movX -= (posX - oldPosX)/2;
		movY -= (posY - oldPosY)/2;
		collision = 1;
	}

	//Correct possible position issues
	if(collision == 1){
		//Vertical adjustement
		if((movX > bX and movX < b2X)
		or (movX + szW > bX and movX + szW < b2X)
		or (movX < bX and movX + szW > b2X)){
			while(movY + szH < bY){
				movY++;
				velocityY = 0;
			}
			while(movY - 1 > b2Y){
				movY--;
			}
		}
		//Horizontal adjustement
		if((movY > bY and movY < b2Y)
		or (movY + szH > bY and movY + szH < b2Y)
		or (movY < bY and movY + szH > b2Y)){
			while(movX + szW < bX){
				movX++;
				velocityX = 0;
			}
			while(movX > b2X){
				movX--;
				velocityX = 0;
			}
		}
	}

	//Set and int-ize the position*/
	posX = static_cast<int>(movX);
	posY = static_cast<int>(movY);

	//Check collsion type and reset velocities
	//Vertical collisions
	if((posX >= bX and posX < b2X)
	or (posX + szW > bX and posX + szW <= b2X)
	or (posX < bX and posX + szW > b2X)){
		//Top collision
		if(posY + szH == bY){
			ground = true;
			collision = 2;
			velocityY = 0;
			//posY -= 40;
		}
		//Bottom collision
		else if(posY == b2Y){
			collision = 3;
			topCollision = true;
			if(velocityY > 0)
				velocityY -= static_cast<int>(velocityY);
		}
	}
	//Horizontal collisions
	if((posY >= bY and posY < b2Y)
	or (posY + szH > bY and posY + szH <= b2Y)
	or (posY < bY and posY + szH > b2Y)){
	//Left collision
		if(posX + szW == bX){
			collision = 4;
			if(velocityX > 0)
				velocityX -= static_cast<int>(velocityX);
		}
		//Right collision
		else if(posX == b2X){
			collision = 5;
			if(velocityX < 0)
				velocityX -= static_cast<int>(velocityX);
		}
	}
	}
	else if(type == 2 and power == 0){
		if(((movX >= bX and movX < b2X)
		or (movX + szW > bX and movX + szW <= b2X)
		or (movX < bX and movX + szW > b2X))
		and ((movY >= bY and movY < b2Y)
		or (movY + szH > bY and movY + szH <= b2Y)
		or (movY < bY and movY + szH > b2Y))){
			//power = 10 / dTime.getDt();
			power = 360;
		}
	}
	return power;
};
