#include "donfedejugador.h"
#include "suelosimple.h"
#include "zombiesimple.h"
#include <QDebug>
#include <math.h>

donFedeJugador::donFedeJugador(QPixmap pixmap)
{
    setPixmap(pixmap);
    level = -1;
    m_x = 0;
    m_y = 0;
    animationStep=0;
    lives = new vidas();
    puntos = new points();
    lookingRight = true;
    falling = true;
    movingLeft = false;
    movingRight = false;
    jumping = false;
    onFloor = false;
    rightWall = false;
    leftWall = false;
    floorYcoor = 360-boundingRect().height();
    yAnimation = new QPropertyAnimation(this,"y",this);
    connect(yAnimation,&QPropertyAnimation::finished,this,
            &donFedeJugador::checkYAnimationFinished);

    xAnimation = new QPropertyAnimation(this,"x",this);
    connect(xAnimation,&QPropertyAnimation::finished,this,
            &donFedeJugador::checkXAnimationFinished);

    connect(puntos, &points::pointsChanged,this,[=](){
        emit pointsChanged();
    });

    animationTimer = new QTimer();
    animationTimer->start(25);
    connect(animationTimer, &QTimer::timeout,this, &donFedeJugador::animationPixmapRefresh);
}

donFedeJugador::~donFedeJugador()
{
    delete xAnimation;
    delete yAnimation;
    delete puntos;
    delete lives;
    delete animationTimer;
}

qreal donFedeJugador::x() const
{
    return m_x;
}

void donFedeJugador::setX(qreal newX)
{
    moveBy(newX-m_x,0);
    m_x = newX;
    emit xChanged(m_x,m_y);
}

qreal donFedeJugador::y() const
{
    return m_y;
}

void donFedeJugador::setY(qreal newY)
{
    moveBy(0,newY-m_y);
    m_y = newY;
    emit yChanged(m_x,m_y);
}

void donFedeJugador::fallingPlayer()
{
    if(!onFloor){
        falling = true;
        climbable = false;
        yAnimation->setStartValue(scenePos().y());
        yAnimation->setEndValue(floorYcoor);
        yAnimation->setEasingCurve(QEasingCurve::InOutQuad);
        yAnimation->setDuration(55.0*pow(floorYcoor-scenePos().y(), 1.0/3.0)+1);

        yAnimation->start();
    }
}

void donFedeJugador::stopFalling()
{
    if(falling){
        yAnimation->stop();
        falling = false;
    }
}

void donFedeJugador::jumpingPlayer()
{
    if(!falling && !jumping){
        jumping = true;
        yAnimation->setStartValue(scenePos().y());
        yAnimation->setEndValue(scenePos().y()-boundingRect().height()*0.9);
        yAnimation->setEasingCurve(QEasingCurve::OutQuad);
        yAnimation->setDuration(350);
        yAnimation->start();
    }
}

void donFedeJugador::climbPlayer()
{
    if(climbable){
        setY(m_y-2);
    }
}

void donFedeJugador::startLateralMovingRight()
{
    lookingRight = true;
    xAnimation->setStartValue(scenePos().x());
    xAnimation->setEndValue(scenePos().x()+500);
    xAnimation->setEasingCurve(QEasingCurve::Linear);
    xAnimation->setDuration(1000);
    movingRight = true;
    xAnimation->start();
}

void donFedeJugador::startLateralMovingLeft()
{
    lookingRight = false;
    xAnimation->setStartValue(scenePos().x());
    xAnimation->setEndValue(scenePos().x()-500);
    xAnimation->setEasingCurve(QEasingCurve::Linear);
    xAnimation->setDuration(1000);
    movingLeft = true;
    xAnimation->start();
}

void donFedeJugador::stopLateralMoving()
{
    movingLeft = false;
    movingRight = false;
    xAnimation->stop();
}

void donFedeJugador::setLevel(int newLevel)
{
    level = newLevel;
}

void donFedeJugador::interactable1()
{
    switch(level){
    case 0:
        //moveBy(-350-m_x,0);
        //m_x = -350;
        //setY(-250);
        //break;
        emit levelFinished();
        break;
    }
}

void donFedeJugador::interactable2()
{
    switch(level){
    case 0:
    case 1:
        puntos->changeAmountPoints(25);
        break;
    }
}

void donFedeJugador::death()
{
    xAnimation->stop();
    yAnimation->stop();
    if(jumping)jumping=false;
    if(!onFloor) onFloor=true;
    lives->changeAmountVidas(lives->getVidas()-1);
    if(lives->getVidas()<0) {
        emit outOfLives();
    }
    moveBy(-540-m_x,0);
    m_x = -540;
    setY(284);
}

points * donFedeJugador::getPoints()
{
    return puntos;
}

vidas *donFedeJugador::sendLives()
{
    return lives;
}

proyectil *donFedeJugador::shoot()
{
    int dx = boundingRect().width()/2;
    proyectil * bala = new proyectil(QPixmap(":/ImagenesDeProyecto/Proyectil.png"),
                                     scenePos().x()+dx,scenePos().y()+32,lookingRight);
    return bala;
}

