/********************************************************************
** @source JEEPS output functions
**
** @author Copyright (C) 1999 Alan Bleasby
** @version 1.0 
** @modified Dec 28 1999 Alan Bleasby. First version
** @@
** 
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Library General Public
** License as published by the Free Software Foundation; either
** version 2 of the License, or (at your option) any later version.
** 
** This library 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
** Library General Public License for more details.
** 
** You should have received a copy of the GNU Library General Public
** License along with this library; if not, write to the
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA  02111-1307, USA.
********************************************************************/
#include "gps.h"
#include <stdio.h>
#include <time.h>


static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf);
static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf);

static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf);
static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf);
static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf);

static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf);


char *gps_marine_sym[]=
{
    "Anchor","Bell","Diamond-grn","Diamond_red","Dive1","Dive2","Dollar",
    "Fish","Fuel","Horn","House","Knife","Light","Mug","Skull",
    "Square_grn","Square_red","Wbuoy","Wpt_dot","Wreck","Null","Mob",

    "Buoy_amber","Buoy_blck","Buoy_blue","Buoy_grn","Buoy_grn_red",
    "Buoy_grn_wht","Buoy_orng","Buoy_red","Buoy_red_grn","Buoy_red_wht",
    "Buoy_violet","Buoy_wht","Buoy_wht_grn","Buoy_wht_red","Dot","Rbcn",

    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","","","","","","","","","",
    "","",

    "Boat_ramp","Camp","Toilets","Showers","Drinking_wtr","Phone",
    "1st_aid","Info","Parking","Park","Picnic","Scenic","Skiing",
    "Swimming","Dam","Controlled","Danger","Restricted","Null_2","Ball",
    "Car","Deer","Shpng_trolley","Lodging","Mine","Trail_head",
    "Lorry_stop","User_exit","Flag","Circle-x"
};



char *gps_land_sym[]=
{
    "Is_hwy","Us_hwy","St_hwy","Mi_mrkr","Trcbck","Golf","Sml_cty",
    "Med_cty","Lrg_cty","Freeway","Ntl_hwy","Cap_cty","Amuse_pk",
    "Bowling","Car_rental","Car_repair","Fastfood","Fitness","Film",
    "Museum","Chemist","Pizza","Post_ofc","Rv_park","School",
    "Stadium","Shop","Zoo","Petrol_plus","Theatre","Ramp_int",
    "St_int","","","Weigh_stn","Toll_booth","Elev_pt","Ex_no_srvc",
    "Geo_place_mm","Geo_place_wtr","Geo_place_lnd","Bridge","Building",
    "Cemetery","Church","Civil_loc","Crossing","Hist_town","River_Embankment",
    "Military_loc","Oil_field","Tunnel","Beach","Forest","Summit",
    "Lrg_ramp_int","Lrg_exit_no_srvc","Official_badge","Gambling",
    "Snow_ski","Ice_ski","Tow_truck","Border"
};


char *gps_aviation_sym[]=
{
    "Airport","Int","Ndb","Vor","Heliport","Private","Soft_fld",
    "Tall_tower","Short_tower","Glider","Ultralight","Parachute",
    "Vortac","Vordme","Faf","Lom","Map","Tacan","Seaplane"
};


char *gps_16_sym[]=
{
    "Dot","House","Fuel","Car","Fish","Boat","Anchor","Wreck",
    "Exit","Skull","Flag","Camp","Circle-x","Deer","1st_aid","Back_track"
};





