#include "Texture2D.h"

#include "Animation.h"
#include "Image.h"

using namespace Framework;

// Contents of the Texture2D class from Texture2D.h

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

// Destructor
Texture2D::~Texture2D()
{
    if (txt) txt->release();
    for (auto i : *animData)
    {
        i->data->release();
        delete i;
    }
    animData->release();
}

// specifies whether the animation should repeat automatically
//  ca: 1 if the animation should repeat automatically
void Texture2D::setCircularAnimation(bool ca)
{
    circularAnimation = ca;
}

// sets a pointer to the texture (if not animated)
//  textur: The pointer to the image
void Texture2D::setTextureZ(Image* texture)
{
    if (txt) txt->release();
    txt = texture;
}

// adds an animation
//  textur: The pointer to the animation data
void Texture2D::addAnimationZ(Animation2DData* texture)
{
    animData->add(new Animation{texture, 0, 0});
}

// sets the current animation
//  index: The index of the animation
void Texture2D::setAnimation(int index)
{
    if (animationIndex == index) return;
    if (animationIndex != -1)
    {
        animData->get(animationIndex)->now = 0;
        animData->get(animationIndex)->compensation = 0;
    }
    animationIndex = index;
    int anz = animData->getEntryCount();
    if (animationIndex >= anz && (!circularAnimation || anz == 0))
        animationIndex = -1;
    else if (animationIndex >= anz)
        animationIndex = 0;
}

// activates the next animation
void Texture2D::nextAnimation()
{
    if (animationIndex != -1)
    {
        animData->get(animationIndex)->now = 0;
        animData->get(animationIndex)->compensation = 0;
    }
    animationIndex++;
    int anz = animData->getEntryCount();
    if (animationIndex >= anz && (!circularAnimation || anz == 0))
        animationIndex = -1;
    else if (animationIndex >= anz)
        animationIndex = 0;
}

// sets the elapsed time since the last call
//  t: the elapsed time in seconds
bool Texture2D::tick(double t)
{
    if (animationIndex != -1)
    {
        Animation* a = animData->get(animationIndex);
        a->compensation += t;
        int tmp = a->now;
        int tmp2 = animationIndex;
        a->data->readLock().lock();
        if (a->compensation >= 1.0 / a->data->getFPS())
        {
            a->compensation -= 1.0 / a->data->getFPS();
            if (++(a->now) >= a->data->getImageCount())
            {
                a->now = 0;
                if (!a->data->isRepeating()) nextAnimation();
            }
        }
        a->data->readLock().unlock();
        if (tmp != a->now || tmp2 != animationIndex) return 1;
    }
    return 0;
}

// returns the current texture
Image* Texture2D::zTexture() const
{
    if (animationIndex != -1)
        return animData->get(animationIndex)
            ->data->zImage(animData->get(animationIndex)->now);
    return txt;
}