#include "const.h"
#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
	setTexture(texture);
	setRenderer(renderer);

	// Establece el alto y el ancho del sprite
	setWidth(w);
	setHeight(h);

	// Establece la posición X,Y del sprite
	setPosX(x);
	setPosY(y);
	mPosXPrev = x;
	mPosYPrev = y;

	// Establece la velocidad X,Y del sprite
	setVelX(velx);
	setVelY(vely);

	// Establece la aceleración X,Y del sprite
	setAccelX(accelx);
	setAccelY(accely);

	// Establece el zoom W,H del sprite
	setZoomW(1);
	setZoomH(1);

	// Establece el angulo con el que se dibujará
	setAngle(0.0);

	// Establece los valores de rotacion
	setRotate(false);
	setRotateSpeed(0);
	setRotateAmount(0.0);

	// Contador interno
	mCounter = 0;

	// Establece el rectangulo de donde coger la imagen
	setSpriteClip(0, 0, w, h);

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

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

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

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

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

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

	mZoomW = 1.0f; // Zoom aplicado a la anchura
	mZoomH = 1.0f; // Zoom aplicado a la altura

	mAngle = 0.0;		 // Angulo para dibujarlo
	mRotate = false;	 // Indica si ha de rotar
	mCenter = {0, 0};	 // Centro de rotación
	mRotateSpeed = 0;	 // Velocidad de giro
	mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
	mCounter = 0;		 // Contador interno

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

// Mueve el sprite
void MovingSprite::move()
{
	if (mEnabled)
	{
		mPosXPrev = mPosX;
		mPosYPrev = mPosY;

		mPosX += mVelX;
		mPosY += mVelY;

		mVelX += mAccelX;
		mVelY += mAccelY;
	}
}

// Muestra el sprite por pantalla
void MovingSprite::render()
{
	if (mEnabled)
		mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle, &mCenter, mFlip);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Establece la rotacion
void MovingSprite::rotate()
{
	if (mEnabled)
		if (mRotate)
		{
			if (mCounter % mRotateSpeed == 0)
			{
				incAngle(mRotateAmount);
			}
		}
}

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

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

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

// Establece el valor de la variable
void MovingSprite::disableRotate()
{
	mRotate = false;
	mAngle = 0;
}

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

	if (mEnabled)
		++mCounter %= 60000;
}

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

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

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

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

// Devuelve el rectangulo donde está el sprite
SDL_Rect MovingSprite::getRect()
{
	SDL_Rect rect = {(int)getPosX(), (int)getPosY(), getWidth(), getHeight()};
	return rect;
}

// Deshace el último movimiento
void MovingSprite::undoMove()
{
	mPosX = mPosXPrev;
	mPosY = mPosYPrev;
}

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

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

// Pone a cero las velocidades de desplacamiento
void MovingSprite::clearVel()
{
	mVelX = mVelY = 0;
}