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

/**
 * This modules manages several data structures:
 * 
 * - Munitions defined in the munition file.
 * 
 * - Craft types. Crafts types includes: aircraft, airports (with each runway
 *   being represented by several polygons) and generic features from the scenery.
 *   Airports and features are related to some zone they were loaded from and
 *   can be added and removed along with the zones. Aircraft are defined in the
 *   corresponding configuration file.
 */

#ifndef _inventory_h
#define _inventory_h

#include "../V/Vlib.h"
#include "../V/VObjects.h"
#include "../dis/dis/dis.h"
#include "interpolate.h"
#include "manifest.h"
#include "zone.h"

#ifdef inventory_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif


/**
 * Maps munition entity/warhead combinations to explosions sizes and damage.
 */
typedef struct {
	dis_entity_type entity_type;
	dis_entity_type entity_mask;
	/** Type of warhead; currently always 1; no other values defined. */
	u_short         warhead_type;
	/** 0 = any, 1 = specific type of warhead. */
	u_short         warhead_mask;
	double          explosion_diameter_meters;
	double          damage_factor;
	/* If kinetic, only relative velocity matters; if blast type, only explosion
	 * diameter matters to asses damage. */
	int             kinetic_flag;
} munition_map;


typedef struct {
	int       id;               /* weapon type weapon_* */
	char     *type;             /* type of weapon at this station */
	int       info;             /* extra info (weapon specific) */
	int       info2;            /* "      " */
	int       info3;            /* "      " */
	double    info4;            /* time offset to next round firing (s) */
} weaponStation;


typedef enum {
	
	/** Glider. */
	inventory_NoEngine,
			
	/** Generic piston engine with propeller. */
	inventory_GenericPistonEngine,
			
	/** Generic jet engine. */
	inventory_GenericJetEngine,
			
	/** Generic rocket engine (thrust does not depends on air density). */
	inventory_GenericRocketEngine
			
} inventory_EngineType;

// Forward declaration.
struct craft;

/**
 * Function that calculates the current thrust for the aircraft and updates the
 * current RPM value based on the current throttle setting, afterburner status,
 * speed and altitude. There is one for each type of aircraft/engine.
 * @param cinfo Specific craft informations.
 * @return Current engine thrust (lbf).
 */
typedef double inventory_ThrustCalculator(struct craft *cinfo);

/*
 *  This structure describes a class of aircraft (e.g. an F-16C).
 */

