//
// Created by jovian on 18/07/17.
//

#include <iostream>
#include "Bullet.h"
#include "b2Angle.h"
#define DEFAULT_TIME_LIFE 480


Bullet::Bullet(const b2Vec2 &pos, b2World *physics, const b2Vec2 &dir, const b2Vec2 &speed, unsigned int camp)
        : Entity(BULLET, 0, physics),
          m_damageScale(0.015f), m_timeLife(DEFAULT_TIME_LIFE), m_camp(camp), m_aero(0.3f), m_dir(dir) {
    // Creation of physical body
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position = pos;
    bodyDef.angle = b2Angle(dir);
    bodyDef.fixedRotation = false;
    bodyDef.bullet = true;
    bodyDef.angularDamping = 5.0f;
    m_body = physics->CreateBody(&bodyDef);

    // Creation of triangle shape
    b2Vec2 vertices[3];
    vertices[0].Set(-9.0f / DEFAULT_ZOOM, 10.0f / DEFAULT_ZOOM);
    vertices[1].Set(9.8f / DEFAULT_ZOOM, 0.0f);
    vertices[2].Set(-9.0f / DEFAULT_ZOOM, -10.0f / DEFAULT_ZOOM);

    b2PolygonShape shape;
    shape.Set(vertices, 3);

    // Definition of fixture
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &shape;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.03f;
    fixtureDef.restitution = 0.1f;

    // Fixture filtering
    if (m_camp == 0)
        fixtureDef.filter.categoryBits = 0b0010;
    else if (m_camp == 1)
        fixtureDef.filter.categoryBits = 0b1000;

    fixtureDef.filter.maskBits = 0b1111;

    // Creation of fixture
    m_body->CreateFixture(&fixtureDef);

    // Initial propulsion
    m_body->SetLinearVelocity(speed);
    m_dir.Normalize();
    m_body->ApplyForceToCenter(10.0f * m_dir, true);

    // Appearance
    if (camp == 0)
        m_imgId = 12;
    else if (camp == 1)
        m_imgId = 14;

    // Link this bullet
    establishPhysicalLink();
}

void Bullet::update() {
    // Boost
    m_body->ApplyForceToCenter(m_aero * m_dir, true);

    // Existence
    if (m_timeLife == 0 || m_body->GetPosition().y > 100.0f)
        m_exist = false;
    else //if (!m_body->IsAwake())
        m_timeLife--;
}

int Bullet::getDamage() const {
    return (int) (m_damageScale * m_body->GetLinearVelocity().LengthSquared()) + 1;
}