#pragma once

#include <array>
#include <vector>

constexpr double degToRad(double degrees)
{
    return degrees * (3.14159265 / 180.0);
}

using stAxSpeed = struct _stAxSpeed
{
    double dStartSpeed{ 0. }; // axis start speed
    double dMaxSpeed{ 0. };   // axis max speed
    double dEndSpeed{ 0. };   // axis end speed
    // reserved
    double dSCurve{ 0.5 }; // s-curve
    double dAcc{ 0. };     // axis acceleration
    double dDec{ 0. };     // axis deceleration
};

using stPathSpeed = struct _stPathSpeed
{
    double dMaxSpeed{ 0. }; // path max speed
    double dEndSpeed{ 0. }; // path end speed
};

using stHelixPosition = struct _stHelixPosition
{
    // MUST be 3 elements: X, Y, Z
    std::array<double, 3> arrCenterPosition;
    std::array<double, 3> arrNormal;
    double                AngleDegree{ 0. }; // angle in degree
    double                deltaHeight{ 0. }; // height change
    double                endRadius{ 0. };   // end radius
    //
    stPathSpeed PathSpeed; // speed for each point
    //
    unsigned long ulDwell{ 0 }; // dwell time in ms
};

using stPointPosition = struct _stPointPosition
{
    // axis position for each point (number of position MUST match number of axis)
    std::vector<double> vecAxisPosition;
    stPathSpeed         PathSpeed; // speed for each point
    //
    unsigned long ulDwell{ 0 }; // dwell time in ms
};

using stMotionPath = struct _stMotionPath
{
    // point path
    std::vector<stPointPosition> vecPointPath; // list of axis position for each point
    std::vector<stHelixPosition> vecHelixPath; // list of helix position for each point
    // speed profile
    stAxSpeed AxSpeed;           // speed for each axis
    int       nId{};             // Point Table Id for ECAT
    bool      bUseAbsolutePos{}; // true: absolute position, false: relative position (default)
};