#include "SpielObjekt.h"
#include "Define.h"

// Inhalt der SpielObjekt Klasse aus SpielObjekt.h
// Konstruktor
SpielObjekt::SpielObjekt( ObjektStr *zStr )
    : Model2DObject()
{
    id = zStr->id;
    position = zStr->pos;
    rotation = zStr->rot;
    size = zStr->scale;
    style = zStr->style;
    stability = zStr->maxStability;
    energie = zStr->maxEnergie;
    maxStability = zStr->maxStability;
    maxEnergie = zStr->maxEnergie;
    energieRadius = zStr->energieRadius;
    reparatur = zStr->reparatur;
    akkuLeistung = zStr->akkuLeistung;
    team = 0;
    amLeben = 1;
    level = 1;
    ep = 0;
    nextSkillEp = 80;
    setCollision( ( style | 0x4 ) == style );
}

// Destruktor
SpielObjekt::~SpielObjekt()
{
    if( team )
        team->release();
}

// nicht constant
void SpielObjekt::addEp( float ep )
{
    this->ep += ep;
    while( this->ep >= nextSkillEp )
    {
        level++;
        this->ep -= nextSkillEp;
        nextSkillEp *= 1.025f;
    }
}

void SpielObjekt::setTeam( Team *team )
{
    if( this->team )
        this->team->release();
    this->team = team;
}

bool SpielObjekt::tick( const WeltInfo &info, double zeit )
{
    wInfo = info;
    if( !amLeben )
        return 0;
    repAbk -= zeit;
    if( repAbk < 0 )
        repAbk = 0;
    akkuAbk -= zeit;
    if( akkuAbk < 0 )
        akkuAbk = 0;
    if( !repAbk )
    {
        stability += reparatur * zeit;
        if( stability > maxStability )
            stability = maxStability;
    }
    if( !akkuAbk )
    {
        if( !team )
        {
            energie -= akkuLeistung * zeit;
            if( energie < 0 )
                energie = 0;
        }
        else
        {
            energie += akkuLeistung * zeit;
            if( energie > maxEnergie )
                energie = maxEnergie;
        }
    }
    if( ( style | 0x2 ) != style )
    {
        speed.x = 0;
        speed.y = 0;
        rSpeed = 0;
    }
    return Model2DObject::tick( info, zeit );
}

bool SpielObjekt::nimmSchaden( double &intensity, int sLevel )
{
    if( ( style | 0x1 ) != style )
    {
        intensity = 0;
        return 0;
    }
    double originalIntens = intensity;
    /*double schieldVal = intensity - intensity / calculateEnergieSchild();
    double schieldEVal = schieldVal / ( calculateEnergieSchildEffizienz() / 100 );
    if( schieldEVal > energie )
    {
        schieldEVal = energie;
        schieldVal = schieldEVal * ( calculateEnergieSchildEffizienz() / 100 );
    }
    intensity -= schieldVal;
    energie -= schieldEVal;*/
    stability -= intensity;
    akkuAbk = 1.5;
    repAbk = 2;
    if( stability <= 0 )
    {
        amLeben = 0;
        setCollision( 0 );
        stability = 0;
    }
    else if( doesShotAddEp() )
    {
        float levelFactor = (float)sLevel / (float)level;
        addEp( ( (float)originalIntens / 20 ) * levelFactor );
    }
    return stability == 0;
}

// constant
bool SpielObjekt::doesCollideWithLaser() const
{
    return ( style | 0x8 ) == style;
}

bool SpielObjekt::doesShotAddEp() const
{
    return ( style | 0x20 ) == style;
}

Team *SpielObjekt::zTeam() const
{
    if( ( style | 0x10 ) == style )
        return 0;
    return team;
}

bool SpielObjekt::istTreffer( Vec2< float > pos ) const
{
    if( !amLeben )
        return 0;
    return istPunktInnen( pos ) || istPunktInnen( pos + wInfo.size ) || istPunktInnen( pos + Punkt( wInfo.size.x, 0 ) ) || istPunktInnen( pos + Punkt( 0, wInfo.size.y ) ) ||
        istPunktInnen( pos + -wInfo.size ) || istPunktInnen( pos + Punkt( -wInfo.size.x, 0 ) ) || istPunktInnen( pos + Punkt( 0, -wInfo.size.y ) ) ||
        istPunktInnen( pos + Punkt( -wInfo.size.x, wInfo.size.y ) ) || istPunktInnen( pos + Punkt( wInfo.size.x, -wInfo.size.y ) );
}

int SpielObjekt::getLevel() const
{
    return level;
}

int SpielObjekt::getObjektId() const
{
    return id;
}