
#ifndef AP_NAVIGATION_h
#define AP_NAVIGATION_h

#define XTRACK_GAIN 10 					// Amount to compensate for crosstrack (degrees/100 per meter)
#define XTRACK_ENTRY_ANGLE 3000			// Max angle used to correct for track following	degrees*100
#include <GPS.h>						// ArduPilot GPS Library
#include "Waypoints.h"					// ArduPilot Waypoints Library
#if defined(ARDUINO) && ARDUINO >= 100
	#include "Arduino.h"
#else
	#include "WProgram.h"
#endif

#define T7 10000000

class Navigation {
public:
	Navigation(GPS *withGPS, Waypoints *withWP);
	
	void 		update_gps(void);					// called 50 Hz
	void		set_home(Waypoints::WP loc);
	void		set_next_wp(Waypoints::WP loc);
	void 		load_first_wp(void);
	void 		load_wp_with_index(uint8_t i);
	void 		load_home(void);
	void		return_to_home_with_alt(uint32_t alt);

	void		reload_wp(void);
	void		load_wp_index(uint8_t i);
	void		hold_location();
	void		set_wp(Waypoints::WP loc);

	void		set_hold_course(int16_t b);				// -1 deisables, 0-36000 enables
	int16_t 	get_hold_course(void);

	int32_t 	get_distance(Waypoints::WP *loc1, Waypoints::WP *loc2);
	int32_t 	get_bearing(Waypoints::WP *loc1, Waypoints::WP *loc2);
	void		set_bearing_error(int32_t error);
	
	void		set_loiter_vector(int16_t v);
	void 		update_crosstrack(void);

	int32_t		wrap_180(int32_t error);			// utility
	int32_t		wrap_360(int32_t angle);			// utility
	
	int32_t		bearing;							// deg * 100 : 0 to 360 current desired bearing to navigate
	int32_t		distance;							// meters : distance plane to next waypoint
	int32_t		altitude_above_home;				// meters * 100 relative to home position
	int32_t		total_distance;						// meters : distance between waypoints
	int32_t 	bearing_error; 						// deg * 100 : 18000 to -18000 	
	int32_t 	altitude_error; 					// deg * 100 : 18000 to -18000 	

	int16_t		loiter_sum;
	Waypoints::WP 	home, location, prev_wp, next_wp;

private:
	void 		calc_int32_t_scaling(int32_t lat);
	void 		calc_bearing_error(void);
	void		calc_altitude_error(void);
	void		calc_distance_error(void);
	void 		calc_long_scaling(int32_t lat);
	void 		reset_crosstrack(void);

	int16_t		_old_bearing;						// used to track delta on the bearing
	GPS			*_gps;
	Waypoints	*_wp;
	int32_t 		_crosstrack_bearing;				// deg * 100 : 0 to 360 desired angle of plane to target
	float		_crosstrack_error;					// deg * 100 : 18000 to -18000  meters we are off trackline
	int16_t 	_hold_course;						// deg * 100 dir of plane
	int32_t 	_target_altitude;			// used for 
	int32_t 	_offset_altitude;			// used for 
	float		_altitude_estimate;
	float 		_scaleLongUp;				// used to reverse int32_ttitude scaling
	float 		_scaleLongDown;				// used to reverse int32_ttitude scaling	
	int16_t		_loiter_delta;
};


#endif // AP_NAVIGATION_h
