/*  -*-c++-*-
 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library 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
 * OpenSceneGraph Public License for more details.
*/

#ifndef OSGANIMATION_ANIMATION_MANAGER_BASE
#define OSGANIMATION_ANIMATION_MANAGER_BASE 1

#include <osgAnimation/LinkVisitor>
#include <osgAnimation/Animation>
#include <osgAnimation/Export>
#include <osg/FrameStamp>
#include <osg/Group>



namespace osgAnimation
{
    class OSGANIMATION_EXPORT AnimationManagerBase : public osg::NodeCallback
    {
    public:
        typedef std::set<osg::ref_ptr<Target> > TargetSet;

        AnimationManagerBase();
        AnimationManagerBase(const AnimationManagerBase& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY);
        virtual ~AnimationManagerBase();
        virtual void buildTargetReference();
        virtual void registerAnimation (Animation*);
        virtual void unregisterAnimation (Animation*);
        virtual void link(osg::Node* subgraph);
        virtual void update(double t) = 0;
        virtual bool needToLink() const;
        const AnimationList& getAnimationList() const { return _animations;}
        AnimationList& getAnimationList() { return _animations;}

        //uniformisation of the API
        inline Animation * getRegisteredAnimation(unsigned int i) { return _animations[i].get();}
        inline unsigned int getNumRegisteredAnimations() const { return _animations.size();}
        inline void addRegisteredAnimation(Animation* animation)
        {
            _needToLink = true;
            _animations.push_back(animation);
            buildTargetReference();
        }
        void removeRegisteredAnimation(Animation* animation);

        /** Callback method called by the NodeVisitor when visiting a node.*/
        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);

        /** Reset the value of targets
            this Operation must be done each frame */
        void clearTargets();

        LinkVisitor* getOrCreateLinkVisitor();
        void setLinkVisitor(LinkVisitor*);

        /// set a flag to define the behaviour
        void setAutomaticLink(bool);
        bool getAutomaticLink() const;
        bool isAutomaticLink() const { return getAutomaticLink(); }
        void dirty();

    protected:

        osg::ref_ptr<LinkVisitor> _linker;
        AnimationList _animations;
        TargetSet _targets;
        bool _needToLink;
        bool _automaticLink;
    };
}
#endif