/**
 * The zone objects represents the contents of a cached scenery file.
 * 
 * ZONE LOADING AND CACHING.
 * A zone can be loaded or not loaded. When loaded, all the items of the scenery
 * (runways, navigation aids, ILS, features, ...) are available to the program.
 * When not loaded, all these elements are removed from memory.
 * 
 * The zones module uses zone objects to implement a scenery caching mechanism
 * where only the strictly needed sceneries are loaded in memory at any given
 * time based on the region each player (normally only one) is flying over;
 * nearby zone closer than 200 NM are loaded as well, so any tunable radio
 * station be available.
 * 
 * INSIDE/OUTSIDE ZONE DEFINITION.
 * As items are loaded from the scenery file, a consistency check is performed
 * and the location (lat,lon) of each item is compared against the state range
 * of latitude and longitude; the item is indeed inside the zone only if:
 * 
 *     LAT_MIN &le; lat &lt; LAT_MAX   and
 *     LON_MIN &le; lon &lt; LON_MAX
 * 
 * A non-fatal warning is sent on standard output if the location of the item
 * falls outside the range. Note that there is no way to include an item if it
 * is located exactly at the north pole; this does not seem to be a severe
 * limitation, though. For items located exactly on the 180E meridian, the
 * 180W can be indicated instead.
 * 
 * - VOR, DME and NDB are inside if their location is in the range.
 * 
 * - ILS are included based on the location of the LOCATOR antenna only;
 *   the location of the associate GS and DME antennas do not matter.
 * 
 * - Runways are included if their middle point lies in the range.
 * 
 * Note that a runway may belong to the zone but its corresponding ILS be outside
 * or vice-versa; this is not a problem as soon as the nearby zone including the
 * missing item be available, as in this case ACM loads both the zones anyway as
 * the aircraft gets close to the edge or within 200 NM from it.
 * 
 * SIDE EFFECTS OF THIS MODULE.
 * Several global data structures and modules are involved:
 * 
 * - The list of surface objects, including runways and features is constantly
 *   updated based on the sceneries currently loaded. This is the main task of
 *   this module.
 * 
 * - The list of NAVAIDs, including NDB, VOR and ILS, see the navaid module.
 * 
 * - The list of "craft types" used to store airports informations, see the
 *   inventory module.
 * 
 * @file
 * @author Umberto Salsi <salsi@icosaedro.it>
 * @version $Date: 2020/01/08 06:11:07 $
 */

#ifndef ZONE_H
#define ZONE_H

#include "../dis/dis/earth.h"

#ifdef zone_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif

/**
 * State of a zone.
 */
typedef struct zone_Type zone_Type;

/**
 * Allocates a new zone. The initial status of the zone is "not loaded".
 * @param path Scenery file.
 * @param lat1 Minimum latitude covered by this scenery (included, RAD).
 * @param lat2 Maximum latitude covered by this scenery (excluded, RAD).
 * @param lon1 Minimum longitude covered by this scenery (included, RAD).
 * @param lon2 Maximum longitude covered by this scenery (excluded, RAD).
 * @return Allocated new zone. Must be released with memory_dispose().
 */
EXTERN zone_Type * zone_new(char *path, double lat1, double lat2, double lon1, double lon2);

/**
 * Tells if this zone is currently loaded, that is the scenery file has been
 * parsed and the items therein defined are available to the player.
 */
EXTERN int zone_isLoaded(zone_Type *this);

/**
 * Returns the name of the file this zone has been (or might be) loaded from.
 */
EXTERN char * zone_getPath(zone_Type *this);

/**
 * Returns the ground color name defined in the zone. Returns NULL if the zone
 * is not currently loaded.
 */
EXTERN char * zone_getGroundColor(zone_Type *this);

/**
 * Returns the location of the force base.
 * @param this
 * @param force Force number, one of the DISForce enum constants.
 * @return Location of the force base if the zone is currently loaded and the
 * zone defines the requested team location; NULL otherwise.
 */
EXTERN earth_LatLonAlt * zone_getForceBaseLocation(zone_Type *this, int force);

/**
 * Returns true if the zone includes the point. Points over and beyond the
 * maximum latitude and longitude are outside.
 */
EXTERN int zone_includesLocation(zone_Type *this, earth_LatLonAlt *w);

/**
 * Returns true if the point p is flying over or it is close to the zone.
 * A point is close to this zone if it is inside or not farther than 4 DEG
 * from any of its borders; the test is implemented to be fast, not precise.
 * Altitude does not matter here.
 * @param this
 * @param p
 * @return True if close or inside the zone.
 */
EXTERN int zone_isClose(zone_Type *this, earth_LatLonAlt *p);

/**
 * Returns true is the zones overlaps, that is they share at least one point.
 */
EXTERN int zone_overlaps(zone_Type *this, zone_Type *other);

/**
 * Reads the scenery file and all the items therein defined. Recoverable errors
 * are sent to standard error; unrecoverable errors are fatal. The lists of
 * surface items, navaids and ILS are updated accordingly. If the zone is
 * already in its loaded status, simply postpones its expiry time.
 */
EXTERN void zone_load(zone_Type *this);

/**
 * Purge items related to the zone.The lists of surface items, navaids and ILS
 * are purged accordingly. Does nothing if the zone is already in its "not
 * loaded" status or the expiry time is not elapsed.
 * @param this
 * @param forced If true, overrides the internal expiry time caching mechanism
 * and really purges all items.
 */
EXTERN void zone_purge(zone_Type *this, int forced);

#undef EXTERN
#endif
