
#include "movingsprite.h"

// Constructor
MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer)
{
	// Copia los punteros
	this->texture = texture;
	this->renderer = renderer;

	// Establece el alto y el ancho del sprite
	this->w = w;
	this->h = h;

	// Establece la posición X,Y del sprite
	this->x = x;
	this->y = y;
	xPrev = x;
	yPrev = y;

	// Establece la velocidad X,Y del sprite
	vx = velx;
	vy = vely;

	// Establece la aceleración X,Y del sprite
	ax = accelx;
	ay = accely;

	// Establece el zoom W,H del sprite
	zoomW = 1;
	zoomH = 1;

	// Establece el angulo con el que se dibujará
	angle = (double)0;

	// Establece los valores de rotacion
	rotateEnabled = false;
	rotateSpeed = 0;
	rotateAmount = (double)0;

	// Contador interno
	counter = 0;

	// Establece el rectangulo de donde coger la imagen
	spriteClip = {0, 0, w, h};

	// Establece el centro de rotación
	center = {0, 0};

	// Establece el tipo de volteado
	currentFlip = SDL_FLIP_NONE;
};

// Destructor
MovingSprite::~MovingSprite()
{
}

// Reinicia todas las variables
void MovingSprite::clear()
{
	x = 0.0f; // Posición en el eje X
	y = 0.0f; // Posición en el eje Y

	vx = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
	vy = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse

	ax = 0.0f; // Aceleración en el eje X. Variación de la velocidad
	ay = 0.0f; // Aceleración en el eje Y. Variación de la velocidad

	zoomW = 1.0f; // Zoom aplicado a la anchura
	zoomH = 1.0f; // Zoom aplicado a la altura

	angle = 0.0;		   // Angulo para dibujarlo
	rotateEnabled = false; // Indica si ha de rotar
	center = {0, 0};	   // Centro de rotación
	rotateSpeed = 0;	   // Velocidad de giro
	rotateAmount = 0.0;	   // Cantidad de grados a girar en cada iteración
	counter = 0;		   // Contador interno

	currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
}

// Mueve el sprite
void MovingSprite::move()
{
	if (enabled)
	{
		xPrev = x;
		yPrev = y;

		x += vx;
		y += vy;

		vx += ax;
		vy += ay;
	}
}

// Muestra el sprite por pantalla
void MovingSprite::render()
{
	if (enabled)
		texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, &center, currentFlip);
}

// Obtiene el valor de la variable
float MovingSprite::getPosX()
{
	return x;
}

// Obtiene el valor de la variable
float MovingSprite::getPosY()
{
	return y;
}

// Obtiene el valor de la variable
float MovingSprite::getVelX()
{
	return vx;
}

// Obtiene el valor de la variable
float MovingSprite::getVelY()
{
	return vy;
}

// Obtiene el valor de la variable
float MovingSprite::getAccelX()
{
	return ax;
}

// Obtiene el valor de la variable
float MovingSprite::getAccelY()
{
	return ay;
}

// Obtiene el valor de la variable
float MovingSprite::getZoomW()
{
	return zoomW;
}

// Obtiene el valor de la variable
float MovingSprite::getZoomH()
{
	return zoomH;
}

// Obtiene el valor de la variable
double MovingSprite::getAngle()
{
	return angle;
}

// Establece la posición del objeto
void MovingSprite::setPos(SDL_Rect rect)
{
	x = (float)rect.x;
	y = (float)rect.y;
	w = rect.w;
	h = rect.h;
}

// Establece el valor de la variable
void MovingSprite::setPosX(float value)
{
	x = value;
}

// Establece el valor de la variable
void MovingSprite::setPosY(float value)
{
	y = value;
}

// Establece el valor de la variable
void MovingSprite::setVelX(float value)
{
	vx = value;
}

// Establece el valor de la variable
void MovingSprite::setVelY(float value)
{
	vy = value;
}

// Establece el valor de la variable
void MovingSprite::setAccelX(float value)
{
	ax = value;
}

// Establece el valor de la variable
void MovingSprite::setAccelY(float value)
{
	ay = value;
}

// Establece el valor de la variable
void MovingSprite::setZoomW(float value)
{
	zoomW = value;
}

// Establece el valor de la variable
void MovingSprite::setZoomH(float value)
{
	zoomH = value;
}

// Establece el valor de la variable
void MovingSprite::setAngle(double value)
{
	angle = value;
}

// Incrementa el valor de la variable
void MovingSprite::incAngle(double value)
{
	angle += value;
}

// Decrementa el valor de la variable
void MovingSprite::decAngle(double value)
{
	angle -= value;
}

// Obtiene el valor de la variable
bool MovingSprite::getRotate()
{
	return rotateEnabled;
}

// Obtiene el valor de la variable
Uint16 MovingSprite::getRotateSpeed()
{
	return rotateSpeed;
}

// Establece la rotacion
void MovingSprite::rotate()
{
	if (enabled)
		if (rotateEnabled)
		{
			if (counter % rotateSpeed == 0)
			{
				incAngle(rotateAmount);
			}
		}
}

// Establece el valor de la variable
void MovingSprite::setRotate(bool value)
{
	rotateEnabled = value;
}

// Establece el valor de la variable
void MovingSprite::setRotateSpeed(int value)
{
	rotateSpeed = value;
}

// Establece el valor de la variable
void MovingSprite::setRotateAmount(double value)
{
	rotateAmount = value;
}

// Establece el valor de la variable
void MovingSprite::disableRotate()
{
	rotateEnabled = false;
	angle = (double)0;
}

// Actualiza las variables internas del objeto
void MovingSprite::update()
{
	move();
	rotate();

	if (enabled)
	{
		++counter %= 60000;
	}
}

// Cambia el sentido de la rotación
void MovingSprite::switchRotate()
{
	rotateAmount *= -1;
}

// Establece el valor de la variable
void MovingSprite::setFlip(SDL_RendererFlip flip)
{
	currentFlip = flip;
}

// Gira el sprite horizontalmente
void MovingSprite::flip()
{
	currentFlip = (currentFlip == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
}

// Obtiene el valor de la variable
SDL_RendererFlip MovingSprite::getFlip()
{
	return currentFlip;
}

// Devuelve el rectangulo donde está el sprite
SDL_Rect MovingSprite::getRect()
{
	const SDL_Rect rect = {(int)x, (int)y, w, h};
	return rect;
}

// Establece los valores de posición y tamaño del sprite
void MovingSprite::setRect(SDL_Rect rect)
{
	x = (float)rect.x;
	y = (float)rect.y;
	w = rect.w;
	h = rect.h;
}

// Deshace el último movimiento
void MovingSprite::undoMove()
{
	x = xPrev;
	y = yPrev;
}

// Deshace el último movimiento en el eje X
void MovingSprite::undoMoveX()
{
	x = xPrev;
}

// Deshace el último movimiento en el eje Y
void MovingSprite::undoMoveY()
{
	y = yPrev;
}

// Pone a cero las velocidades de desplacamiento
void MovingSprite::clearVel()
{
	vx = vy = 0.0f;
}

// Devuelve el incremento en el eje X en pixels
int MovingSprite::getIncX()
{
	return (int)x - (int)xPrev;
}