/** 
 * \file path.h
 * \brief path header file
 * \details File contains structures, enumerations and functions declarations for PATH regulators
 *
 * \author Juraj Golej
 * \version 1.0
 */


#ifndef PATH_H_
#define PATH_H_

#include "sam.h"
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
#include <drivers/pio/pio.h>
#include <drivers/pwm/pwm.h>
#include <drivers/timer/timer.h>
#include <utils/retcode/retcode.h>
#include <utils/assert/arm_assert.h>
#include <app/axis/axis.h>
#include <pins.h>
#include "path_cfg.h"

/** 
 * \brief PATH axis enumeration
 */
enum PATH_AXIS {
	PATH_AXIS_X, ///< Axis X
	PATH_AXIS_Y, ///< Axis Y
}; /* enum PATH_AXIS */

/** 
 * \brief Move end callback function
 */
typedef void (*path_move_end)(void);

/**
 * \brief Initialize application
 * 
 * \return \b enum \b retCode Return code value
 * \retval ENone everything OK
 * \retval EInvalidParameter Can't initialize PWM or TIMER periphery
 *
 * \note Call this function before anything else
 */
enum retCode PATH_init();

/**
 * \brief Execute free movement with defined speed
 *
 * \param[in] axis Selected axis
 * \param[in] speed Speed in mm/s
 * 
 * \return \b enum \b retCode Return code value
 * \retval ENone everything OK
 * \retval EInvalidParameter Defined speed is higher than maximum speed
 * \retval EDenied There is currently controlled movement (MOVE TO)
 */
enum retCode PATH_moveFree(const enum PATH_AXIS axis, const int16_t speed);

/**
 * \brief Execute controlled movement with defined absolute position and speed
 * 
 * \param[in] position Absolute position in mm
 * \param[in] speed Speed in mm/s
 * 
 * \return \b enum \b retCode Return code value
 * \retval ENone everything OK
 * \retval EInvalidParameter Defined speed is higher than maximum speed
 * \retval EDenied There is currently another controlled movement (MOVE TO) or free movement (MOVE FREE)
 */
enum retCode PATH_moveToAbs(const float posX, const float posY, const uint16_t speed, const uint16_t endSpeed);

/**
 * \brief Execute controlled movement with defined incremental position and speed
 * 
 * \param[in] position Incremental position in mm (can be negative)
 * \param[in] speed Speed in mm/s
 * 
 * \return \b enum \b retCode Return code value
 * \retval ENone everything OK
 * \retval EInvalidParameter Defined speed is higher than maximum speed
 * \retval EDenied There is currently another controlled movement (MOVE TO) or free movement (MOVE FREE)
 */
enum retCode PATH_moveToInc(const float posX, const float posY, const uint16_t speed, const uint16_t endSpeed);

/**
 * \brief Return pointer on X or Y axis structure
 *
 * \param[in] axis Selected X or Y axis
 * 
 * \return \b struct \b AXIS_app* Pointer on axis structure
 */
struct AXIS_app* PATH_getAxis(const enum PATH_AXIS axis);

/**
 * \brief Register user defined callback function for movement end
 *
 * \param[in] callback Pointer on callback function
 */
void PATH_registerCallback(path_move_end callback);

#endif /* PATH_H_ */