#include "Textur2D.h"
#include "Bild.h"
#include "Animation.h"

using namespace Framework;
// inhalt der Textur2D Klasse aus Textur2D.h

// Konstructor
Textur2D::Textur2D()
{
    circularAnimation = 0;
    animationIndex = -1;
    txt = 0;
    animData = new Array< Animation* >();
    ref = 1;
}

// Destructor
Textur2D::~Textur2D()
{
    if( txt )
        txt->release();
    for( auto i = animData->getIterator(); i; i++ )
    {
        i->data->release();
        delete i;
    }
    animData->release();
}

// Legt fest, ob die animation sich automatisch wiederhohlen soll
//  ca: 1, falls sich die animation automatisch wiederhohlen soll
void Textur2D::setCircularAnimation( bool ca )
{
    circularAnimation = ca;
}

// setzt einen Zeiger auf die Textur (fals nicht animiert)
//  textur: Der Zeiger auf das Bild
void Textur2D::setTexturZ( Bild *textur )
{
    if( txt )
        txt->release();
    txt = textur;
}

// f�gt eine Animation hinzu
//  textur: Der Zeiger auf die Animationsdaten
void Textur2D::addAnimationZ( Animation2DData *textur )
{
    animData->add( new Animation{ textur, 0, 0 } );
}

// setzt die aktuelle Annimation
//  index: Der Index der Animation
void Textur2D::setAnimation( int index )
{
    if( animationIndex == index )
        return;
    if( animationIndex != -1 )
    {
        animData->get( animationIndex )->jetzt = 0;
        animData->get( animationIndex )->ausgleich = 0;
    }
    animationIndex = index;
    int anz = animData->getEintragAnzahl();
    if( animationIndex >= anz && ( !circularAnimation || anz == 0 ) )
        animationIndex = -1;
    else if( animationIndex >= anz )
        animationIndex = 0;
}

// aktiviert die nachfolgende animation
void Textur2D::nextAnimation()
{
    if( animationIndex != -1 )
    {
        animData->get( animationIndex )->jetzt = 0;
        animData->get( animationIndex )->ausgleich = 0;
    }
    animationIndex++;
    int anz = animData->getEintragAnzahl();
    if( animationIndex >= anz && ( !circularAnimation || anz == 0 ) )
        animationIndex = -1;
    else if( animationIndex >= anz )
        animationIndex = 0;
}

// setzt die vergangene Zeit seit dem letzten Aufruf
//  t: die vergangene Zeit in sekunden
bool Textur2D::tick( double t )
{
    if( animationIndex != -1 )
    {
        Animation *a = animData->get( animationIndex );
        a->ausgleich += t;
        int tmp = a->jetzt;
        int tmp2 = animationIndex;
        a->data->lock();
        if( a->ausgleich >= 1.0 / a->data->getFPS() )
        {
            a->ausgleich -= 1.0 / a->data->getFPS();
            if( ++(a->jetzt) >= a->data->getBildAnzahl() )
            {
                a->jetzt = 0;
                if( !a->data->istWiederhohlend() )
                    nextAnimation();
            }
        }
        a->data->unlock();
        if( tmp != a->jetzt || tmp2 != animationIndex )
            return 1;
    }
    return 0;
}

// gibt die aktuelle Textur zur�ck
Bild *Textur2D::zTextur() const
{
    if( animationIndex != -1 )
        return animData->get( animationIndex )->data->zBild( animData->get( animationIndex )->jetzt );
    return txt;
}

// erh�ht den Reference Counter um 1 und gibt this zur�ck
Textur2D *Textur2D::getThis()
{
    ref++;
    return this;
}

// verringert den reference counter um 1 und l�scht sich selbst, falls er 0 erreicht
//  gibt 0 zur�ck
Textur2D *Textur2D::release()
{
    if( !--ref )
        delete this;
    return 0;
}