//
//  SequenceActions.hpp
//  Meteor
//
//  Created by Cesar Parent on 27/08/2015.
//  Copyright © 2015 Cesar Parent. All rights reserved.
//

#ifndef SequenceActions_hpp
#define SequenceActions_hpp

#include "TimedActions.h"
#include <initializer_list>
#include <vector>
#include "../Nodes/Node.h"

NS_BEGIN

/*!
 * @internal
 * @brief           ActionRepeat repeats an action an infinite amount of times until it is removed
 *                  from its target node.
 */
class ActionRepeat : public Action {
    
public:
    
    /*!
 * @internal
     * @brief       Creates a repeat action with a given action.
     * @param       action      Action to repeat.
     */
    ActionRepeat(ARC<Action> action);
    
    /*
     * @brief       ActionRepeat destructor
     */
    virtual ~ActionRepeat();
    
    /*!
 * @internal
     * @brief       Registers the target.
     */
    virtual void
    registerTarget(Node* target) override;
    
    /*!
 * @internal
     * @brief       Update method. handles re-playing the repeated action.
     * @param       delta       Time elapsed since the last frame in seconds.
     */
    virtual void
    update(double delta) override;
    
    virtual void
    start() override;
    
    virtual bool
    done() const override { return false; }
    
private:
    
    ARC<Action>     _action;
    
};


class ActionSequence : public Action {
    
public:
    
    ActionSequence(std::initializer_list<ARC<Action>> actions);
    
    virtual ~ActionSequence();
    
    virtual void
    registerTarget(Node* target) override;
    
    virtual void
    update(double delta) override;
    
    virtual void
    start() override;
    
    virtual bool
    done() const override { return _currentAction >= _actions.size(); }
    
private:
    
    std::vector<ARC<Action>>    _actions;
    
    unsigned int                _currentAction;
};

class ActionWait : public TimedAction {
    
public:
    
    ActionWait(double duration) : TimedAction(duration) {}
    
    virtual ~ActionWait() {}
};

class ActionRemove : public Action {
public:
    
    ActionRemove() : _ran(false) {}
    
    virtual ~ActionRemove() {}
    
    virtual void
    start() override { _ran = false; }
    
    virtual void
    update(double delta) override {
        CPNullCheck(_target);
        if(!_ran) {
            _target->removeFromParent();
            _ran = true;
        }
    }
    
    virtual bool
    done() const override { return _ran; }
    
private:
    
    bool _ran;
};


NS_END

#endif /* SequenceActions_hpp */