/* @func GPS_Fmt_Print_Time ********************************************
**
** Output Date/time
**
** @param [r] Time [time_t] unix-style time
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

void GPS_Fmt_Print_Time(time_t Time, FILE *outf)
{
    (void) fprintf(outf,"%s",ctime(&Time));
    fflush(outf);

    return;
}



/* @func GPS_Fmt_Print_Position ********************************************
**
** Output position
**
** @param [r] lat [double] latitude  (deg)
** @param [r] lon [double] longitude (deg)
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf)
{
    (void) fprintf(outf,"Latitude: %f   Longitude %f\n",lat,lon);
    fflush(outf);

    return;
}



/* @func GPS_Fmt_Print_Pvt ********************************************
**
** Output pvt
**
** @param [r] pvt [GPS_PPvt_Data] pvt
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf)
{

    (void) fprintf(outf,"Fix: ");
    switch(pvt->fix)
    {
    case 0:
	(void) fprintf(outf,"UNUSABLE\n\n");
	break;
    case 1:
	(void) fprintf(outf,"INVALID \n\n");
	break;
    case 2:
	(void) fprintf(outf,"2D      \n\n");
	break;
    case 3:
	(void) fprintf(outf,"3D      \n\n");
	break;
    case 4:
	(void) fprintf(outf,"2D-diff \n\n");
	break;
    case 5:
	(void) fprintf(outf,"2D-diff \n\n");
	break;
    default:
	(void) fprintf(stderr,"PVT: Unsupported Fix type\n");
	break;
    }
    
    (void) fprintf(outf,"Altitude (WGS 84): %-20f \n",pvt->alt);
    (void) fprintf(outf,"EPE:               %-20f \n",pvt->epe);
    (void) fprintf(outf,"EPE (hor only):    %-20f \n",pvt->eph);
    (void) fprintf(outf,"EPE (ver only):    %-20f \n",pvt->epv);
    (void) fprintf(outf,"Time of week:      %-20d \n",(int)pvt->tow);
    (void) fprintf(outf,"Latitude:          %-20f \n",pvt->lat);
    (void) fprintf(outf,"Longitude:         %-20f \n",pvt->lon);
    (void) fprintf(outf,"East velocity:     %-20f \n",pvt->east);
    (void) fprintf(outf,"North velocity:    %-20f \n",pvt->north);
    (void) fprintf(outf,"Upward velocity    %-20f \n",pvt->up);
    (void) fprintf(outf,"Height above MSL:  %-20f \n",pvt->msl_hght+pvt->alt);
    (void) fprintf(outf,"Leap seconds:      %-20d \n",pvt->leap_scnds);
    (void) fprintf(outf,"Week number days:  %-20d \n",(int)pvt->wn_days);

    fflush(outf);

    return;
}



/* @func GPS_Fmt_Print_Almanac ********************************************
**
** Output almanac
**
** @param [r] alm [GPS_PAlmanac *] almanac array
** @param [r] n [int32] number of almanac entries
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf)
{
    int32 i;
    int32 t;
    int32 s;
    
    /* Type 0 models require all 32 satellites to be sent */
    t=32;
    s=0;
    if(n && alm[0]->svid!=0xff)
    {
	s=1;
	t=n;
    }
    (void) fprintf(outf,"Almanac %d %d\n",(int)t,(int)s);
    

    for(i=0;i<n;++i)
    {
	if(alm[i]->wn<0) continue;

	if(alm[i]->svid == 0xff)
	    alm[i]->svid = i;
	(void) fprintf(outf,"#\n#\n");	
	(void) fprintf(outf,"\tID:                           %d\n",
		       alm[i]->svid+1);
	(void) fprintf(outf,"\tWeek number:                  %d\n",
		       alm[i]->wn);
	(void) fprintf(outf,"\tAlmanac Data Reference Time:  %f\n",
		       alm[i]->toa);
	(void) fprintf(outf,"\tClock Correction Coeff (s):   %f\n",
		       alm[i]->af0);
	(void) fprintf(outf,"\tClock Correction Coeff (s/s): %f\n",
		       alm[i]->af1);
	(void) fprintf(outf,"\tEccentricity:                 %f\n",
		       alm[i]->e);
	(void) fprintf(outf,"\tSqrt of semi-major axis:      %f\n",
		       alm[i]->sqrta);
	(void) fprintf(outf,"\tMean Anomaly at Ref. Time:    %f\n",
		       alm[i]->m0);
	(void) fprintf(outf,"\tArgument of perigee:          %f\n",
		       alm[i]->w);
	(void) fprintf(outf,"\tRight ascension:              %f\n",
		       alm[i]->omg0);
	(void) fprintf(outf,"\tRate of right ascension:      %f\n",
		       alm[i]->odot);
	(void) fprintf(outf,"\tInclination angle:            %f\n",
		       alm[i]->i);
	(void) fprintf(outf,"\tHealth:                       %d\n",
		       alm[i]->hlth);
    }


    fflush(outf);

    return;
}



