/********************************************************************
 *  Nomes: Gabriel Capella                       Números USP: 8962078 
 *         João Herique Luciano                               8535957
 * 
 *  Tarefa:    RedCore - EP2 MAC0463
 *  Arquivo:   Paddle.cpp
 *  Descrição: Classe para auxiliar na criação da raquete.
 ********************************************************************/

#include "Paddle.h"
#include "../params.h"

USING_NS_CC;

bool Paddle::init() {
    // Double size paddle
    double_paddle = DrawNode::create();
    float py = PADDLE_HEIGHT/2.0;
    float pxl = - PADDLE_WIDTH/2;
    float pxr =  PADDLE_WIDTH/2;
    double_paddle->drawSegment(Vec2(pxl*2, py), Vec2(pxr*2, py), py, Color4F(COLOR_grey));
    double_paddle->setPositionY(PADDLE_ALTURA);
    
    auto double_size = Size((PADDLE_WIDTH+PADDLE_HEIGHT)*2, PADDLE_HEIGHT);
    auto doubleBody = PhysicsBody::createBox(double_size, PhysicsMaterial(0.1f, 1.0f, 0.0f));
    doubleBody->setPositionOffset(Vec2(0, PADDLE_HEIGHT/2));
    doubleBody->setGravityEnable(false);
    doubleBody->setDynamic(false);
    doubleBody->setContactTestBitmask(0xFFFFFFFF);
    double_paddle->setTag(PADDLE_TAG);
    double_paddle->addComponent(doubleBody);
    addChild(double_paddle);
    
    // Normal size paddle
    normal_paddle = DrawNode::create();
    normal_paddle->drawSegment(Vec2(pxl, py), Vec2(pxr, py), py, Color4F(COLOR_grey));
    normal_paddle->setPositionY(PADDLE_ALTURA);
    
    auto normal_size = Size(PADDLE_WIDTH+PADDLE_HEIGHT, PADDLE_HEIGHT);
    auto normalBody = PhysicsBody::createBox(normal_size, PhysicsMaterial(0.1f, 1.0f, 0.0f));
    normalBody->setPositionOffset(Vec2(0, PADDLE_HEIGHT/2));
    normalBody->setGravityEnable(false);
    normalBody->setDynamic(false);
    normalBody->setContactTestBitmask(0xFFFFFFFF);
    normal_paddle->setTag(PADDLE_TAG);
    normal_paddle->addComponent(normalBody);
    addChild(normal_paddle);
    
    // Half size paddle
    half_paddle = DrawNode::create();
    half_paddle->drawSegment(Vec2(pxl/2.0, py), Vec2(pxr/2.0, py), py, Color4F(COLOR_grey));
    half_paddle->setPositionY(PADDLE_ALTURA);
    
    auto half__size = Size((PADDLE_WIDTH+PADDLE_HEIGHT)/2.0, PADDLE_HEIGHT);
    auto half_Body = PhysicsBody::createBox(half__size, PhysicsMaterial(0.1f, 1.0f, 0.0f));
    half_Body->setPositionOffset(Vec2(0, PADDLE_HEIGHT/2));
    half_Body->setGravityEnable(false);
    half_Body->setDynamic(false);
    half_Body->setContactTestBitmask(0xFFFFFFFF);
    half_paddle->setTag(PADDLE_TAG);
    half_paddle->addComponent(half_Body);
    addChild(half_paddle);
    
    normalSize();
    
    return true;
}

void Paddle::listen(double width) {
    
    // Registra eventos touch
    auto listener = EventListenerTouchOneByOne::create();
    
    // trigger when you push down
    listener->onTouchBegan = [=](Touch* touch, Event* event){
        setPX(touch->getLocation().x, width);
        return true; // if you are consuming it
    };
    
    // trigger when moving touch
    listener->onTouchMoved = [=](Touch* touch, Event* event){
        setPX(touch->getLocation().x, width);
    };
    
    // Add listener
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    
}

void Paddle::setPX(double px, double width) {
    double paddle_x =  PADDLE_WIDTH/2;
    switch (stade) {
        case HALF:
            paddle_x /=  2.0;
            break;
        case DOUBLE:
            paddle_x *=  2.0;
            break;
    }
    if (px >= paddle_x && px < width - paddle_x)
        this->setPositionX(px);
}

void Paddle::doubleSize() {
    if (stade == HALF) {
        normalSize();
        return;
    }
    stade = DOUBLE;
    double_paddle->getPhysicsBody()->setEnabled(true);
    double_paddle->setVisible(true);
    normal_paddle->getPhysicsBody()->setEnabled(false);
    normal_paddle->setVisible(false);
    half_paddle->getPhysicsBody()->setEnabled(false);
    half_paddle->setVisible(false);
    startNormalTimer();
}

void Paddle::halfSize() {
    if (stade == DOUBLE) {
        normalSize();
        return;
    }
    stade = HALF;
    double_paddle->getPhysicsBody()->setEnabled(false);
    double_paddle->setVisible(false);
    normal_paddle->getPhysicsBody()->setEnabled(false);
    normal_paddle->setVisible(false);
    half_paddle->getPhysicsBody()->setEnabled(true);
    half_paddle->setVisible(true);
    startNormalTimer();

}

void Paddle::normalSize() {
    stade = NORMAL;
    double_paddle->getPhysicsBody()->setEnabled(false);
    double_paddle->setVisible(false);
    normal_paddle->getPhysicsBody()->setEnabled(true);
    normal_paddle->setVisible(true);
    half_paddle->getPhysicsBody()->setEnabled(false);
    half_paddle->setVisible(false);
}

void Paddle::startNormalTimer() {
    auto delay = DelayTime::create(POWER_UP_PADDLE_SECONDS);
    CallFunc *runCallback = CallFunc::create(CC_CALLBACK_0(Paddle::normalSize, this));
    auto seq = Sequence::create(delay, runCallback, nullptr);
    runAction(seq);
}