/*
 *	utility.c
 *
 *	HNMS User Interface
 *	HNMS 2.0
 *
 *	February 1994
 *
 *	Leslie Schlecht
 *	Computer Sciences Corporation
 *	Numerical Aerodynamic Simulation Systems Division
 *	NASA Ames Research Center
 *
 *	Copyright (c) 1994 Leslie Schlecht
 *
 *	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 1, 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.
 *
 */

#include	<sys/types.h>
#include	<stdio.h>
#include	<malloc.h>
#include	<string.h>
#include	<time.h>
#include	<math.h>

#define		CONV		M_PI/180.0

#include	<X11/StringDefs.h>
#include	<X11/Intrinsic.h>
#include	<X11/Shell.h>
#include	<X11/Core.h>
#include	<Xm/Xm.h>

#include	"defines.h"

void
InitializeUtilities()
	{
#ifdef sgi
	mallopt(M_FREEHD, 1);
#endif
	}

caddr_t
myalloc(addr1, size1, size2)
caddr_t	addr1;
int	size1, size2;
	{
	int	i, j;
	caddr_t	a;

	i = size1*size2;
	if (!addr1)
		a = malloc(i);
	else
		a = realloc(addr1, i);
	if (!a)
		LogMessage("error in malloc\n");
	bzero(a, i);
	return(a);
	}

char *
get_time(t)
time_t	t;
	{
	static char	s[32];
	time_t		tt;

	if (!t)
		tt = time(0);
	else
		tt = t;
#ifdef sun
	strftime(s, 31, "%d%h%y %H:%M:%S", localtime(&tt));
#endif
#ifdef sgi
	cftime(s, "%d%h%y %H:%M:%S", &tt);
#endif
	return(s);
	}

/*
 *	Extract a string from an XmString.
 */
char *
exstr(xs)
XmString	xs;
	{

	XmStringContext		cntx;
	XmStringCharSet		set;
	XmStringDirection	dir;
	Boolean			sep;
	static	char		*str;

	XmStringInitContext(&cntx, xs);
	XmStringGetNextSegment(cntx, &str, &set, &dir, &sep);
	XmStringFreeContext(cntx);
	return((char *)str);
	}

/*
 *	Get an argument from the command line.
 */
int
get_arg(s, sr, argc, argv)
char	*s, **sr, *argv[];
int	argc;
	{
	register	i, l;
	char		*v;

	l = strlen(s);
	for (i=0; i<argc; i++) {
		if (strncmp(argv[i], s, l) == 0) {
			if (!sr) return(1);
			if (strlen(argv[i]) > l) {
				*sr = argv[i]+l;
				return(1);
				}
			else {
				if (i < argc) {
					v = argv[i+1];
					if (*v == '-') return(0);
					*sr = v;
					return(1);
					}
				else
					return(0);
				}
			}
		}
	return(0);
	}

char *
newstr(s)
char	*s;
	{
	return(strcpy(myalloc(NULL,strlen(s)+1,1),s));
	}

char*
gettoken(s)
char	*s;
	{
	static	char	*lasts=NULL;
	char	*p, *q;

	if (!s && !lasts) return(NULL);
	if (s) lasts = s;
	for (p=lasts; *p; p++) {
		if (*p == '\n') {
			q = lasts;
			*p = '\0';
			lasts = p+1;
			return(q);
			}
		}
	lasts = NULL;
	return(NULL);
	}


void
ConvertStrToTable(str, table, count)
char		*str;
XmStringTable	*table;
int		*count;
	{
	char	buf[BUFSIZ];
	char	*p;
	int	k=0;
	XmStringTable	t;

	*table = NULL;
	*count = 0;
	if (!str) return;
	strcpy(buf, str);
	for (p=gettoken(buf); p; p=gettoken(NULL)) k ++;
	if (!k) return;
	*count = k;
	*table = (XmStringTable)myalloc(NULL, k, sizeof(XmStringTable), NULL);
	t = *table;
	p = buf;
	for (k=0 ; k<(*count); k++) {
		t[k] = X_STR(p);
		p += (strlen(p)+1);
		}
	}


void
ConvertTableToStr(table, count, str)
XmStringTable	table;
int		count;
char		**str;
	{
	char	buf[BUFSIZ];
	register	i;

	buf[0] = '\0';
	for (i=0; i<count; i++) {
		strcat(buf, exstr(table[i]));
		strcat(buf, "\n");
		};
	*str = newstr(buf);
	}

/*
 *	Project latitude and longitude coordinates to world coordinates.
 */
int
project(lat, lon, xco, yco, vlt, vln, vd)
float	lat, lon;
float	*xco, *yco;
float	vlt, vln, vd;
	{
	double          xx, yy, zz;
	double          x, y, z;
	double          dot, factor;
	double		viewdist;
	double          lati, longi;
	double		viewlat, viewlong;

	lati = lat*CONV;
	longi = lon*CONV;
	viewlat = vlt*CONV;
	viewlong = vln*CONV;
	viewdist = vd;
	x = sin(longi-viewlong)*cos(lati);
	y = cos(longi-viewlong)*cos(lati);
	z = sin(lati);

	yy = y*cos(viewlat)+z*sin(viewlat);
	zz = -y*sin(viewlat)+z*cos(viewlat);
	xx = x;

	dot = xx*xx+zz*zz-yy*(viewdist+(1.-yy));

	if (dot > 0.) return(0);

	factor = viewdist/(viewdist+(1.0-yy));
	xx *= factor;
	zz *= factor;

	*xco = xx;
	*yco = zz;
	return(1);
	}


int
MetaCmp(s1, s2)
char	*s1, *s2;
	{
	int	count=0;
	int	meta=False;

	if (!s1 || !s2) return(False);
	while (1) {
		count ++;
		if (count == BUFSIZ) return(False);
		if (*s1 == '\0') {
			if (*s2 == '\0') return(True);
			if (meta) return(True);
			return(False);
			}
		if (*s2 == '\0') return(False);
		while (*s1 == '*') {
			meta = True;
			s1 ++;
			}
		if (*s1 == *s2)
			meta = False;
		else if (!meta)
			return(False);
		if (!meta) s1 ++;
		s2 ++;
		}
	}


int
InStrList(list, s)
char	*list, *s;
	{
	char	buf[BUFSIZ];
	char	*p;
	int	rc = 0;

	if (!list) return(False);
	if (!s) return(False);
	strcpy(buf, list);
	for (p=gettoken(buf); p; p=gettoken(NULL)) {
		rc = MetaCmp(p, s);
		if (rc) return(True);
		}
	return(False);
	}


int
IntersectLine(x0, y0, x1, y1, x2, y2)
int	x0, y0;
float	x1, y1, x2, y2;
	{
	float	dyl, dyp, dxl, dxp;

	if (x0 < MINIMUM(x2, x1)-1) return(0);
	if (x0 > MAXIMUM(x2, x1)+1) return(0);
	if (y0 < MINIMUM(y2, y1)-1) return(0);
	if (y0 > MAXIMUM(y2, y1)+1) return(0);
	dxl = x1-x2;
	if (dxl == 0.0) return(0);
	dxp = x0-x2;
	dyl = y1-y2;
	dyp = dyl/dxl*dxp+y2;
	dyp = fabs(y0-dyp);
	if (dyp <= 2.0) return(1);
	return(0);
	}


int
LabelLength(s)
char	*s;
	{
	register	i;

	for (i=0; (*s != '\0') && (*s != '.'); i++)
		s ++;
	return(i);
	}