/* @func GPS_Fmt_Print_Track ********************************************
**
** Output track log
**
** @param [r] trk [GPS_PTrack *] track array
** @param [r] n [int32] number of track entries
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf)
{
    int32 i;


    switch(gps_trk_transfer)
    {
    case pA300:
	break;
    case pA301:
	GPS_Fmt_Print_Track301(trk,n,outf);
	return;
    default:
	GPS_Error("GPS_Fmt_Print_Track: Unknown protocol");
	return;
    }


    (void) fprintf(outf,"Track log 300 %d\n#\n",(int)gps_trk_type);    
    (void) fprintf(outf,"Start\n#\n");    

    for(i=0;i<n;++i)
    {
	if(trk[i]->tnew)
	    (void) fprintf(outf,"#\nNew track\n#\n");

	switch(gps_trk_type)
	{
	case pD300:
	    GPS_Fmt_Print_D300(trk[i],outf);
	    break;
	case pD301:
	    GPS_Fmt_Print_D301(trk[i],outf);
	    break;
	default:
	    break;
	}
    }

    (void) fprintf(outf,"End\n#\n");
    fflush(outf);

    return;
}



/* @funcstatic GPS_Fmt_Print_Track301 ***********************************
**
** Output track log
**
** @param [r] trk [GPS_PTrack *] track array
** @param [r] n [int32] number of track entries
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf)
{
    int32 i;

    if(!n)
	return;

    (void) fprintf(outf,"Track log 301 %d\n#\n",(int)gps_trk_type);    
    (void) fprintf(outf,"Start\n#\n");    

    for(i=0;i<n;++i)
    {
	if(trk[i]->ishdr)
	{
	    (void) fprintf(outf,"Header\n");
	    (void) fprintf(outf,"\tIdent:       %s\n",trk[i]->trk_ident);
	    (void) fprintf(outf,"\tDisplay:     %d\n",(int)trk[i]->dspl);
	    (void) fprintf(outf,"\tColour:      %d\n#\n",
			   (int)trk[i]->colour);
	    continue;
	}
	
	if(trk[i]->tnew)
	    (void) fprintf(outf,"#\nNew track\n#\n");
	
	switch(gps_trk_type)
	{
	case pD300:
	    GPS_Fmt_Print_D300(trk[i],outf);
	    break;
	case pD301:
	    GPS_Fmt_Print_D301(trk[i],outf);
	    break;
	default:
	    break;
	}
    }

    (void) fprintf(outf,"End\n#\n");
    fflush(outf);

    return;
}


/* @funcstatic GPS_Fmt_Print_D300 ****************************************
**
** Output track log
**
** @param [r] trk [GPS_PTrack *] track array
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf)
{
    (void) fprintf(outf,"\tLatitude:    %f\n",trk->lat);
    (void) fprintf(outf,"\tLongitude:   %f\n",trk->lon);
    if(trk->Time)
	(void) fprintf(outf,"\tTime:        %s\n",ctime(&trk->Time));
    else
	(void) fprintf(outf,"\tTime:        Computer\n\n");

    return;
}



/* @funcstatic GPS_Fmt_Print_D301 ****************************************
**
** Output track log
**
** @param [r] trk [GPS_PTrack *] track array
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf)
{
    (void) fprintf(outf,"\tLatitude:    %f\n",trk->lat);
    (void) fprintf(outf,"\tLongitude:   %f\n",trk->lon);
    if(trk->Time)
	(void) fprintf(outf,"\tTime:        %s",ctime(&trk->Time));
    else
	(void) fprintf(outf,"\tTime:        Computer\n");
    (void) fprintf(outf,"\tAltitude:    %f\n",trk->alt);
    (void) fprintf(outf,"\tDepth:       %f\n\n",trk->dpth);

    return;
}




/* @func GPS_Fmt_Print_Waypoint *****************************************
**
** Output waypoints
**
** @param [r] way [GPS_PWay *] waypoint array
** @param [r] n [int32] number of waypoint entries
** @param [w] outf [FILE *] output stream
**
** @return [int32] success
************************************************************************/