typedef struct craftType {
	struct craftType *prev, *next;
	
	/**
	 * Zone this craft type belongs to. Set only for runways and features;
	 * NULL in any other type of "craft".
	 */
	zone_Type *zone;
	
	char     *name;             /* short name of aircraft class */
	char     *description;      /* long name */
	char     *modelname;        /* compiled object model to drive this aircraft type */

	double    aspectRatio;      /* wing aspect ratio */
	double    CLOrigin, CLSlope;  /* Defines the CL characteristic eqn */
	double    betaStall;        /* Stall angle for rudder */
	double    CDOrigin, CDFactor;    /* Defines the CD Characteristic eqn */
	interpolate_Table   *CLift;      /* compute lift coefficient */
	interpolate_Table   *CDb;        /* compute body + wave drag coeff */
	interpolate_Table   *CnBeta;     /* compute yaw moment due to sideslip */
	interpolate_Table   *ClBeta;     /* compute roll moment due to sideslip */
	double    CDBOrigin, CDBFactor;  /* Defines the CD Characteristic eqn */
	double    CDBPhase;
	double    CYbeta;           /* Side-force from side-slip (dCY/dBeta) */
	double    Clda;             /* roll moment from aileron offset */
	double    Cldr;             /* roll moment from rudder offset */
	double    Clp;              /* roll damping */

	double    Cmq;              /* damping in pitch */
	double    Cnr;              /* damping in yaw */

	double    maxAileron;       /* maximum aileron offset */
	double    maxRudder;        /* maximum rudder offset */

	double    effElevator;      /* Elevator effectiveness */
	double    effRudder;        /* Rudder effectiveness */

	VMatrix   I;                /* Moments of Inertia about CG in AXYZ (lb ft^2) */
	double    cmSlope;          /* CmAlpha curve slope */

	double    maxFlap;          /* maximum flap setting (RAD) */
	double    cFlap;            /* lift coefficient of flaps */
	double    cFlapDrag;        /* drag coefficient of lowered flaps */
	double    flapRate;         /* flap movement rate (RAD/s) */

	double    cGearDrag;        /* drag coefficient of lowered gear */
	double    gearRate;         /* landing gear movement rate (RAD/s) */

	double    maxSpeedBrake;    /* maximum speed brake setting (RAD) */
	double    cSpeedBrake;      /* drag coefficient of 90 degree speed brake */
	double    speedBrakeRate;   /* rate of speed brake movement (RAD/s) */
	double    speedBrakeIncr;   /* number of radians than one keystroke moves brake */

	double    wingS;            /* wing area (ft^2) */
	double    wings;            /* wing half-span (ft) */
	double    wingh;            /* wing areodyn. center height above the CM (ft) */
	double    c;                /* mean aerodynamic chord (MAC) (ft) */
	double    emptyWeight;      /* empty mass (lb) */
	double    maxLoadZPositive; /* max climb wing load (lbf) */
	double    maxLoadZNegative; /* max sink wing load (lbf) */
	double    maxFuel;          /* maximum internal fuel (lb) */

	inventory_EngineType engineType;
	double    maxThrust;        /* max static thrust, military power (lbf) */
	double    maxABThrust;      /* max static thrust, afterburner on  (lbf) */
	interpolate_Table   *Thrust;     /* Change in thrust due to mach number */
	interpolate_Table   *ABThrust;   /* Change in thrust due to mach number */
	int       hasThrustReverser;/* 0 = no, otherwise yes */
	double    engineLag;        /* controls lag between throttle and RPM */
	double    spFuelConsump;    /* specific fuel consump(lb fuel/lbf T x hr) */
	double    spABFuelConsump;
	VPoint    viewPoint;        /* pilot's viewing location wrt CG (ft) */

	double    muStatic;         /* static coefficient of friction no-brakes */
	double    muKinetic;        /* moving coefficient of friction no-brakes */
	double    muBStatic;        /* static brakes-on */
	double    muBKinetic;       /* moving brakes-on */

	double    maxNWDef;         /* maximum nose wheel deflection (RAD) */
	VPoint    rm, rn;           /* location if main/nose gear attachments */
	double    Dm, Dn;           /* main/nose oleo damping factor */
	double    Km, Kn;           /* main/nose oleo spring factor */
	double    Gm, Gn;           /* main/nose strut length with tire */
	double    cmMax, cnMax;     /* main/nose maximum oleo extension distance */
	VPoint    tailExtent;       /* as we rotate, this part may drag */

	/* Speed limits at MTOW (0.0 = unknown): */
	double    MTOW;             /* max takeoff weight (lb) */
	double    alpha_stall;      /* stall AoA (RAD) */
	double    Vs0;              /* stall speed, full flaps (kt) */
	double    Vs1;              /* stall speed, no flaps (kt) */
	double    Vfe;              /* max speed with flaps (kt) */
	double    Vno;              /* normal operation speed (kt) */
	double    Vne;              /* never exceed speed (kt) */

	double    armDelay;         /* arming delay for missiles */
	long      damageBits;       /* initial bit mask of damaged systems */
	long      structurePts;     /* maximum structural damage */

	double    radarOutput;      /* radar output (watts) */
	double    radarTRange;      /* tracking (lock) radar range (nm) */
	double    radarDRange;      /* detection radar range (nm) */
	double    TEWSThreshold;

	long      sCount;           /* number of weapon stations */
	VPoint    wStation[manifest_STATIONS];   /* weapon's stations (launch points) */
	weaponStation station[manifest_STATIONS];  /* what can be at each weapon station */

	inventory_ThrustCalculator *thrust;  /* computes current thrust */
	void    (*resupply) (struct craft *);  /* the plane's rearm & refuel procedure */
	int     (*placeProc) (Viewport *, struct craft *, VMatrix *, VPolySet *ps);
	
	/* Object placement procedure (for special craft; see place.c) */
	char     *objname;          /* name of file containing the object */
	VObject  *object;           /* what it looks like */
	dis_entity_type entityType; /* craft type used in DIS */
	dis_entity_type altEntityType;  /* alternate craft type used in DIS */
} craftType;

/**
 * Compile the aircraft inventory, DIS entity/munition maps.
 */
EXTERN void inventory_init(void);

/**
 * Returns next, empty available entry in the craft models table.
 * @param zone Zone the static items (runway, feature, ...) belongs to.
 * Leave to NULL for real aircraft types which, being mobile, are not bound to
 * any specific zone.
 * @return Empty and reset data structure.
 */
EXTERN craftType * inventory_craftTypeNew(zone_Type *zone);

/**
 * Releases a craft type. There is normally no need for the client to invoke
 * this function.
 */
EXTERN void inventory_craftTypeRelease(craftType *c);

/**
 * Search a specific craft type by zone and name.
 * @param zone Zone the craft belongs to: NULL for real aircraft; zone for
 * surface items (runways, features).
 * @param name Name of the craft type.
 * @return Found craft type, or NULL.
 */
EXTERN craftType * inventory_craftTypeSearchByZoneAndName(zone_Type *zone, char *name);

/**
 * Retrieves craft type informations. First look among the already known
 * aircraft (file objects/inventory) then search in objects/object-map.txt.
 * @param id
 * @return Craft type informations, or NULL if not found.
 */
EXTERN craftType * inventory_craftTypeSearchByEntityType(const dis_entity_type * id );

/**
 * Removes craft types belonging to the given zone.
 * @param zone
 */
EXTERN void inventory_purgeZone(zone_Type *zone);

/**
 * Returns munition at given index.
 * @param i Munition index, starting from 0.
 * @return Munition, or NULL if invalid index.
 */
EXTERN munition_map * inventory_getMunition(int i);

/**
 * Print on standard output a list of the currently defined aircraft types.
 */
EXTERN void inventory_printValidAircraft(void);

#undef EXTERN
#endif
