/*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 "AnimationManager.hpp"

AnimationManager::AnimationManager() :
m_blockingAnimation(false), m_ixAnimation(0), m_ixBackAnimation(0), m_direction(0), m_directionAltered(false)
{
    
}

AnimationManager::AnimationManager(const std::string &animationsPath, const std::string &animationsListPath) :
m_blockingAnimation(false), m_ixAnimation(0), m_ixBackAnimation(0), m_direction(0), m_directionAltered(false)
{
    load(animationsPath, animationsListPath);
}

void AnimationManager::load(const std::string &animationsPath, const std::string &animationsListPath)
{
    loadAnimationsList(animationsPath, animationsListPath); //init the animations
    startAnimation(m_ixAnimation); //start the first (0) animation
}

void AnimationManager::startAnimation(int ixAnimation, bool blocking, int ixBackAnimation)
{
	//Will be updated in update()
    if (!m_blockingAnimation)
    {
        m_ixAnimation = ixAnimation;
        if (blocking)
        {
            m_ixBackAnimation = ixBackAnimation;
            m_blockingAnimation = true;
        }
    }
}

void AnimationManager::update()
{
    //Change frame
    m_animationsList[m_ixAnimation].next();
    
    //Start new animation if the old blocking one is finished
    if (m_blockingAnimation)
    {
        if (m_animationsList[m_ixAnimation].getCurrentFrameIx() == m_animationsList[m_ixAnimation].getFramesNo() - 1)
        {
            m_blockingAnimation = false;
            startAnimation(m_ixBackAnimation, false);
        }
    }
    
    //Adapt animation's direction
    if (m_directionAltered)
    {
        int newX;
        if (getDirection() == 0)
            newX = getXPosition() + getWidth();
        else
            newX = getXPosition() - getWidth();
        
        m_renderImage.SetX(newX);
        
        m_renderImage.FlipX(m_direction);
        m_directionAltered = false;
    }
    
    //Set frame's origin
    int yOrigin;
    yOrigin = getHeight();
    
    int xOrigin;
    if (getDirection() == 0) xOrigin = getWidth();
    else xOrigin = 0;
    
    m_renderImage.SetOrigin(xOrigin, yOrigin);
}

void AnimationManager::startRendering(GraphicsEngine &renderEngine)
{
    renderEngine.addObject(&m_renderImage);
}

void AnimationManager::stopRendering(GraphicsEngine &renderEngine)
{
    renderEngine.removeObject(&m_renderImage);
}

void AnimationManager::loadAnimationsList(const std::string &animationsPath, const std::string &animationsListPath)
{
    //TinyXML initialization
    TiXmlDocument animationsListXMLFile( animationsListPath.c_str() );
    animationsListXMLFile.LoadFile();
    
    TiXmlHandle handleXML(&animationsListXMLFile);
    TiXmlElement *animationsListXMLElements = handleXML.FirstChildElement().FirstChildElement().FirstChildElement().Element();
    
    while (animationsListXMLElements)
    {
        //Get informations about the animation (path, frames number)
        std::string animationName = animationsPath + animationsListXMLElements->Attribute("name") + "/";
        int framesNo;
        animationsListXMLElements->QueryIntAttribute("framesNo", &framesNo);
        
        //Create animation and register it in m_animationsList
        m_animationsList.push_back( Animation(animationName, framesNo, &m_renderImage) );
        
        animationsListXMLElements = animationsListXMLElements->NextSiblingElement();
    }
}

//Get and set methods
Animation *AnimationManager::getCurrentAnimation()
{
    return &m_animationsList[m_ixAnimation];
}

const sf::Vector2f &AnimationManager::getAnimationOrigin() const
{
    return m_renderImage.GetOrigin();
}

bool AnimationManager::isAnimationBlocking() const
{
    return m_blockingAnimation;
}

void AnimationManager::setDirection(int direction)
{
    if (direction == 0 || direction == 1)
    {
        m_directionAltered = true;
        m_direction = direction;
    }
}

int AnimationManager::getDirection() const
{
    return m_direction;
}

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

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

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

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

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

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