int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf)
{
    int32 i;


    if(!n)
	return 1;

    (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n",
		   (int)way[0]->prot);
    

    for(i=0;i<n;++i)
    {
	switch(way[i]->prot)
	{
	case 100:
	    GPS_Fmt_Print_Way100(way[i],outf);
	    break;
	case 101:
	    GPS_Fmt_Print_Way101(way[i],outf);
	    break;
	case 102:
	    GPS_Fmt_Print_Way102(way[i],outf);
	    break;
	case 103:
	    GPS_Fmt_Print_Way103(way[i],outf);
	    break;
	case 104:
	    GPS_Fmt_Print_Way104(way[i],outf);
	    break;
	case 105:
	    GPS_Fmt_Print_Way105(way[i],outf);
	    break;
	case 106:
	    GPS_Fmt_Print_Way106(way[i],outf);
	    break;
	case 107:
	    GPS_Fmt_Print_Way107(way[i],outf);
	    break;
	case 108:
	    GPS_Fmt_Print_Way108(way[i],outf);
	    break;
	case 109:
	    GPS_Fmt_Print_Way109(way[i],outf);
	    break;
	case 150:
	    GPS_Fmt_Print_Way150(way[i],outf);
	    break;
	case 151:
	    GPS_Fmt_Print_Way151(way[i],outf);
	    break;
	case 152:
	    GPS_Fmt_Print_Way152(way[i],outf);
	    break;
	case 154:
	    GPS_Fmt_Print_Way154(way[i],outf);
	    break;
	case 155:
	    GPS_Fmt_Print_Way155(way[i],outf);
	    break;
	default:
	    GPS_Error("Print_Waypoint: Unknown waypoint protocol");
	    return PROTOCOL_ERROR;
	}
	(void) fprintf(outf,"#\n");
    }
    (void) fprintf(outf,"End\n#\n");

    return 1;
}



/* @func GPS_Fmt_Print_Proximity *****************************************
**
** Output proximity
**
** @param [r] way [GPS_PWay *] waypoint array
** @param [r] n [int32] number of waypoint entries
** @param [w] outf [FILE *] output stream
**
** @return [int32] success
************************************************************************/

int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf)
{
    int32 i;


    if(!n)
	return 1;

    (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n",
		   (int)way[0]->prot);
    

    for(i=0;i<n;++i)
    {
	switch(way[i]->prot)
	{
	case 400:
	    GPS_Fmt_Print_Way100(way[i],outf);
	    break;
	case 101:
	    GPS_Fmt_Print_Way101(way[i],outf);
	    break;
	case 102:
	    GPS_Fmt_Print_Way102(way[i],outf);
	    break;
	case 403:
	    GPS_Fmt_Print_Way103(way[i],outf);
	    break;
	case 104:
	    GPS_Fmt_Print_Way104(way[i],outf);
	    break;
	case 105:
	    GPS_Fmt_Print_Way105(way[i],outf);
	    break;
	case 106:
	    GPS_Fmt_Print_Way106(way[i],outf);
	    break;
	case 107:
	    GPS_Fmt_Print_Way107(way[i],outf);
	    break;
	case 108:
	    GPS_Fmt_Print_Way108(way[i],outf);
	    break;
	case 109:
	    GPS_Fmt_Print_Way109(way[i],outf);
	    break;
	case 450:
	    GPS_Fmt_Print_Way150(way[i],outf);
	    (void) fprintf(outf,"\tPindex:           %d\n",(int)way[i]->idx);
	    break;
	case 151:
	    GPS_Fmt_Print_Way151(way[i],outf);
	    break;
	case 152:
	    GPS_Fmt_Print_Way152(way[i],outf);
	    break;
	case 154:
	    GPS_Fmt_Print_Way154(way[i],outf);
	    break;
	case 155:
	    GPS_Fmt_Print_Way155(way[i],outf);
	    break;
	default:
	    GPS_Error("Print_Proximity: Unknown proximity protocol");
	    return PROTOCOL_ERROR;
	}
	(void) fprintf(outf,"\tDistance:         %f\n",way[i]->dst);
	(void) fprintf(outf,"#\n");
    }
    (void) fprintf(outf,"End\n#\n");

    return 1;
}




