/*
REWRITTEN BY XINEF
*/

#ifndef TRINITY_RANDOMMOTIONGENERATOR_H
#define TRINITY_RANDOMMOTIONGENERATOR_H

#include "MovementGenerator.h"
#include "PathGenerator.h"

#define RANDOM_POINTS_NUMBER        12
#define RANDOM_LINKS_COUNT          7
#define MIN_WANDER_DISTANCE_GROUND  6.0f
#define MIN_WANDER_DISTANCE_AIR     10.0f
#define MAX_PATH_LENGHT_FACTOR      1.85f

template<class T>
class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovementGenerator<T> >
{
    public:
        RandomMovementGenerator(float spawnDist = 0.0f) : _nextMoveTime(0), _moveCount(0), _wanderDistance(spawnDist), _pathGenerator(NULL), _currentPoint(RANDOM_POINTS_NUMBER)
        {
            _initialPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
            _destinationPoints.reserve(RANDOM_POINTS_NUMBER);

            for (uint8 i = 0; i < RANDOM_POINTS_NUMBER; ++i)
            {
                _validPointsVector[i].reserve(RANDOM_LINKS_COUNT);
                for (uint8 j = 0; j < RANDOM_LINKS_COUNT; ++j)
                    _validPointsVector[i].push_back((i + j + RANDOM_POINTS_NUMBER/2 - RANDOM_LINKS_COUNT/2) % RANDOM_POINTS_NUMBER);
            }

            _validPointsVector[RANDOM_POINTS_NUMBER].reserve(RANDOM_POINTS_NUMBER);
            for (uint8 i = 0; i < RANDOM_POINTS_NUMBER; ++i)
                _validPointsVector[RANDOM_POINTS_NUMBER].push_back(i);
        }

        void _setRandomLocation(T*);
        void DoInitialize(T*);
        void DoFinalize(T*);
        void DoReset(T*);
        bool DoUpdate(T*, const uint32);
        bool GetResetPosition(float& x, float& y, float& z);
        MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; }

    private:
        TimeTrackerSmall _nextMoveTime;
        uint8 _moveCount;
        float _wanderDistance;
        PathGenerator* _pathGenerator;
        std::vector<G3D::Vector3> _destinationPoints;
        std::vector<uint8> _validPointsVector[RANDOM_POINTS_NUMBER+1];
        uint8 _currentPoint;
        std::map<uint16, Movement::PointsArray> _preComputedPaths;
        Position _initialPosition, _currDestPosition;
};
#endif
