/**************************************************************************
 * hud.c -- hud defines and prototypes
 *
 * Written by Michele America, started September 1997.
 *
 * Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
 *
 * 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; either version 2 of the
 * License, or (at your option) any later version.
 *
 * 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.
 *
 * $Id$
 * (Log is kept at end of this file)
 **************************************************************************/
 

#include <GL/glut.h>
#include <stdlib.h>
#ifndef WIN32
#  include <values.h>  /* for MAXINT */
#endif /* not WIN32 */
#include "hud.h"

#include "../constants.h"

#include "../Aircraft/aircraft.h"
#include "../Scenery/mesh.h"
#include "../Scenery/scenery.h"
#include "../Math/mat3.h"
#include "../Math/polar.h"
#include "../Time/fg_timer.h"
#include "../Math/fg_random.h"
#include "../Weather/weather.h"

// #define DEBUG

#define drawOneLine(x1,y1,x2,y2)  glBegin(GL_LINES);  \
   glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd();
   
/* textString - Bitmap font string */

static void textString(int x, int y, char *msg, void *font)
{
	glRasterPos2f(x, y);
	while (*msg) {
		glutBitmapCharacter(font, *msg);
		msg++;
    }
}

/* strokeString - Stroke font string */

static void strokeString(int x, int y, char *msg, void *font)
{
	glPushMatrix();
	glTranslatef(x, y, 0);
	glScalef(.04, .04, .04);
	while (*msg) {
		glutStrokeCharacter(font, *msg);
		msg++;
	}
	glPopMatrix();
}