/* @funcstatic GPS_Fmt_Print_Way100 *************************************
**
** Output waypoint D100
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf)
{

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);

    return;
}


/* @funcstatic GPS_Fmt_Print_Way101 ************************************
**
** Output waypoint D101
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf)
{

    if(way->smbl > 176) way->smbl=36;
    
    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %d [%s]\n",(int)way->smbl,
		   gps_marine_sym[way->smbl]);

    return;
}


/* @funcstatic GPS_Fmt_Print_Way102 *************************************
**
** Output waypoint D102
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf)
{
    char **p;
    int32  x;
    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }


    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %d [%s]\n",(int)way->smbl,
		   p[way->smbl-x]);

    return;
}


/* @funcstatic GPS_Fmt_Print_Way103 ************************************
**
** Output waypoint D103
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf)
{
    static char *dspl[]=
    {
	"SW","S","SC"
    };
    
    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
		   gps_16_sym[way->smbl]);
    (void) fprintf(outf,"\tDisplay:          %-6d [%s]\n",(int)way->dspl,
		   dspl[way->dspl]);
    
    return;
}


/* @funcstatic GPS_Fmt_Print_Way104 *************************************
**
** Output waypoint D104
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf)
{
    static char *dspl[]=
    {
	"S","S","","SW","","SC"
    };
    char **p;
    int32  x;
    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
		   p[way->smbl-x]);
    (void) fprintf(outf,"\tDisplay:          %-6d [%s]\n",(int)way->dspl,
		   dspl[way->dspl]);

    return;
}


/* @funcstatic GPS_Fmt_Print_Way105 ************************************
**
** Output waypoint D105
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf)
{
    char **p;
    int32  x;
    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }

    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
		   p[way->smbl-x]);
    (void) fprintf(outf,"\tWpt_ident         %s\n",way->wpt_ident);
    
    return;
}


/* @funcstatic GPS_Fmt_Print_Way106 *************************************
**
** Output waypoint D106
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf)
{
    char **p;
    int32  x;
    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }

    if(!way->wpt_class)
    {
	(void) fprintf(outf,"\tClass:            %d [User]\n",way->wpt_class);
	(void) fprintf(outf,"\tSubclass:         %d [%-13.13s]\n",
		       way->wpt_class,way->subclass);
	(void) fprintf(outf,"\tSubclass:\n");
    }
    else
    {
	(void) fprintf(outf,"\tClass:            %d [Non-user]\n",
		       way->wpt_class);
	(void) fprintf(outf,"\tSubclass:         %d [%13.13s]\n",
		       way->wpt_class,
		way->subclass);
    }
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
	    p[way->smbl-x]);
    (void) fprintf(outf,"\tWpt_ident         %s\n",way->wpt_ident);
    (void) fprintf(outf,"\tLnk_ident         %s\n",way->lnk_ident);

    return;
}


/* @funcstatic GPS_Fmt_Print_Way107 ************************************
**
** Output waypoint D107
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf)
{
    static char *dspl[]=
    {
	"SW","S","SC"
    };
    static char *col[]=
    {
	"Default","Red","Green","Blue"
    };
    
    
    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
		   gps_16_sym[way->smbl]);
    (void) fprintf(outf,"\tDisplay:          %-6d [%s]\n",(int)way->dspl,
		   dspl[way->dspl]);
    (void) fprintf(outf,"\tColour:           %-6d [%s]\n",(int)way->colour,
		   col[way->colour]);

    return;
}



/* @funcstatic GPS_Fmt_Print_Way108 ************************************
**
** Output waypoint D108
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf)
{
    char **p;
    int32  x;

    static char *dspl[]=
    {
	"SW","S","SC"
    };

    static char *col[]=
    {
	"Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue",
	"Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green",
	"Yellow","Blue","Magenta","Cyan","White"
    };

    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }

    (void) fprintf(outf,"\tIdent:            %s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    if(way->colour==0xff)
	(void) fprintf(outf,"\tColour:           255    [Default]\n");
    else
	(void) fprintf(outf,"\tColour:           %-6d [%s]\n",(int)way->colour,
		       col[way->colour]);
    (void) fprintf(outf,"\tDisplay:          %-6d [%s]\n",(int)way->dspl,
		   dspl[way->dspl]);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
	    p[way->smbl-x]);
    (void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    (void) fprintf(outf,"\tDepth:            %f\n",way->dpth);
    (void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
    (void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class>=0x80 && way->wpt_class<=0x85)
	(void) fprintf(outf,"\tSubclass:         %18.18s\n",way->subclass);
    if(!way->wpt_class)
	(void) fprintf(outf,"\tComment:          %s\n",way->cmnt);
    if(way->wpt_class>=0x40 && way->wpt_class<=0x46)
    {
	(void) fprintf(outf,"\tFacility:         %s\n",way->facility);
	(void) fprintf(outf,"\tCity:             %s\n",way->city);
    }
    if(way->wpt_class==0x83)
	(void) fprintf(outf,"\tAddress:          %s\n",way->addr);
    if(way->wpt_class==0x82)
	(void) fprintf(outf,"\tCross Road:       %s\n",way->cross_road);
    

    return;
}

/* @funcstatic GPS_Fmt_Print_Way109 ************************************
**
** Output waypoint D109
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf)
{
    char **p;
    int32  x;

    static char *dspl[]=
    {
	"SW","S","SC"
    };

    static char *col[]=
    {
	"Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue",
	"Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green",
	"Yellow","Blue","Magenta","Cyan","White"
    };

    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }

    (void) fprintf(outf,"\tIdent:            %s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    if(way->colour==0xff)
	(void) fprintf(outf,"\tColour:           255    [Default]\n");
    else
	(void) fprintf(outf,"\tColour:           %-6d [%s]\n",(int)way->colour,
		       col[way->colour]);
#if 0
    /* avoid bounds violation in D109.   Probably masking a bug elswhere...*/
    (void) fprintf(outf,"\tDisplay:          %-6d [%s]\n",(int)way->dspl,
		   dspl[way->dspl]);
