/*Copyright (C) 2010 Deveaux Duncan

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Animation.hpp"

Animation::Animation() : m_ixFrame(0)
{
    
}

void Animation::render(sf::RenderWindow &renderWindow)
{
    renderWindow.Draw(m_renderImage);
}

void Animation::addFrame(sf::Image &frame, int frameIx)
{
    sf::Image *newFrame = &frame;
    
    if (frameIx == -1)
        m_framesList.push_back(newFrame);
    
    else if (frameIx >= 0 && frameIx <= static_cast<int>(m_framesList.size()) - 1)
        m_framesList[frameIx] = newFrame;
}

void Animation::removeFrame(int frameIx)
{
    if (frameIx >= 0 && frameIx <= static_cast<int>(m_framesList.size()) - 1)
        m_framesList.erase(m_framesList.begin() + frameIx);
}

void Animation::goToFrame(int frameIx)
{
    if (m_framesList.size() > 0)
    {
        if (frameIx < static_cast<int>(m_framesList.size()) && frameIx >= 0)
            m_ixFrame = frameIx;
        
        m_renderImage.SetImage(*m_framesList[m_ixFrame], true);
    }
}

void Animation::next()
{
    if (m_framesList.size() > 0)
    {
        int bufferFrame = m_ixFrame;
        
        if (bufferFrame < static_cast<int>(m_framesList.size()) - 1) bufferFrame++;
        else bufferFrame = 0;
        
        goToFrame(bufferFrame);
    }
}

void Animation::previous()
{
    if (m_framesList.size() > 0)
    {
        int bufferFrame = m_ixFrame;
        
        if (bufferFrame > 0) bufferFrame--;
        else bufferFrame = static_cast<int>(m_framesList.size()) - 1;
        
        goToFrame(bufferFrame);
    }
}

Animation Animation::loadFromDir(const std::string &dirPath, int framesNo)
{
    //Animation initialization
    Animation animation;
    
    //ImageManager initialization
    ImageManager *imageManager = ImageManager::getInstance();
    
    for (int i = 1; i <= framesNo; i++)
    {
        //Get image path
        std::ostringstream convertInt;
        convertInt << i;
        std::string frameName = dirPath + "f"+convertInt.str()+".png";
        
        //Get image and add it the animation
        animation.addFrame(*imageManager->getImage(frameName));
    }
    
    return animation;
}

//Get and set methods
int Animation::getFramesNo() const
{
    return m_framesList.size();
}

int Animation::getCurrentFrameIx() const
{
    return m_ixFrame;
}

void Animation::setOrigin(const sf::Vector2f &origin)
{
    m_renderImage.SetOrigin(origin);
}

const sf::Vector2f &Animation::getOrigin() const
{
    return m_renderImage.GetOrigin();
}

void Animation::flipX(bool flip)
{
    m_renderImage.FlipX(flip);
}

float Animation::getWidth() const
{
    return m_renderImage.GetSize().x;
}

float Animation::getHeight() const
{
    return m_renderImage.GetSize().y;
}

void Animation::setXPosition(float position)
{
    m_renderImage.SetX(position);
}

float Animation::getXPosition() const
{
    return m_renderImage.GetPosition().x;
}

void Animation::setYPosition(float position)
{
    m_renderImage.SetY(position);
}

float Animation::getYPosition() const
{
    return m_renderImage.GetPosition().y;
}