/*
 *  acm - AutoPilot System module
 *  Copyright (C) 2007 Umberto Salsi
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 dated June, 1991.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program;  if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
 */

/**
 * Auto-Pilot System (APS). Implements the following features:
 * 
 * - AutoPilot (AP): hold altitude or hold climb ratio.
 * - AutoCoordination (AC): rudder control in turns.
 * - AutoTurn (AW): hold heading or hold turn ratio.
 * - AutoNavigation (AN): follow HSI OBS.
 * - AutoLanding (AL): follow ILS locator and glide plane.
 * - AutoThrottle (AT): throttle control to keep IAS.
 * - Rate control: pilot's stick position controls pitch ratio and roll ratio
 *   on a defined range.
 * 
 * Keeps the status of the APS in the 'aps' fields of the 'craft' type.
 * Each function may allocate the APS in the given craft if not already set,
 * no need to call any specific initialization function.
 */

#ifndef _aps_h
#define _aps_h

#include "pm.h"

#ifdef aps_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif

/**
 * Turns of  the APS.
 * @param c
 */
EXTERN void aps_off(craft * c);

/**
 * Enables AP: hold altitude (if climb ratio module less than +/-100 fpm) or
 * hold climb ratio.
 */
EXTERN void aps_ap_enable(craft * c);

/**
 * Disables AP.
 */
EXTERN void aps_ap_disable(craft * c);

/**
 * Returns true if AP is enabled.
 * @param c
 * @return 
 */
EXTERN _BOOL aps_ap_enabled(craft * c);

/**
 * AP enable/disable toggle.
 * @param c
 */
EXTERN void aps_ap_toggle(craft * c);

/**
 * Set AP climb ratio. If current climb ratio is less than +/-100 fpm, hold
 * altitude.
 * @param c
 * @param vs
 */
EXTERN void aps_ap_set_vs(craft * c, double vs /* m/s */);

/**
 * Returns the computed elevator correction as a number between -1.0 and +1.0.
 * Returns 0.0 if AP disabled.
 * @param c
 * @return 
 */
EXTERN double aps_get_delta_elevator(craft * c);

/**
 * Returns the computed ailerons correction as a number between-1.0 and +1.0.
 * Returns 0.0 if AP not enabled.
 * @param c
 * @return 
 */
EXTERN double aps_get_delta_ailerons(craft * c);

/** Enables AC. */
EXTERN void aps_ac_enable(craft * c);
/** Disables AC. */
EXTERN void aps_ac_disable(craft * c);
/** Toggles AC status. */
EXTERN void aps_ac_toggle(craft * c);
/** Returns true if AC currently enabled. */
EXTERN _BOOL aps_ac_enabled(craft * c);
/** AC calculated rudder correction [-1,+1], or zero if disabled. */
EXTERN double aps_ac_get_delta_rudder(craft * c);

/** Enables AT. */
EXTERN void aps_at_enable(craft * c);
/** Disables AT. */
EXTERN void aps_at_disable(craft * c);
/** Toggles AT status. */
EXTERN void aps_at_toggle(craft * c);
/** Returns true if AT currently enabled. */
EXTERN _BOOL aps_at_enabled(craft * c);
/** Returns AT current target IAS (ft/s). */
EXTERN double aps_at_get_velocity(craft * c);
/** Increments AT target IAS +5 KT. */
EXTERN void aps_at_inc_velocity(craft * c);
/** Decrements AT target IAS -5 KT. */
EXTERN void aps_at_dec_velocity(craft * c);

/** Increments maximum bank angle +5 DEG. Max is 25; default is 25. */
EXTERN void aps_bank_max_inc(craft * c);
/** Decrements maximum bank angle -5 DEG. Min is 5; default is 25. */
EXTERN void aps_bank_max_dec(craft * c);
/** Returns current maximum allowed bank angle in turns (DEG). */
EXTERN int aps_bank_max_get(craft * c);

/** Enables AW. */
EXTERN void aps_aw_enable(craft * c);
/** Disables AW. */
EXTERN void aps_aw_disable(craft * c);
/** Returns true if AW currently enabled. */
EXTERN _BOOL aps_aw_enabled(craft * c);

/**
 * Set AW turn rate around the current Earth vertical.
 * @param c
 * @param w Turn rate, left if positive (RAD/s).
 */
EXTERN void aps_aw_set(craft * c, double w);

/** Returns current AW rate (RAD/s). */
EXTERN double aps_aw_get(craft * c);

/** Enables AN. */
EXTERN void aps_an_enable(craft * c);
/** Disables AN. */
EXTERN void aps_an_disable(craft * c);
/** Toggles AN. */
EXTERN void aps_an_toggle(craft * c);
/** Returns true if AN currently enabled. */
EXTERN _BOOL aps_an_enabled(craft * c);

/** Enables AL on currently tuned ILS. Does nothing if no tuned ILS. */
EXTERN void aps_al_enable(craft * c);
/** Disables AL. */
EXTERN void aps_al_disable(craft * c);
/** Toggles AL. */
EXTERN void aps_al_toggle(craft * c);
/** Returns true if AL currently enabled. */
EXTERN _BOOL aps_al_enabled(craft * c);

/** Enables rate control. */
EXTERN void aps_rate_control_enable(craft * c);
/** Disables rate control. */
EXTERN void aps_rate_control_disable(craft * c);
/** Toggles rate control. */
EXTERN void aps_rate_control_toggle(craft * c);
/** Returns true if rate control currently enabled. */
EXTERN _BOOL aps_rate_control_enabled(craft * c);

/** Returns true if AP cannot attain the requested altitude or climb rate. */
EXTERN _BOOL aps_ap_warn(craft * c);
/** Returns true if AT cannot attain the requested speed. */
EXTERN _BOOL aps_at_warn(craft * c);
/** Returns true if AN cannot follow the VOR curse. */
EXTERN _BOOL aps_an_warn(craft * c);
/** Returns true if AL cannot follow the ILS locator or glide slope. */
EXTERN _BOOL aps_al_warn(craft * c);
/** Returns true if AW cannot attain the given turn rate. */
EXTERN _BOOL aps_aw_warn(craft * c);
/** Returns true if the AC cannot compensate lateral acceleration. */
EXTERN _BOOL aps_ac_warn(craft * c);

/**
 * Updates the internal state of the APS. Should be called frequently enough,
 * at least every 0.1 s. Does nothing if no APS enabled.
 * @param c
 */
EXTERN void aps_update(craft * c);

#undef EXTERN
#endif