#endif
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
	    p[way->smbl-x]);
    (void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    (void) fprintf(outf,"\tDepth:            %f\n",way->dpth);
    (void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
    (void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class>=0x80 && way->wpt_class<=0x85)
	(void) fprintf(outf,"\tSubclass:         %18.18s\n",way->subclass);
    if(!way->wpt_class)
	(void) fprintf(outf,"\tComment:          %s\n",way->cmnt);
    if(way->wpt_class>=0x40 && way->wpt_class<=0x46)
    {
	(void) fprintf(outf,"\tFacility:         %s\n",way->facility);
	(void) fprintf(outf,"\tCity:             %s\n",way->city);
    }
    if(way->wpt_class==0x83)
	(void) fprintf(outf,"\tAddress:          %s\n",way->addr);
    if(way->wpt_class==0x82)
	(void) fprintf(outf,"\tCross Road:       %s\n",way->cross_road);
    

    return;
}

/* @funcstatic GPS_Fmt_Print_Way150 *************************************
**
** Output waypoint D150
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf)
{

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class!=4)
    {
	(void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
	(void) fprintf(outf,"\tCity:             %-24.24s\n",way->city);
	(void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
	(void) fprintf(outf,"\tName:             %-30.30s\n",way->name);
    }
    if(!way->wpt_class)
	(void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    
    return;
}


/* @funcstatic GPS_Fmt_Print_Way151 ************************************
**
** Output waypoint D151
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf)
{

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class!=2)
    {
	(void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
	(void) fprintf(outf,"\tCity:             %-24.24s\n",way->city);
	(void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
	(void) fprintf(outf,"\tName:             %-30.30s\n",way->name);
    }
    if(!way->wpt_class)
	(void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    
    return;
}



/* @funcstatic GPS_Fmt_Print_Way152 ************************************
**
** Output waypoint D152
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf)
{

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class!=4)
    {
	(void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
	(void) fprintf(outf,"\tCity:             %-24.24s\n",way->city);
	(void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
	(void) fprintf(outf,"\tName:             %-30.30s\n",way->name);
    }
    if(!way->wpt_class)
	(void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    
    return;
}


/* @funcstatic GPS_Fmt_Print_Way154 ************************************
**
** Output waypoint D154
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf)
{
    char **p;
    int32  x;
    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }
    

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
	    p[way->smbl-x]);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class!=4 && way->wpt_class!=8)
    {
	(void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
	(void) fprintf(outf,"\tCity:             %-24.24s\n",way->city);
	(void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
	(void) fprintf(outf,"\tName:             %-30.30s\n",way->name);
    }
    if(!way->wpt_class)
	(void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    
    return;
}


/* @funcstatic GPS_Fmt_Print_Way155 *************************************
**
** Output waypoint D155
**
** @param [r] way [GPS_PWay] waypoint
** @param [w] outf [FILE *] output stream
**
** @return [void]
************************************************************************/

static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf)
{
    static char *dspl[]=
    {
	"","S","","SW","","SC"
    };

    char **p;
    int32  x;
    
    if(way->smbl < 8192)
    {
	p = gps_marine_sym;
	x = 0;
    }
    else if(way->smbl < 16384)
    {
	p = gps_land_sym;
	x = 8192;
    }
    else
    {
	p = gps_aviation_sym;
	x = 16384;
    }
    

    (void) fprintf(outf,"\tIdent:            %-6.6s\n",way->ident);
    (void) fprintf(outf,"\tLatitude:         %f\n",way->lat);
    (void) fprintf(outf,"\tLongitude:        %f\n",way->lon);
    (void) fprintf(outf,"\tComment:          %-40.40s\n",way->cmnt);
    (void) fprintf(outf,"\tSymbol:           %-6d [%s]\n",(int)way->smbl,
		   p[way->smbl-x]);
    (void) fprintf(outf,"\tDisplay:          %-6d [%s]\n",(int)way->dspl,
		   dspl[way->dspl]);
    (void) fprintf(outf,"\tClass:            %d\n",way->wpt_class);
    if(way->wpt_class!=4 && way->wpt_class!=8)
    {
	(void) fprintf(outf,"\tCountry:          %-2.2s\n",way->cc);
	(void) fprintf(outf,"\tCity:             %-24.24s\n",way->city);
	(void) fprintf(outf,"\tState:            %-2.2s\n",way->state);
	(void) fprintf(outf,"\tName:             %-30.30s\n",way->name);
    }
    if(!way->wpt_class)
	(void) fprintf(outf,"\tAltitude:         %d\n",(int)way->alt);
    
    return;
}