void donFedeJugador::checkInteract()
{
    QList<QGraphicsItem*> collidingItems = this->collidingItems();
    foreach(QGraphicsItem *item, collidingItems){
        interactable * interactuables = dynamic_cast<interactable*>(item);
        if(interactuables){
            switch(interactuables->getInteractable())
            {
            case 1:{
                interactuables->setPixmap(QPixmap(":/ImagenesDeProyecto/desaparecer.png"));
                interactable1();
                break;
            }
            case 2:{
                interactuables->setPixmap(QPixmap(":/ImagenesDeProyecto/desaparecer.png"));
                interactable2();
                break;
            };
                // Add interactions;
            }
        }
    }
}

void donFedeJugador::checkEnemy()
{
    QList<QGraphicsItem*> collidingItems = this->collidingItems();
    foreach(QGraphicsItem *item, collidingItems){
        zombieSimple * zombies = dynamic_cast<zombieSimple*>(item);
        if(zombies){
            death();
        }
    }
}


void donFedeJugador::collidesFloor(bottomHitbox * bottomHB)
{
    QList<QGraphicsItem*> collidingItems = bottomHB->collidingItems();
    foreach(QGraphicsItem *item, collidingItems){
        sueloSimple * bloquesDeSuelo = dynamic_cast<sueloSimple*>(item);
        if(bloquesDeSuelo && falling){
            stopFalling();
            onFloor = true;
            climbable = true;
            falling = false;
            jumping = false;
            setPixmap(QPixmap(":/ImagenesDeProyecto/DonFede8bit.png"));
            return;
        }
    }
    if(onFloor && !jumping){
        climbable = false;
        onFloor = false;
        fallingPlayer();
        qDebug() << "cayendo de suelo";
    }
}

void donFedeJugador::collidesRoof(topHitbox * topHB)
{
    QList<QGraphicsItem*> collidingItems = topHB->collidingItems();
    foreach(QGraphicsItem *item, collidingItems){
        sueloSimple * bloquesDeSuelo = dynamic_cast<sueloSimple*>(item);
        if(bloquesDeSuelo && jumping){
            jumping = false;
            yAnimation->stop();
            fallingPlayer();
            qDebug() << "choque arriba";
            return;
        }
    }
}

void donFedeJugador::collidesWallW(westHitbox * westHB)
{
    QList<QGraphicsItem*> collidingItems = westHB->collidingItems();
    foreach(QGraphicsItem *item, collidingItems){
        sueloSimple * bloquesDeSuelo = dynamic_cast<sueloSimple*>(item);
        if(bloquesDeSuelo && movingLeft && !rightWall){
            stopLateralMoving();
            setX(m_x+5);
            leftWall = true;
            qDebug() << "choque izquierda";
            return;
        }
    }
    if(rightWall && movingLeft){
        rightWall = false;
        qDebug() << "saliendo muro derecho";
    }
    if(leftWall && movingRight){
        leftWall = false;
        qDebug() << "saliendo muro izquierdo";
    }
}

void donFedeJugador::collidesWallE(eastHitbox * eastHB)
{
    QList<QGraphicsItem*> collidingItems = eastHB->collidingItems();
    foreach(QGraphicsItem *item, collidingItems){
        sueloSimple * bloquesDeSuelo = dynamic_cast<sueloSimple*>(item);
        if(bloquesDeSuelo && movingRight && !leftWall){
            stopLateralMoving();
            setX(m_x-5);
            rightWall = true;
            qDebug() << "choque derecha";
            return;
        }
    }
    if(rightWall && movingLeft){
        rightWall = false;
        qDebug() << "saliendo muro derecho";
    }
    if(leftWall && movingRight){
        leftWall = false;
        qDebug() << "saliendo muro izquierdo";
    }
}

void donFedeJugador::checkYAnimationFinished()
{
    if(falling)
    {
        falling = false;
        yAnimation->stop();
    }
    if(jumping)
    {
        jumping = false;
        onFloor = false;
        emit stoppedJumping();
        fallingPlayer();
    }
}

void donFedeJugador::checkXAnimationFinished()
{
    if(movingRight)startLateralMovingRight();
    if(movingLeft)startLateralMovingLeft();
}

void donFedeJugador::animationPixmapRefresh()
{
    if(jumping){
        if(lookingRight)setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkRight2.png"));
        else setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkLeft2.png"));
    }
    else if(movingRight){
        if(!jumping){
            switch(animationStep){
            case 0:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkRight1.png"));
                animationStep = 2;
                break;
            case 1:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkRight1.png"));
                animationStep = 2;
                break;
            case 2:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkRight2.png"));
                animationStep = 1;
                break;
            default:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkRight1.png"));
                animationStep = 2;
            }
        }
    }
    else if(movingLeft){
        if(!jumping){
            switch(animationStep){
            case 0:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkLeft1.png"));
                animationStep = 2;
                break;
            case 1:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkLeft1.png"));
                animationStep = 2;
                break;
            case 2:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkLeft2.png"));
                animationStep = 1;
                break;
            default:
                setPixmap(QPixmap(":/ImagenesDeProyecto/donFedeAnimation/donFedeWalkLeft1.png"));
                animationStep = 2;
            }
        }
    }
    else
    {
        animationStep = 0;
        setPixmap(QPixmap(":/ImagenesDeProyecto/DonFede8bit.png"));
    }
}

