#ifndef PQABSTRACTANIMATION_H
#define PQABSTRACTANIMATION_H

#include <pqobject.h>
#include <QAbstractAnimation>

#define PQANIMATION_ON_SIGNALS()\
    PQ_ADD_ON_SIGNAL("onFinished", "finished()");\
    PQ_ADD_ON_SIGNAL("onStateChanged", "stateChanged(int,int)");\
    PQ_ADD_ON_SIGNAL("onCurrentLoopChanged", "currentLoopChanged(int,int)");\
    PQ_ADD_ON_SIGNAL("onStateChanged", "stateChanged(int,int)");\
    PQ_ADD_ON_SIGNAL("onDirectionChanged", "directionChanged(int)");\

#define PQ_AANIMATION_EX(T) \
    Q_PROPERTY(int state READ state)\
    Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount)\
    Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime)\
    Q_PROPERTY(int currentLoop READ currentLoop)\
    Q_PROPERTY(int direction READ direction WRITE setDirection)\
    \
public: \
    Q_INVOKABLE int state() const; \
    Q_INVOKABLE int direction() const; \
    Q_INVOKABLE void setDirection(int direction);\
    Q_INVOKABLE int currentTime() const;\
    Q_INVOKABLE int currentLoopTime() const;\
    Q_INVOKABLE int loopCount() const;\
    Q_INVOKABLE void setLoopCount(int loopCount);\
    Q_INVOKABLE int currentLoop() const;\
    Q_INVOKABLE int totalDuration() const;\
    \
public Q_SLOTS:\
    Q_INVOKABLE void start(int policy = QAbstractAnimation::KeepWhenStopped);\
    Q_INVOKABLE void pause();\
    Q_INVOKABLE void resume();\
    Q_INVOKABLE void setPaused(bool paused);\
    Q_INVOKABLE void stop();\
    Q_INVOKABLE void setCurrentTime(int msecs);\
    \
    void finished_pslot();\
    void stateChanged_pslot(int newState, int oldState);\
    void currentLoopChanged_pslot(int currentLoop);\
    void directionChanged_pslot(int direction);

#define PQ_ANIMATION_EX(T) \
    PQ_AANIMATION_EX(T)\
    \
protected:\
    Q_INVOKABLE virtual void updateCurrentTime(int currentTime);\
    \
public: \
    Q_INVOKABLE virtual int duration() const;

#define PQ_VANIMATION_EX(T) \
    PQ_ANIMATION_EX(T) \
    \
private:\
    Q_PROPERTY(int easingCurveType READ easingCurveType WRITE setEasingCurveType)\
    Q_PROPERTY(int duration READ duration WRITE setDuration)\
    \
public: \
    Q_INVOKABLE void setStartValue(const QVariant &value);\
    Q_INVOKABLE void setStartPointValue(int x, int y);\
    Q_INVOKABLE void setStartSizeValue(int width, int height);\
    Q_INVOKABLE void setStartRectValue(int x, int y, int width, int height);\
    Q_INVOKABLE void setEndValue(const QVariant &value);\
    Q_INVOKABLE void setEndPointValue(int x, int y);\
    Q_INVOKABLE void setEndSizeValue(int width, int height);\
    Q_INVOKABLE void setEndRectValue(int x, int y, int width, int height);\
    Q_INVOKABLE void setEasingCurveType(int easing);\
    Q_INVOKABLE int easingCurveType();\
    Q_INVOKABLE void setDuration(int msecs);\

class PQAbstractAnimation;
class PQAbstractAnimation : public QAbstractAnimation {
    Q_OBJECT
    PQ_OBJECT_EX(QAbstractAnimation)
    PQ_AANIMATION_EX(QAbstractAnimation)

public:
    Q_INVOKABLE explicit PQAbstractAnimation(QObject *parent = 0);
    ~PQAbstractAnimation() {}

protected:
    void updateCurrentTime(int currentTime) {}

public:
    int duration() const { return 0; }
};

#endif // PQABSTRACTANIMATION_H