/* @func GPS_Fmt_Print_Route *****************************************
**
** Output route(s)
**
** @param [r] way [GPS_PWay *] waypoint array
** @param [r] n [int32] number of waypoint entries
** @param [w] outf [FILE *] output stream
**
** @return [int32] success
************************************************************************/

int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf)
{
    int32 i;
    int32 first;
    
    if(!n)
	return 1;


    switch(gps_route_transfer)
    {
    case pA200:
	break;
    case pA201:
	return GPS_Fmt_Print_Route201(way,n,outf);
    default:
	GPS_Error("GPS_Fmt_Print_Route: Unknown protocol");
	return PROTOCOL_ERROR;
    }


    (void) fprintf(outf,"Route log 200 %d\n#\n",(int)gps_rte_type);    
    (void) fprintf(outf,"Start\n#\n");    



    first = 1;

    for(i=0;i<n;++i)
    {
	if(way[i]->isrte)
	{
	    if(!first)
		(void) fprintf(outf,"End\n#\n");
	    (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot);
	    first=0;
	    
	    switch(way[i]->rte_prot)
	    {
	    case 200:
		(void) fprintf(outf,"Number: %d",way[i]->rte_num);
		break;
	    case 201:
		(void) fprintf(outf,"Number: %d Comment: %-20.20s",
			       way[i]->rte_num,way[i]->rte_cmnt);
		break;
	    case 202:
		(void) fprintf(outf,"Comment: %s",way[i]->rte_ident);
		break;
	    default:
		GPS_Error("Print_Route: Unknown route protocol");
		return PROTOCOL_ERROR;
	    }
	    (void) fprintf(outf,"\n#\n");
	    (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n"
			   ,(int)way[i]->prot);
	    continue;
	}

	switch(way[i]->prot)
	{
	case 100:
	    GPS_Fmt_Print_Way100(way[i],outf);
	    break;
	case 101:
	    GPS_Fmt_Print_Way101(way[i],outf);
	    break;
	case 102:
	    GPS_Fmt_Print_Way102(way[i],outf);
	    break;
	case 103:
	    GPS_Fmt_Print_Way103(way[i],outf);
	    break;
	case 104:
	    GPS_Fmt_Print_Way104(way[i],outf);
	    break;
	case 105:
	    GPS_Fmt_Print_Way105(way[i],outf);
	    break;
	case 106:
	    GPS_Fmt_Print_Way106(way[i],outf);
	    break;
	case 107:
	    GPS_Fmt_Print_Way107(way[i],outf);
	    break;
	case 108:
	    GPS_Fmt_Print_Way108(way[i],outf);
	    break;
	case 109:
	    GPS_Fmt_Print_Way109(way[i],outf);
	    break;
	case 150:
	    GPS_Fmt_Print_Way150(way[i],outf);
	    break;
	case 151:
	    GPS_Fmt_Print_Way151(way[i],outf);
	    break;
	case 152:
	    GPS_Fmt_Print_Way152(way[i],outf);
	    break;
	case 154:
	    GPS_Fmt_Print_Way154(way[i],outf);
	    break;
	case 155:
	    GPS_Fmt_Print_Way155(way[i],outf);
	    break;
	default:
	    GPS_Error("Print_Route: Unknown waypoint protocol");
	    return PROTOCOL_ERROR;
	}
	(void) fprintf(outf,"#\n");
    }
    (void) fprintf(outf,"End\n#\n");

    return 1;
}



