/*
 *  acm : an aerial combat simulator for X
 *  Copyright (C) 1991,1992  Riley Rainey
 *
 *  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.
 */

#ifndef _navaid_h
#define _navaid_h

#include "pm.h"

#ifdef navaid_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif

/**
 * Every navaid_Type station has a frequency encoded as int number
 * whose value is here indicated as "channel".
 * 
 * Channels in the range 0-199 encode frequency between 108.00 MHz
 * and 117.95 MHz (VOR, DME and ILS stations).
 * 
 * Channels in the range 200-529 encode frequency between 200 KHz
 * and 529 KHz (NDB stations).
 */

#define navaid_VOR_CHANNEL_MIN    0
#define navaid_VOR_CHANNEL_MAX  199
#define navaid_NDB_CHANNEL_MIN  200
#define navaid_NDB_CHANNEL_MAX  529


/**
 * Type of radio station. The following combination of flags are allowed:
 * 
 * navaid_LOC (possibly + navaid_LOC + navaid_GS)
 * navaid_DME
 * navaid_VOR (possibly + navaid_DME)
 * navaid_NDB (possibly + navaid_OMARKER|navaid_MMARKER|navaid_IMARKER)
 */
#define navaid_LOC      0x0001
#define navaid_VOR      0x0002
#define navaid_DME      0x0004
#define navaid_GS       0x0008
#define navaid_NDB      0x0010
#define navaid_OMARKER  0x0020
#define navaid_MMARKER  0x0040
#define navaid_IMARKER  0x0080

typedef int navaid_Channel;

typedef struct navaid_Type {
	
	/** Linked list of registered NAVAIDs. */
	struct navaid_Type *prev, *next;
	
	/** The zone (that is, the scenery) from which this NAVAID was read. */
	zone_Type *zone;
	
	/** Type of radio station. */
	unsigned short type;
	
	/** Identifier (e.g. "IHNL"). */
	char id[5];
	
	/** Channel number. */
	navaid_Channel frequency;
	
	/** Location of the station. */
	earth_LatLonAlt loc;
	
	/** Geocentric location of the station. */
	VPoint Sg;
	
	/**
	 * VOR station: magnetic bearing, that is local magnetic deviation,
	 * positive east. Localizer station: geographic bearing, normally aligned
	 * with its runway. Zero for any other type of station.
	 */
	double bearing;
	
	/** Beam width for localizers (rad). */
	double beam_width;
	
	/** Location of the glide-slope. */
	earth_LatLonAlt gs_loc;
	
	/** Angle of glide slope (rad). */
	double slope;
	
	/**
	 * Transform geocentric to local coordinates with the x axis facing the
	 * bearing direction.
	 */
	VMatrix lt;
	
	/**
	 * Transform geocentric to glide slope local coordinates.
	 */
	VMatrix gst;
	
} navaid_Type;

/**
 * Adds ILS to the internal list of known NAVAIDs.
 * @param zone Zone this ILS belongs to.
 * @param ident Station identifier; gets trunked to max 4 chars.
 * @param type Station type.
 * @param w Station location.
 * @param gsw Glide slope location.
 * @param freq Station frequency.
 * @param loc_width Localizer beam width (DEG).
 * @param loc_bearing Localizer geographic bearing (DEG).
 * @param gs_angle Glide slope angle (DEG).
 */
EXTERN void navaid_add_ils(zone_Type *zone, char *ident, char *type, earth_LatLonAlt * w,
	earth_LatLonAlt * gsw, double freq, double loc_width,
	double loc_bearing, double gs_angle);

/**
 * Adds VOR or NDB to the internal list of known NAVAIDs. On error, a message is
 * sent to stderr and the function returns non-zero.
 * @param zone Zone this NAVAID belongs to.
 * @param ident Station identifier; gets trunked to max 4 chars.
 * @param type Station type.
 * @param w Station location.
 * @param freq Station frequency.
 */
EXTERN void navaid_add_vor_dme_ndb(zone_Type *zone, char *ident, char *type, earth_LatLonAlt * w,
	double freq);

/**
 * Search for a NAVAID receivable at the frequency specified.
 * Return the station found, or NULL if no station can be received.
 */
EXTERN navaid_Type * navaid_reception_check(craft * c, navaid_Channel f);

/**
 * Releases all the NAVAIDs related to the specified zone.
 */
EXTERN void navaid_purgeZone(zone_Type *zone);

#undef EXTERN
#endif
