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

#include <math.h>
#include "pm.h"

#define terrain_IMPORT
#include "terrain.h"


static inline double sqr(double x)
{
	return x * x;
}


static double dist2(VPoint * a, VPoint *b)
{
	return sqr(a->x - b->x) + sqr(a->y - b->y) + sqr(a->z - b->z);
}


double terrain_localAltitude(craft *c)
{
	double    d2_min, d2, z;

	if( c->terrain_altitude_timeout > curTime )
		// Return the cached value.
		return c->terrain_altitude;
	
	// Schedule an update timeout as the aircraft moves at least 0.1 NM:
	double dt = 0.1*units_NmToFeetFactor / (fabs(c->Cg.x) + fabs(c->Cg.y) + 1);
	// ...but not too late because it might accelerate in the meanwhile:
	if( dt > 5 )  dt = 5;
	c->terrain_altitude_timeout = curTime + dt;

	// Search nearest runway within 100 NM. If none found, assume sea level.
	d2_min = sqr( units_NMtoMETERS(100) );
	z = 0.0; // Sea level.
	craft *rwy = stbl;
	while( rwy != NULL ){
		if( rwy->type == CT_SURFACE && (rwy->flags && FL_FIXED_OBJECT) ){
			// It is a runway.
			d2 = dist2(&c->Sg, &rwy->Sg);
			if( d2 < d2_min ){
				d2_min = d2;
				z = rwy->w.z;
			}
		}
		rwy = rwy->next;
	}

	// Save cached value:
	c->terrain_altitude = z;

	return z;
}