/*

	Draws a measuring scale anywhere on the HUD
		
	
	Needs: HUD_scale struct

*/
static void drawscale( int type, int sub_type, int min_value, int orientation, int scr_pos, \
		int scr_min, int scr_max, double total_amount, int min_div, int max_div, \
		double cur_value )
{
    double vmin, vmax;
    int marker_x, marker_y;
    int mid_scr;
    // int scale_min, scale_max;
    register i;
    double factor;
    char TextScale[80];
    int condition;

    vmin = cur_value-total_amount/2;
    vmax = cur_value+total_amount/2;
    
    mid_scr = scr_min+(scr_max-scr_min)/2;
    
    if( type == VERTICAL )     // Vertical scale
    {
        if( orientation == LEFT )
            marker_x = scr_pos-6;
        else if( orientation == RIGHT )
            marker_x = scr_pos;
        drawOneLine( scr_pos, scr_min, scr_pos, scr_max );
        if( orientation == LEFT )
        {
            drawOneLine( scr_pos-3, scr_min, scr_pos, scr_min );
            drawOneLine( scr_pos-3, scr_max, scr_pos, scr_max );
            drawOneLine( scr_pos, mid_scr, scr_pos+6, mid_scr );
        } else if( orientation == RIGHT )
        {
            drawOneLine( scr_pos, scr_min, scr_pos+3, scr_min );
            drawOneLine( scr_pos, scr_max, scr_pos+3, scr_max );
            drawOneLine( scr_pos, mid_scr, scr_pos-6, mid_scr );
        }

        factor = (scr_max-scr_min)/total_amount;

        for( i=vmin; i<=vmax; i+=1 )
        {
        	if( sub_type == LIMIT )
        		condition = i>= min_value;
        	else if( sub_type == NOLIMIT )
        		condition = 1;
        		
            if( condition )
            {
                marker_y = scr_min+(i-vmin)*factor;
                if( i%min_div==0 )
                    if( orientation == LEFT )
                    {
                    	drawOneLine( marker_x+3, marker_y, marker_x+6, marker_y );
                    }
                    else if( orientation == RIGHT )
                    {
                    	drawOneLine( marker_x, marker_y, marker_x+3, marker_y );
                    }
                if( i%max_div==0 )
                {
                	drawOneLine( marker_x, marker_y, marker_x+6, marker_y );
                    sprintf( TextScale, "%d", i );
                    if( orientation == LEFT )
                    {
                    	textString( marker_x-8*strlen(TextScale)-2, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
                    }
                    else if( orientation == RIGHT )
                    {
                    	textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
                    }
                }
            }
        }
    }
    if( type == HORIZONTAL )     // Horizontal scale
    {
        if( orientation == TOP )
            marker_y = scr_pos;
        else if( orientation == BOTTOM )
            marker_y = scr_pos-6;
        drawOneLine( scr_min, scr_pos, scr_max, scr_pos );
        if( orientation == TOP )
        {
        	drawOneLine( scr_min, scr_pos, scr_min, scr_pos-3 );
            drawOneLine( scr_max, scr_pos, scr_max, scr_pos-3 );
            drawOneLine( mid_scr, scr_pos, mid_scr, scr_pos-6 );
        } else if( orientation == BOTTOM )
        {
        	drawOneLine( scr_min, scr_pos, scr_min, scr_pos+3 );
            drawOneLine( scr_max, scr_pos, scr_max, scr_pos+3 );
            drawOneLine( mid_scr, scr_pos, mid_scr, scr_pos+6 );
        }

        factor = (scr_max-scr_min)/total_amount;

        for( i=vmin; i<=vmax; i+=1 )
        {
        	if( sub_type == LIMIT )
        		condition = i>= min_value;
        	else if( sub_type == NOLIMIT )
        		condition = 1;
        		
            if( condition )
            {
                marker_x = scr_min+(i-vmin)*factor;
                if( i%min_div==0 )
                    if( orientation == TOP )
                    {
                    	drawOneLine( marker_x, marker_y, marker_x, marker_y+3 );
                   	}
                    else if( orientation == BOTTOM )
                    {
                    	drawOneLine( marker_x, marker_y+3, marker_x, marker_y+6 );
                    }
                if( i%max_div==0 )
                {
                    sprintf( TextScale, "%d", i );
                    if( orientation == TOP )
                    {
                    	drawOneLine( marker_x, marker_y, marker_x, marker_y+6 );
                    	textString( marker_x-4*strlen(TextScale), marker_y+14, TextScale, GLUT_BITMAP_8_BY_13 );
                    }
                    else if( orientation == BOTTOM )
                    {
                    	drawOneLine( marker_x, marker_y, marker_x, marker_y+6 );
                    	textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
                    }
                }
            }
        }
    }

}              

/*

	Draws a climb ladder in the center of the HUD
		
	
	Needs: HUD_ladder struct

*/
static void drawladder( struct HUD_ladder ladder )
{
    double vmin, vmax;
    double roll_value, pitch_value;
    double cos_roll, sin_roll;
    int marker_x, marker_y;
    int mid_scr;
    int scr_min, scr_max;
    int x_ini, x_end;
    int y_ini, y_end;
    int new_x_ini, new_x_end;
    int new_y_ini, new_y_end;
    register i;
    double factor;
    char TextLadder[80];
    int condition;

	roll_value = (*ladder.load_roll)();
	pitch_value = (*ladder.load_pitch)()*RAD_TO_DEG;
	
    vmin = pitch_value-ladder.width_units/2;
    vmax = pitch_value+ladder.width_units/2;
    
    scr_min = ladder.y_pos-(ladder.scr_height/2);
    scr_max = scr_min+ladder.scr_height;
    
    mid_scr = scr_min+(scr_max-scr_min)/2;

	marker_x = ladder.x_pos-ladder.scr_width/2;
	
    factor = (scr_max-scr_min)/ladder.width_units;

    for( i=vmin; i<=vmax; i+=1 )
    {
    	condition = 1;
        if( condition )
        {
            marker_y = scr_min+(i-vmin)*factor;
            if( i%ladder.div_units==0 )
            {
            	sprintf( TextLadder, "%d", i );
            	if( ladder.scr_hole == 0 )
            	{
            		if( i != 0 )
               			x_ini = ladder.x_pos-ladder.scr_width/2;
               		else
               			x_ini = ladder.x_pos-ladder.scr_width/2-10;
               		y_ini = marker_y;
               		x_end = ladder.x_pos+ladder.scr_width/2;
               		y_end = marker_y;
           			new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
           				(y_ini-ladder.y_pos)*sin(roll_value);
           			new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
           				(y_ini-ladder.y_pos)*cos(roll_value);
           			new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
           				(y_end-ladder.y_pos)*sin(roll_value);
           			new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
           				(y_end-ladder.y_pos)*cos(roll_value);
   
   					if( i >= 0 )
   					{
            			drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
            		}
            		else
            		{
            			glEnable(GL_LINE_STIPPLE);
            			glLineStipple( 1, 0x00FF );
            			drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
            			glDisable(GL_LINE_STIPPLE);
            		}
                	textString( new_x_ini-8*strlen(TextLadder)-8, new_y_ini-4, TextLadder, GLUT_BITMAP_8_BY_13 );
                	textString( new_x_end+10, new_y_end-4, TextLadder, GLUT_BITMAP_8_BY_13 );
            	}
            	else
            	{
            		if( i != 0 )
               			x_ini = ladder.x_pos-ladder.scr_width/2;
               		else
               			x_ini = ladder.x_pos-ladder.scr_width/2-10;
               		y_ini = marker_y;
               		x_end = ladder.x_pos-ladder.scr_width/2+ladder.scr_hole/2;
               		y_end = marker_y;
           			new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
           				(y_ini-ladder.y_pos)*sin(roll_value);
           			new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
           				(y_ini-ladder.y_pos)*cos(roll_value);
           			new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
           				(y_end-ladder.y_pos)*sin(roll_value);
           			new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
           				(y_end-ladder.y_pos)*cos(roll_value);
            
            		if( i >= 0 )
            		{
            			drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
            		}
            		else
            		{
            			glEnable(GL_LINE_STIPPLE);
            			glLineStipple( 1, 0x00FF );
            			drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
            			glDisable(GL_LINE_STIPPLE);
            		}
            		textString( new_x_ini-8*strlen(TextLadder)-8, new_y_ini-4, TextLadder, GLUT_BITMAP_8_BY_13 );
            		
            		x_ini = ladder.x_pos+ladder.scr_width/2-ladder.scr_hole/2;
               		y_ini = marker_y;
               		if( i != 0 )
               			x_end = ladder.x_pos+ladder.scr_width/2;
               		else
               			x_end = ladder.x_pos+ladder.scr_width/2+10;
               		y_end = marker_y;
           			new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
           				(y_ini-ladder.y_pos)*sin(roll_value);
           			new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
           				(y_ini-ladder.y_pos)*cos(roll_value);
           			new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
           				(y_end-ladder.y_pos)*sin(roll_value);
           			new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
           				(y_end-ladder.y_pos)*cos(roll_value);
            
            		if( i >= 0 )
            		{
            			drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
            		}
            		else
            		{
            			glEnable(GL_LINE_STIPPLE);
            			glLineStipple( 1, 0x00FF );
            			drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
            			glDisable(GL_LINE_STIPPLE);
            		}
            		textString( new_x_end+10, new_y_end-4, TextLadder, GLUT_BITMAP_8_BY_13 );
            	}
            }
            /* if( i%max_div==0 )
            {
            	drawOneLine( marker_x, marker_y, marker_x+6, marker_y );
                sprintf( TextScale, "%d", i );
                if( orientation == LEFT )
                {
                	textString( marker_x-8*strlen(TextScale)-2, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
                }
                else if( orientation == RIGHT )
                {
                	textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
                }
            } */
        }
    }

}

/*

	Draws an artificial horizon line in the center of the HUD
		(with or without a center hole)
	
	Needs: x_center, y_center, length, hole

*/
static void drawhorizon( struct HUD_horizon horizon )
{
	int x_inc1, y_inc1;
	int x_inc2, y_inc2;
	struct FLIGHT *f;
	double sin_bank, cos_bank;
	double bank_angle;
              
	// f = &current_aircraft.flight;
	
	bank_angle = (*horizon.load_value)();

	// sin_bank = sin( FG_2PI-FG_Phi );
	// cos_bank = cos( FG_2PI-FG_Phi );
	sin_bank = sin(FG_2PI-bank_angle);
	cos_bank = cos(FG_2PI-bank_angle);
	x_inc1 = (int)(horizon.scr_width*cos_bank);
	y_inc1 = (int)(horizon.scr_width*sin_bank);
	x_inc2 = (int)(horizon.scr_hole*cos_bank);
	y_inc2 = (int)(horizon.scr_hole*sin_bank);
	
	if( horizon.scr_hole == 0 )
	{
		drawOneLine( horizon.x_pos-x_inc1, horizon.y_pos-y_inc1, \
						horizon.x_pos+x_inc1, horizon.y_pos+y_inc1 );
	}
	else
	{
		drawOneLine( horizon.x_pos-x_inc1, horizon.y_pos-y_inc1, \
						horizon.x_pos-x_inc2, horizon.y_pos-y_inc2 );
		drawOneLine( horizon.x_pos+x_inc2, horizon.y_pos+y_inc2, \
						horizon.x_pos+x_inc1, horizon.y_pos+y_inc1 );
	}	
}

/*

	Draws a label anywhere in the HUD
	
	Needs: HUD_label struct

*/	
static void drawlabel( struct HUD_label label )
{
	char buffer[80];
	char string[80];
	int posincr;
	int lenstr;
	
	if( label.pre_str != NULL && label.post_str != NULL )
		sprintf( buffer, "%s%s%s", label.pre_str, label.format, label.post_str );
	else if( label.pre_str == NULL && label.post_str != NULL )
		sprintf( buffer, "%s%s", label.format, label.post_str );
	else if( label.pre_str != NULL && label.post_str == NULL )
		sprintf( buffer, "%s%s", label.pre_str, label.format );

	sprintf( string, buffer, (*label.load_value)() );

#ifdef DEBUG	
	printf( buffer );
	printf( "\n" );
	printf( string );
	printf( "\n" );
#endif

	lenstr = strlen( string );
	if( label.justify == LEFT_JUST )
		posincr = -lenstr*8;
	else if( label.justify == CENTER_JUST )
		posincr = -lenstr*4;
	else if( label.justify == RIGHT_JUST )
		posincr = 0;
	
	if( label.size == SMALL )
		textString( label.x_pos+posincr, label.y_pos, string, GLUT_BITMAP_8_BY_13);
	else if( label.size == LARGE )
		textString( label.x_pos+posincr, label.y_pos, string, GLUT_BITMAP_9_BY_15);
	
}

double get_speed()
{
	struct FLIGHT *f;
              
	f = &current_aircraft.flight;
	return( FG_V_equiv_kts );
}

double get_aoa()
{
	struct FLIGHT *f;
              
	f = &current_aircraft.flight;
	return( FG_Gamma_vert_rad*RAD_TO_DEG );
}

double get_roll()
{
	struct FLIGHT *f;
              
	f = &current_aircraft.flight;
	return( FG_Phi );
}

double get_pitch()
{
	struct FLIGHT *f;
              
	f = &current_aircraft.flight;
	return( FG_Theta );
}

double get_heading()
{
	struct FLIGHT *f;
              
	f = &current_aircraft.flight;
	return( FG_Psi*RAD_TO_DEG ); 
}

double get_altitude()
{
	struct FLIGHT *f;
	double rough_elev;
              
	f = &current_aircraft.flight;
	rough_elev = mesh_altitude(FG_Longitude * RAD_TO_ARCSEC,
			                   FG_Latitude  * RAD_TO_ARCSEC);
                                                   
	return( FG_Altitude*FEET_TO_METER-rough_elev );
}

void add_instrument( Hptr hud, HIptr instrument )
{
	HIptr instruments;
	
	instruments = hud->instruments;
	// while( ++instruments
}

Hptr fgHUDInit( struct AIRCRAFT current_aircraft, int color )
{
	Hptr hud;
	
	hud = (Hptr)calloc(sizeof(struct HUD),1);
	if( hud == NULL )
		return( NULL );
		
	hud->code = 123;
	hud->status = 0;
	
	// For now lets just hardcode a hud here .
	// In the future, hud information has to come from the same place 
	// aircraft information came
	
	fgHUDAddHorizon( hud, 590, 50, 40, 20, get_roll );
	fgHUDAddScale( hud, VERTICAL, 220, 100, 280, 5, 10, LEFT, LEFT, 0, 100, get_speed );
	fgHUDAddScale( hud, VERTICAL, 440, 100, 280, 1, 5, RIGHT, RIGHT, -400, 25, get_aoa );
	fgHUDAddScale( hud, HORIZONTAL, 280, 220, 440, 5, 10, TOP, TOP, 0, 50, get_heading );
	fgHUDAddLabel( hud, 180, 85, SMALL, NOBLINK, RIGHT_JUST, NULL, " Kts", "%5.0f", get_speed );
	fgHUDAddLabel( hud, 180, 73, SMALL, NOBLINK, RIGHT_JUST, NULL, " m", "%5.0f", get_altitude );
	fgHUDAddLadder( hud, 330, 190, 90, 180, 70, 10, NONE, 45, get_roll, get_pitch );
	
	return( hud );
}

Hptr fgHUDAddHorizon( Hptr hud, int x_pos, int y_pos, int length, \
						int hole_len, double (*load_value)() )
{
#ifndef WIN32
	struct HUD_horizon *horizon;
	struct HUD_instr *instrument;
	HIptr tmp_first, tmp_next;
	
	tmp_first = hud->instruments;
	if( tmp_first != NULL )
		tmp_next = tmp_first->next;
	else
		tmp_next = NULL;
	
	instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
	if( instrument == NULL )
		return( NULL );
		
	horizon = (struct HUD_horizon *)calloc(sizeof(struct HUD_horizon),1);
	if( horizon == NULL )
		return( NULL );
	
	instrument->type = ARTIFICIAL_HORIZON;
	instrument->instr = *horizon;
	instrument->instr.horizon.x_pos = x_pos;
	instrument->instr.horizon.y_pos = y_pos;
	instrument->instr.horizon.scr_width = length;
	instrument->instr.horizon.scr_hole = hole_len;
	instrument->instr.horizon.load_value = load_value;
	instrument->next = tmp_first;

	hud->instruments = instrument;

	return( hud );
#endif
}

Hptr fgHUDAddScale( Hptr hud, int type, int scr_pos, int scr_min, int scr_max, int div_min, int div_max, \
					int orientation, int with_min, int min_value, int width_units, double (*load_value)() )
{
#ifndef WIN32
	struct HUD_scale *scale;
	struct HUD_instr *instrument;
	HIptr tmp_first, tmp_next;
	
	tmp_first = hud->instruments;
	if( tmp_first != NULL )
		tmp_next = tmp_first->next;
	else
		tmp_next = NULL;
	
	instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
	if( instrument == NULL )
		return( NULL );
		
	scale = (struct HUD_scale *)calloc(sizeof(struct HUD_scale),1);
	if( scale == NULL )
		return( NULL );
	
	instrument->type = SCALE;
	instrument->instr = *scale;
	instrument->instr.scale.type = type;
	instrument->instr.scale.scr_pos = scr_pos;
	instrument->instr.scale.scr_min = scr_min;
	instrument->instr.scale.scr_max = scr_max;
	instrument->instr.scale.div_min = div_min;
	instrument->instr.scale.div_max = div_max;
	instrument->instr.scale.orientation = orientation;
	instrument->instr.scale.with_minimum = with_min;
	instrument->instr.scale.minimum_value = min_value;
	instrument->instr.scale.width_units = width_units;
	instrument->instr.scale.load_value = load_value;
	instrument->next = tmp_first;

	hud->instruments = instrument;

	return( hud );
#endif
}

Hptr fgHUDAddLabel( Hptr hud, int x_pos, int y_pos, int size, int blink, int justify, \
					char *pre_str, char *post_str, char *format, double (*load_value)() )
{
#ifndef WIN32
	struct HUD_label *label;
	struct HUD_instr *instrument;
	HIptr tmp_first, tmp_next;
	
	tmp_first = hud->instruments;
	if( tmp_first != NULL )
		tmp_next = tmp_first->next;
	else
		tmp_next = NULL;
	
	instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
	if( instrument == NULL )
		return( NULL );
		
	label = (struct HUD_label *)calloc(sizeof(struct HUD_label),1);
	if( label == NULL )
		return( NULL );
	
	instrument->type = LABEL;
	instrument->instr = *label;
	instrument->instr.label.x_pos = x_pos;
	instrument->instr.label.y_pos = y_pos;
	instrument->instr.label.size = size;
	instrument->instr.label.blink = blink;
	instrument->instr.label.justify = justify;
	instrument->instr.label.pre_str = pre_str;
	instrument->instr.label.post_str = post_str;
	instrument->instr.label.format = format;
	instrument->instr.label.load_value = load_value;
	instrument->next = tmp_first;

	hud->instruments = instrument;

	return( hud );
#endif
}

Hptr fgHUDAddLadder( Hptr hud, int x_pos, int y_pos, int scr_width, int scr_height, \
					int hole_len, int div_units, int label_pos, int width_units, \
					double (*load_roll)(), double (*load_pitch)() )
{
#ifndef WIN32
	struct HUD_ladder *ladder;
	struct HUD_instr *instrument;
	HIptr tmp_first, tmp_next;
	
	tmp_first = hud->instruments;
	if( tmp_first != NULL )
		tmp_next = tmp_first->next;
	else
		tmp_next = NULL;
	
	instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
	if( instrument == NULL )
		return( NULL );
		
	ladder = (struct HUD_ladder *)calloc(sizeof(struct HUD_ladder),1);
	if( ladder == NULL )
		return( NULL );

	instrument->type = LADDER;
	instrument->instr = *ladder;
	instrument->instr.ladder.type = 0;	// Not used.
	instrument->instr.ladder.x_pos = x_pos;
	instrument->instr.ladder.y_pos = y_pos;
	instrument->instr.ladder.scr_width = scr_width;
	instrument->instr.ladder.scr_height = scr_height;
	instrument->instr.ladder.scr_hole = hole_len;
	instrument->instr.ladder.div_units = div_units;
	instrument->instr.ladder.label_position = label_pos;
	instrument->instr.ladder.width_units = width_units;
	instrument->instr.ladder.load_roll = load_roll;
	instrument->instr.ladder.load_pitch = load_pitch;
	instrument->next = tmp_first;

	hud->instruments = instrument;

	return( hud );
#endif
}

/*
Hptr fgHUDAddMovingHorizon( Hptr hud, int x_pos, int y_pos, int length, int hole_len, \
						int color )
{

}

Hptr fgHUDAddCircularLadder( Hptr hud, int scr_min, int scr_max, int div_min, int div_max, \
						int max_value )
{

}

Hptr fgHUDAddNumDisp( Hptr hud, int x_pos, int y_pos, int size, int color, int blink, \
						char *pre_str, char *post_str )
{

}
*/

void fgUpdateHUD( Hptr hud )
{
	HIptr hud_instr;
	union HUD_instr_data instr_data;
              
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();

	glLoadIdentity();
	gluOrtho2D(0, 640, 0, 480);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
         
	glColor3f(1.0, 1.0, 1.0);
	glIndexi(7);
              
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
                  
	glLineWidth(1);
	glColor3f (0.1, 0.9, 0.1);
                      
#ifdef DEBUG    
    printf( "HUD Code %d  Status %d\n", hud->code, hud->status ); 
#endif
    hud_instr = hud->instruments;
	while( hud_instr != NULL )
	{
		instr_data = hud_instr->instr;
#ifdef DEBUG
		printf("Instr Type %d   SubType %d  Orient %d\n", hud_instr->type, hud_instr->sub_type, hud_instr->orientation );
#endif
		if( hud_instr->type == ARTIFICIAL_HORIZON )
		{
			drawhorizon( instr_data.horizon );
		  	/* drawhorizon( instr_data.horizon.x_pos, instr_data.horizon.y_pos, \
    				instr_data.horizon.scr_width, instr_data.horizon.scr_hole ); */
    	}
    	else if( hud_instr->type == SCALE )
    	{
    		drawscale( instr_data.scale.type, instr_data.scale.with_minimum, \
    				instr_data.scale.minimum_value, instr_data.scale.orientation, \
    				instr_data.scale.scr_pos, instr_data.scale.scr_min, \
    				instr_data.scale.scr_max, instr_data.scale.width_units, \
    				instr_data.scale.div_min, instr_data.scale.div_max, \
					(*instr_data.scale.load_value)() );     				
    	}
    	else if( hud_instr->type == LABEL )
    	{
    		drawlabel( instr_data.label );
    		/* drawlabel( instr_data.label.x_pos, instr_data.label.y_pos, instr_data.label.size, \
    				instr_data.label.blink, instr_data.label.pre_str, instr_data.label.post_str, \
    				instr_data.label.format, (*instr_data.label.load_value)() ); */
    	}
    	else if( hud_instr->type == LADDER )
    	{
    		drawladder( instr_data.ladder );
    	}
    	hud_instr = hud_instr->next;
    }
    
    
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
                
}


/* $Log$
/* Revision 1.4  1997/09/23 00:29:32  curt
/* Tweaks to get things to compile with gcc-win32.
/*
 * Revision 1.3  1997/09/05 14:17:26  curt
 * More tweaking with stars.
 *
 * Revision 1.2  1997/09/04 02:17:30  curt
 * Shufflin' stuff.
 *
 * Revision 1.1  1997/08/29 18:03:22  curt
 * Initial revision.
 *
 */