/* @funcstatic GPS_Fmt_Print_Route201 ***********************************
**
** Output route(s)
**
** @param [r] way [GPS_PWay *] waypoint array
** @param [r] n [int32] number of waypoint entries
** @param [w] outf [FILE *] output stream
**
** @return [int32] success
************************************************************************/

static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf)
{
    int32 i;
    int32 first;
    
    if(!n)
	return 1;


    (void) fprintf(outf,"Route log 201 %d\n#\n",(int)gps_rte_link_type);    
    (void) fprintf(outf,"Start\n#\n");    


    first = 1;

    for(i=0;i<n;++i)
    {
	if(way[i]->isrte)
	{
	    if(!first)
		(void) fprintf(outf,"End\n#\n");
	    (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot);
	    first=0;
	    
	    switch(way[i]->rte_prot)
	    {
	    case 200:
		(void) fprintf(outf,"Number: %d",way[i]->rte_num);
		break;
	    case 201:
		(void) fprintf(outf,"Number: %d Comment: %-20.20s",
			       way[i]->rte_num,way[i]->rte_cmnt);
		break;
	    case 202:
		(void) fprintf(outf,"Comment: %s",way[i]->rte_ident);
		break;
	    default:
		GPS_Error("Print_Route: Unknown route protocol");
		return PROTOCOL_ERROR;
	    }
	    (void) fprintf(outf,"\n#\n");
	    (void) fprintf(outf,"Waypoints Type: %d\n#\n"
			   ,(int)way[i]->prot);
	    continue;
	}


	if(way[i]->islink)
	{
	    (void) fprintf(outf,"\tLink Class:       %d\n",
			   (int)way[i]->rte_link_class);
	    if(!(way[i]->rte_link_class==3 || way[i]->rte_link_class==0xff))
	    (void) fprintf(outf,"\tLink Subclass:    %-18.18s\n",
			   way[i]->rte_link_subclass);
	    (void) fprintf(outf,"\tLink Ident:       %s\n#\n",
			   way[i]->rte_link_ident);
	    continue;
	}


	switch(way[i]->prot)
	{
	case 100:
	    GPS_Fmt_Print_Way100(way[i],outf);
	    break;
	case 101:
	    GPS_Fmt_Print_Way101(way[i],outf);
	    break;
	case 102:
	    GPS_Fmt_Print_Way102(way[i],outf);
	    break;
	case 103:
	    GPS_Fmt_Print_Way103(way[i],outf);
	    break;
	case 104:
	    GPS_Fmt_Print_Way104(way[i],outf);
	    break;
	case 105:
	    GPS_Fmt_Print_Way105(way[i],outf);
	    break;
	case 106:
	    GPS_Fmt_Print_Way106(way[i],outf);
	    break;
	case 107:
	    GPS_Fmt_Print_Way107(way[i],outf);
	    break;
	case 108:
	    GPS_Fmt_Print_Way108(way[i],outf);
	    break;
	case 109:
	    GPS_Fmt_Print_Way109(way[i],outf);
	    break;
	case 150:
	    GPS_Fmt_Print_Way150(way[i],outf);
	    break;
	case 151:
	    GPS_Fmt_Print_Way151(way[i],outf);
	    break;
	case 152:
	    GPS_Fmt_Print_Way152(way[i],outf);
	    break;
	case 154:
	    GPS_Fmt_Print_Way154(way[i],outf);
	    break;
	case 155:
	    GPS_Fmt_Print_Way155(way[i],outf);
	    break;
	default:
	    GPS_Error("Print_Route: Unknown waypoint protocol");
	    return PROTOCOL_ERROR;
	}
	(void) fprintf(outf,"#\n");
    }
    (void) fprintf(outf,"End\n");

    return 1;
}
