/*  

	collage.c  3-4-91
	from mapper.c

	cll1.bat = cl /AL collage.c vmaputil vimage2 graphlib

	by Russell A. Ambroziak, Ph. D.

*/
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "font.h"
#include "nomouse.h"

#define DEG_RAD 0.01745329251				/* converts degrees to radians */
#define MAXDO 1000
#define MAX_COLORS 16
#define STR_LEN 100
#define NUM_DP 100
#define MENUXC 550
#define TYPE 'p'

#define BLACK     0
#define D_GREY    1
#define GREY2     2
#define L_GREY    3
#define GREY1     4
#define WHITE     5
#define BUFF      6
#define L_BUFF    7
#define RED       8
#define ORANGE    9
#define YELLOW   10
#define GREEN    11
#define D_GREEN  12
#define VD_GREEN 13
#define BLUE     14
#define D_BLUE   15

#define NUM_TYPE 25
#define NUM_SIZE 25
#define NUM_PLACE 3
#define NUM_PSIZE 3
#define MAX_IMG 250

#define MENU_M  10
#define MENU_L   8
#define MENU_P   6
#define SYM_SIZE 9
#define S_SIZE 40

int Rxc,Ryc,Repeat=0;	/* multiple screens if Repeat>1 */
extern int GF_Order[300];
struct file_id
{
	char name[S_SIZE];
	long size;
	unsigned date,time;
};
extern struct file_id GF_File[300];

struct board
{
	int row,col,color;
}B_Id;
char String[STR_LEN];
int RawOn;
int FontSize=2;
int NumPath=1;
char Path[NUM_DP][STR_LEN];
float PixScale;
char Suffix[20];
char VideoType='X';
int MaxXs,MaxYs;
char Disk_Dir[STR_LEN];
char *Menu_V[NUM_TYPE];
char *Menu_M[MENU_M]=
{
	"zoom",               /*  0 */
	"Change projection",  /*  1 */
	"Save collage",       /*  2 */
	"Recall collage",     /*  3 */
	"cursor mode",        /*  4 */
	"vector plot",        /*  5 */
	"annotate",           /*  6 */
	"draw lines",         /*  7 */
	"labels",             /*  8 */
	"exit"        
};

char T_Menu_L[NUM_TYPE+3][2][50];
char *T_Menu_P[MENU_P][2];

float MaxLat,MinLat,MaxLon,MinLon;

char SaveName[STR_LEN]={"collage.out"};

struct map_screen
{
	int xc,yc,xs,ys;
}map_pos;
struct   Color 
{ 
	unsigned char  r, g, b; 
};
double ll[MAXDO][2];
int todo[2][MAXDO];
unsigned char MT_Buff[12][640],Mbuff[48][640],Buffer[640];
long Mbuff_Size=30720,MT_Buff_Size=7680,Buffer_Size=640;
unsigned char ImgBuffer[10000];
long ImgBuffer_Size=10000;
unsigned char Hdrbuff[BUFSIZ],Inbuff[BUFSIZ],Inbuff2[BUFSIZ],Outbuff[BUFSIZ];

struct map_input
{
	char *name,type;
	double indat[6];
}miv;
int SaveVec=0,SNum=1;
int ScreenXs,ScreenYs;
struct image_name
{
	char name[100];
	float maxlat,minlat,maxlon,minlon;
	float max_pix,min_pix,a[6],b[6];
	int num_a,num_b,row,col;
}Img[MAX_IMG];
struct line_name
{
	char filename[54];
	float max_pix,min_pix;
	int color;
};
struct place_name
{
	char *name,*filename;
	float max_pix,min_pix;
	int color;
};
struct col
{
	int Plot;
	int Plot_At;
	int Num_Plot;
	int Msng;
	float Min_Pix;
	int White,Num_Color;
	int Comp_Color[256];
	int screen_xs,screen_ys;
	int Num_Type,Out;
	float Pixsize,Clat,Clon,Space;
	int Mback,Text,High,Back,Grat;
	int GratOn;
	int LatLon,Black;
	char Color_Name[MAX_COLORS][30];
	int Color_Val[MAX_COLORS][3];
	int Type;
	int Ns[NUM_TYPE];
	int Mm[NUM_TYPE];
	int Pp[NUM_PLACE];
	char Group_Name[NUM_TYPE][30];
	struct line_name ColFile[NUM_TYPE][NUM_SIZE];
	struct place_name PlaceFile[NUM_PLACE][NUM_PSIZE];
	struct Color lut[256];
	int assignment[256];
}M;
int Verbose=0,Dither=0,Assignment[256][2];
FILE *Fpout;
char LastMap[STR_LEN],LastFile[STR_LEN],Auto=0;

int do_menu(char *[],int,int,int,int,int,int,int,int [128][25]); 
int annotate(int *,int *,int *,int *);
int convert_bin(int,char *);
int draw_line(int *,int *,int *);
int get_color(char *);
void get_corners(int,int,int,int, double , double , double ,
		 double , double , double ,int[4],int[4]);
int latlon(double *,double *,int,int,int);
int M_do_menu(char *[],int,int,int,int,int,int,int,int [128][25]);
int plot_col(int,int,int,int, double , double , double , double ,int);
int plot_img(int,unsigned char *,long);
int read_control(char *);
int save_col(char *);
void screen_mm(void);
int search_list(char *,char *);
void set_lut(char,int);
int split(char *,char *,char *,char *);
int T_do_menu(char [][2][50],int,int,int,int,int,int,int,int [128][25],int *);
int tplot_line(int,int,int,int,int,unsigned char *);
int unplot_line(int,int,int,int,int,unsigned char *);
int unsave_col(char *);
int vector_plot( double );
int video_on(void);
char zoom(int,int,int,int, float  *, float  *, float  *, float  *);
void pix_loc(int,int,int *,int *,int *);
FILE *open_to_read_binary(char *);
FILE *open_to_write_text(char *);
FILE *open_to_write_binary(char *);
char fsplit(char *,char *,char *,char *);
unsigned char getpt(int plane,int x,int y);

main(argc,argv)

int argc;
char *argv[];

{
	int i,j,k,p;
	char ans,ans2,cfile[STR_LEN],string[STR_LEN];
	int mt=0,lbrite=64,nbrite=127,brite;
	int cx=256,cy=ScreenYs/2;
	int xc,yc,xs,ys,ix,iy,val,speed,isize=FontSize,color;
	float pixsize=12.0,clat=38.0,clon=-95.75,space=10.0;
	int m_num=0;
	FILE *fp;

	ix=ScreenXs/2;
	iy=ScreenYs/2;
	speed=16;
	for(i=0;i<argc;i++)
	{
		if(argv[i][0]=='v')
			Verbose=1;
		if(argv[i][1]==':')
			add_disk_path(argv[i]);
		if(argv[i][0]=='/'&&(argv[i][1]=='e'||argv[i][1]=='E'))
		{
			ScreenYs=380;
			cy=ScreenYs/2;
		}
		if(argv[i][0]=='/'&&argv[i][1]=='R')
			RawOn=1;
		if(argv[i][0]=='/'&&(argv[i][1]=='X'||argv[i][1]=='x'))
			VideoType='X';
		if(argv[i][0]=='/'&&(argv[i][1]=='Y'||argv[i][1]=='y'))
			VideoType='Y';
		if(argv[i][0]=='/'&&(argv[i][1]=='E'||argv[i][1]=='e'))
			VideoType='E';
		if(argv[i][0]=='/'&&(argv[i][1]=='V'||argv[i][1]=='v'))
			VideoType='V';
		if(argv[i][0]=='/'&&(argv[i][1]=='S'||argv[i][1]=='s'))
			VideoType='S';
		if(argv[i][0]=='/'&&(argv[i][1]=='g'||argv[i][1]=='G'))
		{
			M.GratOn=1;
		}
		if(argv[i][0]=='/'&&argv[i][1]=='o')
		{
			if(M.Out==0&&i<argc-1)
			{
				add_disk_path(argv[i+1]);
				if(Fpout)
				{
					Fpout=fopen(argv[i+1],"wt");
					printf("Output file = '%s'\n",argv[i+1]);
				}
				else
				{
					printf("Could not open '%s' to write.\n\n",argv[i+1]);
					printf("HIT ANY KEY TO CONTINUE!\n\n");
					getch();
				}
			}
		}
	}
	xc=0;yc=0;xs=ScreenXs;ys=ScreenYs;
	video_on();
	M.Pixsize*=PixScale;
	pixsize=M.Pixsize;
	clat=M.Clat;
	clon=M.Clon;
	space=M.Space;	
	cy=ScreenYs/2;
	SetVideoMode(0,&B_Id);
	printf("     Choose a map to start with\n");
	printf("by using the up and down arrow\n");
	printf("keys, 'Pg Up' or 'Pg Dn' keys,\n");
	printf("or by typing the name of the\n");
	printf("map.  Hit 'Enter' to select a\n");
	printf("map.  If the map is not in this\n");
	printf("directory and you have entered\n");
	printf("command line path names, hit\n");
	printf("'Esc' to continue on to other\n");
	printf("paths.\n\n");
	printf("     If you wish to draw a map\n");
	printf("rather than load one that is\n");
	printf("already drawn -- hit 'Esc'\n");
	printf("until the menu contains '*.map'\n");
	printf("files.\n\n");
	printf("     If you copy drawn map\n");
	printf("files from one disc to another,\n");
	printf("the path names may be incorrect\n");
	printf("and you may not be able to\n");
	printf("zoom.\n");
	sprintf(string,"*%s",Suffix);
	if(search_list(string,cfile)>=0)
	{
		video_on();
		unsave_col(cfile);
		set_lut('c',0);
	}
	else
	{
		search_list("*.col",cfile);
		if(strlen(cfile)>0)
			val=read_control(cfile);
		else
		{
			printf("no file chosen\n\n");
			exit(0);
		}

		if(val<0)
		{
			if(val==-1)
				printf("Could not open control file '%s'\n\n",cfile);
			if(val==-2)
				printf("Could not find 'begin_color in file '%s'\n\n",cfile);
			if(val==-3)
				printf("Could not find 'begin_vector in file '%s'\n\n",cfile);
			if(val==-4)
				printf("Too many vectors in a group in file '%s'\n\n",cfile);
			if(val==-5)
				printf("Bad color name in file '%s'\n\n",cfile);
			if(val==-6)
	printf
	("Missing or bad pixel size, central lat and lon or graticule spacing\n");
			exit(0);
		}
		video_on();
		M.Pixsize*=PixScale;
		pixsize=M.Pixsize;
		clat=M.Clat;
		clon=M.Clon;
		space=M.Space;	
		cy=ScreenYs/2;
		set_lut('c',0);
		plot_col(xc,yc,ScreenXs,ScreenYs,(double)pixsize,clat,clon,space,0);
	}
	do
	{
	m_num=M_do_menu(Menu_M,MENU_M,MENUXC,25,m_num,M.Mback,M.Text,M.High,Font);
		if(m_num==0)
		{
			pixsize=M.Pixsize;
			clat=M.Clat;
			clon=M.Clon;
			space=M.Space;
			ans=zoom(xc,yc,ScreenXs,ScreenYs,&pixsize,&clat,&clon,&space);
			if(ans!=27)
			plot_col(xc,yc,ScreenXs,ScreenYs,(double)pixsize,clat,clon,space,0);
		}
		if(m_num==1)
		{
			pixsize=M.Pixsize;
			clat=M.Clat;
			clon=M.Clon;
			space=M.Space;
			save_box(0,M.Black,
				(unsigned char *)Mbuff,0,MaxYs-40,MaxXs,40);
			sprintf(String,"Give new projection type.  l=Lambert  a=Albers");
			if(VideoType=='S')
				plot_font_h(M.White,5,MaxYs-38,String,3,Font);
			else
				plot_font_h(M.White,5,MaxYs-38,String,2,Font);
			sprintf(String,
"'m'=Mercator  's'=polar stereographic  'p'=plate carre   S=sinusoidal");
			if(VideoType=='S')
				plot_font_h(M.White,5,MaxYs-18,String,3,Font);
			else
				plot_font_h(M.White,5,MaxYs-18,String,2,Font);
			M.Type=getch();
			if(M.Type=='l'||M.Type=='a'||
					M.Type=='m'||M.Type=='s'||M.Type=='p'||M.Type=='S')
				plot_col(xc,yc,ScreenXs,ScreenYs,(double)pixsize,clat,clon,space,0);
			else
			{
				M.Type='p';
				unsave_box(0,M.Black,
				(unsigned char *)Mbuff,0,MaxYs-40,MaxXs,40);
			}
		}
		if(m_num==2)
		{
			i=0;
			do
			{
				if(fp)
					fclose(fp);
				sprintf(string,"colage%02d%s",i++,Suffix);
				fp=fopen(string,"rb");
			}while(fp);
			if(fp)
				fclose(fp);
			save_col(string);
		}
		if(m_num==3)
		{
			sprintf(string,"*%s",Suffix);
			SetVideoMode(0,&B_Id);
			search_list(string,cfile);
			video_on();
			unsave_col(cfile);
			set_lut('c',0);
		}
		if(m_num==4)	/* cursor mode */
		{
			ix=ScreenXs/2;
			iy=ScreenYs/2;
			speed=16;
			pix_loc(ix,iy,&ix,&iy,&speed);
		}
		if(m_num==5)
		{
			pixsize=M.Pixsize;
			vector_plot(pixsize);
		}
		if(m_num==6)
		{
			ix=ScreenXs/2;
			iy=ScreenYs/2;
			isize=FontSize;
			color=M.White;
			while(annotate(&ix,&iy,&isize,&color)!=27);
		}
		if(m_num==7)
		{
			ix=ScreenXs/2;
			iy=ScreenYs/2;
			color=M.White;
			while(draw_line(&ix,&iy,&color)!=27);
		}
		if(m_num==8)
		{
			pixsize=M.Pixsize;
			plot_labels(M.White,(double)pixsize);
		}
	}while(m_num!=MENU_M-1); 

	SetVideoMode(0,&B_Id);
	return(1);

}

/**************************************************************************
**
**
**
************************************************************************* */

int add_disk_path(string)

char *string;

{
	int i,j,k;
	char dsk,pth[STR_LEN],nam[10],typ[10],str[STR_LEN];
	int match,add=0;

	dsk=fsplit(string,pth,nam,typ);
	if(dsk>0)
		sprintf(str,"%c:%s",dsk,pth);
	else
		sprintf(str,"%s",pth);
	if((dsk>0||strlen(pth)>0)&&NumPath<NUM_DP)
	{
		match=0;
		for(i=0;i<NumPath;i++)
		{
			if(strcmpi(Path[i],str)==0)
				match=1;
		}
		if(match==0)
		{
			strcpy(Path[NumPath],str);
			NumPath+=1;
			add+=1;
		}
	}
	return(add);
}


/**************************************************************************
**
**
**
************************************************************************* */

char fsplit(instring,path,name,type)

char *instring,*path,*name,*type;

{
	int i,j,k;
	int dot=-1,last_slash=-1,len=strlen(instring),first_slash=-1;
	int num=0,colon=-1;
	int disk=0;
	char string[STR_LEN];

	strcpy(string,instring);
	path[0]='\0';
	name[0]='\0';
	type[0]='\0';

	for(i=0;i<len;i++)
	{
		if(string[i]==':')
			colon=i;
		else if(string[i]=='\\')
		{
			last_slash=i;
			if(first_slash<0)
				first_slash=i;
		}	
		else if(string[i]=='.')
			dot=i;
	}
	if(dot<0&&first_slash>=0&&last_slash<len-1)  /* d:test */
	{
		string[len]='\\';
		last_slash=len;
		len+=1;
		string[len]='\0';
	}
	if(dot<0&&first_slash<0&&len>colon-1)
	{
		string[len]='.';
		dot=len;
		len+=1;
		string[len]='\0';
	}
	if(colon>0)
		disk=string[0];
	if(first_slash>=0)
	{
		for(i=first_slash;i<=last_slash;i++)
			path[i-first_slash]=string[i];
		path[last_slash-first_slash+1]='\0';
	}
	if(last_slash>0&&last_slash<len-1&&dot>0)
	{
		for(i=last_slash+1;i<dot;i++)
			name[i-last_slash-1]=string[i];
		name[dot-last_slash-1]='\0';
	}
	if(colon>0&&last_slash<0&&dot>0)	/* d:test.img */
	{
		for(i=colon+1;i<dot;i++)
			name[i-colon-1]=string[i];
		name[dot-colon]='\0';
	}
	if(colon<0&&last_slash<0&&dot>0)	/* test.img */
	{
		for(i=0;i<dot;i++)
			name[i]=string[i];
		name[dot]='\0';
	}
	if(dot>0&&dot<len-1)
	{
		for(i=dot+1;i<len;i++)
			type[i-dot-1]=string[i];
		type[len-dot-1]='\0';
		if(strlen(type)>3)
			type[3]='\0';
	}
	return(disk);
}


/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_write_text(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"wt");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_write_binary(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"wb");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_read_text(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];
	int len;

	string[0]='\0';
	for(j=0;j<NumPath;j++)
	{
		len=strlen(Path[j])+strlen(name);
		if(len>0&&len<STR_LEN);
		{
			sprintf(string,"%s%s",Path[j],name);
			fp=fopen(string,"rt");
			if(fp)
			{
				strcpy(LastFile,name);
				return(fp);
			}	
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}


/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_read_binary(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];
	int len;

	string[0]='\0';
	for(j=0;j<NumPath;j++)
	{
		len=strlen(Path[j])+strlen(name);
		if(len>0&&len<STR_LEN);
		{
			sprintf(string,"%s%s",Path[j],name);
			fp=fopen(string,"rb");
			if(fp)
			{
				strcpy(LastFile,name);
				return(fp);
			}	
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}


/***********************************************************************
**
**
**
**
************************************************************************/

int plot_labels(val,pixsize)

int val;
double pixsize;

{
	int i,j,k;
	char *menu[20],names[20][10],string[101];
	int m_num=0,numfile;
	double lat,lon,x,y;
	char text[100];
	int size;
	double max,min;
	double rot;
	FILE *fpclb;

	numfile=load_File("*.clb");
	if(numfile>20)
		numfile=20;
	for(i=0;i<numfile;i++)
	{
		strcpy(names[i],GF_File[i].name);
		for(j=0;j<10;j++)
		{
			if(names[i][j]=='.')
				names[i][j]='\0';
			menu[i]=names[i];
		}
	}
	menu[numfile++]="don't plot";
	m_num=M_do_menu(menu,numfile,MENUXC,25,m_num,
							M.Mback,M.Text,M.High,Font);
	{
		fpclb=open_to_read_text(GF_File[m_num].name);
		if(!fpclb)
			return(-1);
		if(m_num==numfile-1)
			return(-2);
		fgets(string,100,fpclb);	/* read header */
		while(fgets(string,100,fpclb))
		{
			sscanf(string,"%lf%lf%s%d%lf%lf%lf",
				&lat,&lon,text,&size,&max,&min,&rot);
			if(max*PixScale>pixsize
				&&min*PixScale<=pixsize)
			{
				ll_xy(&x,&y,lat,lon);
				if(rot==0.0)
					plot_font_h(val,(int)x,(int)y,text,size,Font);
				else if(rot==90.0)
					plot_font_v(val,(int)x,(int)y,text,size,Font);
				else
					plot_font_rot(val,(int)x,(int)y,text,size,Font,rot);
			}
		}
	}
}



/********************************************************************
**
**
**
********************************************************************* */

int video_off()

{
	SetVideoMode(0,&B_Id);
}


/********************************************************************
**
**
**
********************************************************************* */

int plot_col(xc,yc,xs,ys,pixsize,clat,clon,space,iop)

int xc,yc,xs,ys;
double pixsize,clat,clon,space;
int iop;

{
	int i,j,k,l,m,n;
	double sp=space;
	int num,val,filled=0,status;
	int ix=ScreenXs/2,iy=ScreenYs/2,speed=16;

	miv.type=M.Type;
	miv.indat[0]=pixsize;
	miv.indat[1]=clat;
	miv.indat[2]=clon;
	miv.indat[3]=clon;
	miv.indat[4]=clat+10;
	miv.indat[5]=clat-10;
	map_pos.xc=xc;	
	map_pos.yc=yc;
	map_pos.xs=xs;
	map_pos.ys=ys;
	auto_set_cc(miv.type,miv.indat);
	screen_mm();

	if(iop==0)
	{
		paint_box(3,M.Back,
				(unsigned char *)MT_Buff,0,0,ScreenXs,ScreenYs);
		if(pixsize>5.0)
		{
			sp=10;
			plot_graticule((int *)Font,M.Grat,M.LatLon,sp,M.GratOn);
		}
		if(pixsize>2.5&&pixsize<=5.0)
		{
			sp=5;
			plot_graticule((int *)Font,M.Grat,M.LatLon,sp,M.GratOn);
		}
		if(pixsize<=2.5&&pixsize>0.5)
		{
			sp=1;
			plot_graticule((int *)Font,M.Grat,M.LatLon,sp,M.GratOn);
		}
		if(pixsize<=0.5&&pixsize>0.25)
		{
			sp=0.5;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.25&&pixsize>0.05)
		{
			sp=0.1;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.05&&pixsize>0.025)
		{
			sp=0.05;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.025&&pixsize>0.005)
		{
			sp=0.01;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.005&&pixsize>0.0025)
		{
			sp=0.005;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.0025&&pixsize>0.0005)
		{
			sp=0.001;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.0005&&pixsize>0.00025)
		{
			sp=0.0005;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.00025&&pixsize>0.00005)
		{
			sp=0.0001;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(pixsize<=0.00005&&pixsize>0.000025)
		{
			sp=0.00005;
			plot_graticule_frac((int *)Font,M.Grat,M.LatLon,sp);
		}
		if(iop==0)
		{
			for(i=0;i<M.Num_Type;i++)
			{
				if(M.Plot>0&&i==M.Plot_At)
				{
					for(n=0;n<M.Num_Plot;n++)
					{	
						if(Img[n].max_pix>pixsize
							&&Img[n].min_pix<=pixsize&&
							Img[n].maxlon>MinLon&&Img[n].minlon<MaxLon&&
							Img[n].maxlat>MinLat&&Img[n].minlat<MaxLat)
						{
							if((status=plot_img(n,ImgBuffer,ImgBuffer_Size))==-4)
								break;
							else if(status==-6)
							{
								video_off();
								printf("status=%d\n",status);
								printf(
					"Bad value in 'grey.asn' -- no assignment can exceed 139.\n\n");
								exit(0);
							}
						}
					}
				}
				else
				{
					for(j=0;j<M.Ns[i];j++)
					{
						if(M.ColFile[i][j].max_pix>pixsize
							&&M.ColFile[i][j].min_pix<=pixsize
							&&M.Mm[i]==1)
						{
							if(kbhit()>0)
							{
								val=getch();
								if(val==27)
									return(-1);
							}
							num=convert_bin(M.ColFile[i][j].color,
									M.ColFile[i][j].filename);
							if(num<-1)
								return(-2);
						}
					}
				}
			}
		}
	}
}

/**************************************************************************
**
**		returns:
**						-1	=	could not open image file
**						-2	=	illegal image number
**						-3	=	unexpected EOF
**						-4	=	'Esc' key pressed
**						-5	=	column > buffer_size
**						-6	=	bad value assignment
**
***************************************************************************/

int plot_img(n,buffer,buffer_size)

int n;
unsigned char *buffer;
long buffer_size;

{
	int i,j,k;
	int row,col,val,ix,iy,di;
	double x=0.0,y=0.0,lat=28.0,lon=-90.0,y1,y1o,dely,dnum;
	FILE *fpimg;
	int hue=0,hit;
	long offset;

	fcloseall();
	if(n<0||n>=M.Num_Plot)
		return(-2);
	fpimg=open_to_read_binary(Img[n].name);
	if(!fpimg)
	{
		if(fpimg)
			fclose(fpimg);
		return(-1);
	}
	row=Img[n].row;
	col=Img[n].col;
	if((long)col>=buffer_size)
		return(-5);
	for(i=0;i<row;i++)
	{
		if(kbhit()>0)
		{
			val=getch();
			if(val==27)
			{
				if(fpimg)
					fclose(fpimg);
				return(-4);
			}
		}
		if(fread((char *)buffer,sizeof(char),col,fpimg)<col)
		{
			if(fpimg)
				fclose(fpimg);
			return(-3);
		}
		hit=0;
		for(j=0;j<col;j++)
		{
			if(M.Msng==-1||buffer[j]!=M.Msng)
			{
				latlon(&lat,&lon,i,j,n);
				ll_xy(&x,&y,lat,lon);
				if(j==0)
					y1=y;
				val=M.assignment[buffer[j]]+16;
				if(val<0||val>255)
					return(-6);
				ix=x;iy=y;
				if(ix>=0&&ix<ScreenXs&&iy>=0&&iy<ScreenYs)
				{
					hit+=1;
					if(Dither==0)
						plotpt(hue,ix,iy,val);
					else
						plotpt(hue,ix,iy,Assignment[buffer[j]][(ix+iy)%2]);
				}
			}
			else if(j==0)
			{
				latlon(&lat,&lon,i,j,n);
				ll_xy(&x,&y,lat,lon);
				y1=y;
			}
		}
		if(hit==0&&y1>=ScreenYs)
		{
			if(fpimg)
				fclose(fpimg);
			return(1);
		}
		if(i>0&&hit==0&&y1<0.0)
		{
			dely=y1-y1o;
			dnum=-y1/dely;
			di=dnum-1;
			if(di>1)
			{
				offset=di;
				i+=di;
				if(i<0||i>=row)
					return(0);
				offset*=col;
				fseek(fpimg,offset,SEEK_CUR);
			}
		}
		y1o=y1;
	}
	if(fpimg)
		fclose(fpimg);
	return(1);
}

/* ******************************************************************
**
**	plots a point at coordinates x and y with gun hue and brightness val
**
**	functions called: -- none
**
**	return:
**		 1 = point plotted
**		-1 = point not plotted
********************************************************************* */

int xplotpt(hue,x,y,val)

int hue;	/* color plane -- 0-3 */
int x,y;	/* pixel coordinates */
int val;	/* brighness of pixel 0-255 */

{
	int status;
	
	WritePixel(y,x,val);
}




/**************************************************************************
**
**
**
***************************************************************************/

int latlon(lat,lon,row,col,n)

double *lat,*lon;
int row,col,n;

{
	double x,y;

	x=col;
	y=row;

	*lat=Img[n].a[0];
	*lat+=y*Img[n].a[1];
	if(Img[n].num_a>2)
		*lat+=y*y*Img[n].a[2];
	if(Img[n].num_a>3)
		*lat+=x*Img[n].a[3];
	if(Img[n].num_a>4)
		*lat+=x*x*Img[n].a[4];
	if(Img[n].num_a>5)
		*lat+=x*y*Img[n].a[5];

	*lon=Img[n].b[0];
	*lon+=x*Img[n].b[1];
	if(Img[n].num_b>2)
		*lon+=x*x*Img[n].b[2];
	if(Img[n].num_b>3)
		*lon+=y*Img[n].b[3];
	if(Img[n].num_b>4)
		*lon+=y*y*Img[n].b[4];
	if(Img[n].num_b>5)
		*lon+=y*x*Img[n].b[5];
}

/********************************************************************
**
**	locate a point
**
********************************************************************* */

void pix_loc(fx,fy,px,py,sp)

int fx,fy;			/* starting point of cursor */
int *px,*py,*sp;		/* pointers to final location */

{
	int i,j,l,m,p;
	int ans,size=0,speed,x,y,xo,yo,k,ans2,ans3,screen_xs=ScreenXs;
	int ans1;
	static unsigned char tbuff[200];
	int lsize=FontSize,val,ival,val1,val2;
	int cursize=15/FontSize,labelsize=FontSize;
	char string[100],pth[STR_LEN],nam[10],typ[10];
	int idc[2],clr;
	double lat,lon;
	FILE *fpblb;
	double dx,dy;
	int ix,iy,color=M.White,xc,txs,cspeed=8,tcolor[3],v_num=0;
	float fspeed=0.05;
	char latdir[2],londir[2];
	int td,nd;

	latdir[0]='N';
	latdir[1]='S';
	londir[0]='E';
	londir[1]='W';
	if(VideoType=='S')
		lsize=3;
	ScreenXs=MaxXs;
	speed=*sp;
	size=0;
	xo=x=fx;
	yo=y=fy;
	tcursor(0,x,y,5,tbuff);
	save_box(0,M.Back,(unsigned char *)Mbuff,
		0,ScreenYs-32/lsize,42*15/lsize,32/lsize);
	while((ans=getpad(&size,&x,&y,&speed,0))!=83&&ans!=27&&ans!=13)
	{
		if(ans=='h'||ans=='H'||ans==59)		/* F1 */
		{
			txs=ScreenXs;
			unsave_box(0,M.Back,(unsigned char *)Mbuff,
				0,ScreenYs-32/lsize,42*15/lsize,32/lsize);
			save_box(0,M.Back,(unsigned char *)Mbuff,
				0,0,MaxXs,32/lsize);
			paint_box(0,M.Back,MT_Buff,0,0,ScreenXs,32/lsize);
			sprintf(string,
"(L)abel vectors: move cursor near vector and hit enter to label (hit any key)"
			);
			plot_font_h(M.White,1,1,string,FontSize,Font);
			getch();
			paint_box(0,M.Back,MT_Buff,0,0,ScreenXs,32/lsize);
			sprintf(string,
"As with all options 'Esc' will end the Label option (hit any key)");
			plot_font_h(M.White,1,1,string,FontSize,Font);
			getch();
			unsave_box(0,M.Back,(unsigned char *)Mbuff,
				0,0,MaxXs,32/lsize);
			save_box(0,M.Back,(unsigned char *)Mbuff,
				0,ScreenYs-32/lsize,42*15/lsize,32/lsize);
		}
		uncursor(0,xo,yo,5,tbuff);
		val=getpt(0,x,y)-16;
		color=RED;
		tcursor(0,x,y,5,tbuff);
		cursor(0,x,y,color,5);
		dx=xo=x;
		dy=yo=y;
		if(ans=='L')
		{
			color=YELLOW;
			for(i=0;i<M.Num_Type;i++)
				Menu_V[i]=M.Group_Name[i];
			v_num=M_do_menu(Menu_V,M.Num_Type,MENUXC,25,v_num,
							M.Mback,M.Text,M.High,Font);
			uncursor(0,xo,yo,5,tbuff);
			tcursor(0,x,y,cursize,tbuff);
			cursor(0,x,y,color,cursize);
			while((ans1=getpad(&size,&x,&y,&speed,0))!=83&&ans1!=27)
			{
				i=v_num;
				uncursor(0,xo,yo,cursize,tbuff);
				if(ans1==13)
					vector_label(i,x,y,labelsize);
				if(ans1=='l'&&labelsize>1)
				{
					labelsize-=1;
					cursize=15/labelsize;
				}
				if(ans1=='s'&&labelsize<4)
				{
					labelsize+=1;
					cursize=15/labelsize;
				}
				tcursor(0,x,y,cursize,tbuff);
				cursor(0,x,y,color,cursize);
				xo=x;
				yo=y;
			}
			uncursor(0,xo,yo,cursize,tbuff);
			color=RED;
			cursor(0,x,y,color,5);
		}
		xy_ll(dx,dy,&lat,&lon);
		paint_box(0,M.Back,
			(unsigned char *)MT_Buff,0,ScreenYs-32/lsize,42*15/lsize,32/lsize);
		td=nd=0;
		if(lat<0.0)
			td=1;
		if(lon<0)
			nd=1;
		if(val>0)
			sprintf(string,"dn=%3d at %8.5lf%c %10.5lf%c",
				val,lat,latdir[td],lon,londir[nd]);
		else
			sprintf(string,"          %8.5lf%c %10.5lf%c",
				lat,latdir[td],lon,londir[nd]);
		plot_font_h(M.White,2,ScreenYs-30/lsize,string,lsize,Font);
		xo=x;yo=y;
	}
	uncursor(0,xo,yo,5,tbuff);
	unsave_box(0,M.Back,(unsigned char *)Mbuff,
		0,ScreenYs-32/lsize,42*15/lsize,32/lsize);
	*px=x;*py=y;*sp=speed;
	ScreenXs=screen_xs;
	return;
}


/**************************************************************************
**
**
**
************************************************************************* */

int vector_label(vi,ix,iy,size)

int vi,ix,iy,size;

{
	int i,j,k,ij;
	int boxsize=10;
	double x,y,maxlat,minlat,maxlon,minlon,mindist=100000000.0,rot,r;
	int v_num=0,val,cx,cy,hit=0,d1,d2=11/size,len;
	long attr,attrib;
	char string[100];
	float pixsize=M.Pixsize;

	x=ix+boxsize;
	y=iy-boxsize;
	xy_ll(x,y,&maxlat,&maxlon);
	x=ix-boxsize;
	y=iy+boxsize;
	xy_ll(x,y,&minlat,&minlon);
	x=ix;
	y=iy;
	i=vi;
	if(i>=0&&i<M.Num_Type)
	{
		for(j=0;j<M.Ns[i];j++)
		{
			if(M.ColFile[i][j].max_pix*PixScale>pixsize
				&&M.ColFile[i][j].min_pix*PixScale<=pixsize)
			{
				if(kbhit()>0)
				{
					val=getch();
					if(val==27)
						return(-2);
				}
				if(check_atr(M.ColFile[i][j].filename,&mindist,x,y,&cx,&cy,
					&attr,&r,maxlat,minlat,maxlon,minlon)>0)
				{
					attrib=attr;
					ij=j;
					ix=cx;
					iy=cy;
					hit+=1;
					rot=r;
				}
			}
		}
	}
	if(hit>0)
	{
		sprintf(string,"%ld",attrib);
		len=strlen(string)*15/size;
		d1=len/2;
		if(rot==0.0)
		{
			iy-=d2;
			ix-=d1;
			plot_font_h(M.ColFile[i][ij].color,ix,iy,string,size,Font);
		}
		else if(rot==90.0)
		{
			iy+=d1;
			ix-=d2;
			plot_font_v(M.ColFile[i][ij].color,ix,iy,string,size,Font);
		}
		else
		{
			r=rot*DEG_RAD;
			ix-=d1*cos(r)+d2*sin(r);
			iy+=d1*sin(r)-d2*cos(r);
			plot_font_rot(M.ColFile[i][ij].color,ix,iy,string,size,Font,rot);
		}
	}
}

/***********************************************************************
**
**
**
***********************************************************************/

int check_atr(region,mindist,cur_x,cur_y,cx,cy,
		attrib,rot,maxlat,minlat,maxlon,minlon)

char *region;
double *mindist,cur_x,cur_y;
int *cx,*cy;
long *attrib;
double *rot;
float maxlat,minlat,maxlon,minlon;

{
	int i,i1,i2,j,k,m,n=0,p;
	double x,y,xo,yo;
	int ix,iy,ixo=-1,iyo=-1;
	double dx,dy,dist;
	int secnum,numpt,numsec,ival;
	FILE *fp,*fphdr,*fpatr;
	float latlon[2],mll[4],mnln,mxln,mnlt,mxlt;
	char string[40],pth[40],name[40],type[40];
	int doit,numplot=0;
	int first_seg=-1,last_seg=-1,atr=1;
	long offset,attr;
	int changed=0,lag=2;
	float px[21],py[21],pi=-1,ox1,oy1,ox2,oy2;

	strcpy(string,region);
	strcat(string,".atr");
	fcloseall();
	fpatr=open_to_read_binary(string);
	if(!fpatr)
		return(-1);
	strcpy(string,region);
	strcat(string,".hdr");
	fphdr=open_to_read_binary(string);
	if(!fphdr)
		return(-1);
	setbuf(fphdr,Hdrbuff);
	strcpy(string,region);
	strcat(string,".bin");
	fp=open_to_read_binary(string);
	if(!fp)
		return(-1);
	setbuf(fp,Inbuff);
	fread((char *)&numsec,sizeof(int),1,fphdr);
	fread((char *)&numsec,sizeof(int),1,fp);
	for(j=0;j<numsec;j++)
	{
		if(kbhit()>0)
		{
			ival=getch();
			if(ival==27)
			{
				if(fp)
					fclose(fp);
				if(fpatr)
					fclose(fpatr);
				if(fphdr)
					fclose(fphdr);
				return(-2);
			}
		}
		fread((char *)&offset,sizeof(long),1,fphdr);
		fread((char *)mll,sizeof(float),4,fphdr);
		fread((char *)&attr,sizeof(long),1,fpatr);
		doit=1;
		mnln=mll[0];mxln=mll[1];mnlt=mll[2];mxlt=mll[3];
		if(mnln>maxlon||mnlt>maxlat||mxln<minlon||mxlt<minlat)
		{
			doit=0;
		}
		if(doit==1)
		{
			numplot+=1;
			fseek(fp,offset,SEEK_SET);
			fread((char *)&numpt,sizeof(int),1,fp);
			fread((char *)mll,sizeof(float),4,fp);
			m=0;
			pi=-1000;
			for(i=0;i<numpt;i++)
			{
				fread((char *)latlon,sizeof(float),2,fp);
				ll_xy(&x,&y,(double)latlon[0],(double)latlon[1]);
				px[i%21]=x;
				py[i%21]=y;
				if(doit==1)
				{
					dist=(cur_x-x)*(cur_x-x)+(cur_y-y)*(cur_y-y);
					if(dist<*mindist)
					{
						*attrib=attr;
						*mindist=dist;
						*cx=x;
						*cy=y;
						changed+=1;
						pi=i;
						i1=i-lag;
						if(i1<0)
							i1=0;
						ox1=px[i1%21];
						oy1=py[i1%21];
					}
				}
				if(i-pi<=lag)
				{
					ox2=x;
					oy2=y;
				}
			}
		}
	}
	if(fp)
		fclose(fp);
	if(fphdr)
		fclose(fphdr);
	if(fpatr)
		fclose(fpatr);
	x=ox2-ox1;
	y=oy2-oy1;
	*rot=0.0;
	if(x==0.0)
		*rot=90.0;
	else
	{
		 if(y!=0.0)
			*rot=atan2(-y,x)/DEG_RAD;	
		else
			*rot=0.0;
	}
	if(*rot>90.0)
		*rot-=180.0;
	if(*rot<-90.0)
		*rot+=180.0;
	return(changed);
}



/**************************************************************************
**
**
**
************************************************************************* */

int read_control(filename)

char *filename;

{
	int i,j,k,n=1,m;
	FILE *fp,*fp2;
	char string1[STR_LEN],string2[STR_LEN],string2a[STR_LEN],string3[STR_LEN];
	char string2b[STR_LEN],type;
	int numread,val,numcolors;
	char cval;
	double lat,lon;

	M.Msng=-1;
	M.Min_Pix=0.0;
	fp=open_to_read_binary(filename);
	if(!fp)
		return(-1);
	fscanf(fp,"%s",string1);
	if(strlen(string1)==1)
	{
		type=string1[0];
		if(type=='l'||type=='a'||type=='m'||
			type=='s'||type=='p'||type=='S')
		{
			M.Type=type;
			numread=fscanf(fp,"%f%f%f%f",&M.Pixsize,&M.Clat,&M.Clon,&M.Space);
			if(numread!=4)
			{
				return(-6);
			}
		}
	}

	do
	{
		numread=fscanf(fp,"%s",string1);
	}while(numread>0&&strcmpi(string1,"begin_color")!=0);
	if(numread<1)
		return(-2);		/* could not find 'begin_color' */

	i=0;
	do
	{
		fscanf(fp,"%s",M.Color_Name[i]);
		if(strcmpi(M.Color_Name[i],"end_color")!=0)
		{
			numread=fscanf(fp,"%s%d%d%d",
				string1,&M.Color_Val[i][0],&M.Color_Val[i][1],&M.Color_Val[i][2]);
			if(strcmpi(M.Color_Name[i],"white")==0)
			{
				M.White=i;
			}
			if(strcmpi(M.Color_Name[i],"black")==0)
			{
				M.Black=i;
			}
		}
		i+=1;
	}while(numread==4&&strcmpi(M.Color_Name[i-1],"end_color")!=0&&i<MAX_COLORS);
	numcolors=i;
	do
	{
		numread=fscanf(fp,"%s",string1);
		if(strcmpi(string1,"menu_background")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.Mback=val;
			else
			{
				printf("'%s' %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
		if(strcmpi(string1,"text")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.Text=val;
			else
			{
				printf("'%s' %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
		if(strcmpi(string1,"highlight")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.High=val;
			else
			{
				printf("'%s %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
		if(strcmpi(string1,"background")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.Back=val;
			else
			{
				printf("'%s' %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
		if(strcmpi(string1,"graticule")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.Grat=val;
			else
			{
				printf("'%s' %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
		if(strcmpi(string1,"lat/lon")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.LatLon=val;
			else
			{
				printf("'%s' %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
		if(strcmpi(string1,"black")==0)
		{
			fscanf(fp,"%s%s",string2,string3);
			val=get_color(string3);
			if(val>=0&&val<MAX_COLORS)
				M.Black=val;
			else
			{
				printf("'%s' %s '%s'\n",string1,string2,string3);
				return(-5);	/* bad color name */
			}
		}
	}while(numread>0&&strcmpi(string1,"begin_vector")!=0);
	if(numread<1)
		return(-3);		/* could not find 'begin_vector' */
	i=0;
	do
	{
		numread=fscanf(fp,"%s",M.Group_Name[i]);
/* do collage */
		if(numread==1&&strcmpi(M.Group_Name[i],"begin_collage")==0)
		{
			M.Plot_At=i++;
			M.Plot=1;
			do
			{
				fscanf(fp,"%s",string1);
				if(strcmpi(string1,"end_collage")!=0)
				{
					if(strcmpi(string1,"missing")==0)
					{
						fscanf(fp,"%s%d",string1,&M.Msng);
					}
					if(strcmpi(string1,"minimum_pixel")==0)
					{
						fscanf(fp,"%s%f",string1,&M.Min_Pix);
					}
					if(strcmpi(string1,"color_lut")==0)
					{
						fscanf(fp,"%s",string1);
						fscanf(fp,"%s",string1);
						fp2=open_to_read_text(string1);
						if(!fp2)
						{
							printf("Could not open '%s'\n",string1);
							exit(0);
						}
						else
						{
							for(k=0;k<240;k++)
							{
								if(fscanf(fp2,"%d%d%d%d",&j,&M.lut[k+16].r,
												&M.lut[k+16].g,&M.lut[k+16].b)<4)
									break;
							}
							if(fp2)
								fclose(fp2);
						}
					}
					if(strcmpi(string1,"assignment")==0)
					{
						fscanf(fp,"%s",string1);
						fscanf(fp,"%s",string1);
						fp2=open_to_read_text(string1);
						if(!fp2)
						{
							printf("Could not open '%s'\n",string1);
							exit(0);
						}
						else
						{
							for(k=0;k<256;k++)
							{
								if(fscanf(fp2,"%d%d",&j,&M.assignment[k])<2)
									break;
							}
							if(fp2)
								fclose(fp2);
						}
					}
					if(strcmpi(string1,"begin_image")==0)
					{
						m=0;
						while((cval=fgetc(fp))!='*'&&cval!=EOF);
						if(cval==EOF)
						{
							printf("Hit unexpected EOF in collage header: no '*'\n\n");
							exit(0);
						}
						do
						{
							fscanf(fp,"%s",string1);
							if(strcmpi(string1,"end_image")!=0)
							{
								strcpy(Img[m].name,string1);
								fscanf(fp,"%f%f",&Img[m].max_pix,&Img[m].min_pix);
								fscanf(fp,"%d%d",&Img[m].row,&Img[m].col);
								fscanf(fp,"%d",&Img[m].num_a);
if(Verbose==1)
	printf("%s %8.4f %8.4f %d %d %d\n",
		Img[m].name,Img[m].max_pix,Img[m].min_pix,
		Img[m].row,Img[m].col,Img[m].num_a);
								if(Img[m].num_a>6)
								{
									printf("Too many a's '%s'\n",string1);
									exit(0);
								}
								else
								{
									for(n=0;n<Img[m].num_a;n++)
									{
										fscanf(fp,"%f",&Img[m].a[n]);
if(Verbose==1)
	printf("  %14.7e",Img[m].a[n]);
									}
								}
								fscanf(fp,"%d",&Img[m].num_b);
if(Verbose==1)
	printf("\n%d\n",Img[m].num_b);
								if(Img[m].num_b>6)
								{
									printf("Too many b's '%s'\n",string1);
									exit(0);
								}
								else
								{
									for(n=0;n<Img[m].num_b;n++)
									{
										fscanf(fp,"%f",&Img[m].b[n]);
if(Verbose==1)
	printf("  %14.7e",Img[m].b[n]);
									}
								}
if(Verbose==1)
	printf("\n");
									latlon(&lat,&lon,0,0,m);
									Img[m].maxlat=lat;
									Img[m].minlon=lon;
									latlon(&lat,&lon,Img[m].row,Img[m].col,m);
									Img[m].minlat=lat;
									Img[m].maxlon=lon;
									latlon(&lat,&lon,Img[m].row,0,m);
									if(lat>Img[m].maxlat)
										Img[m].maxlat=lat;
									if(lon>Img[m].maxlon)
										Img[m].maxlon=lon;
									if(lat<Img[m].minlat)
										Img[m].minlat=lat;
									if(lon<Img[m].minlon)
										Img[m].minlon=lon;
									latlon(&lat,&lon,0,Img[m].col,m);
									if(lat>Img[m].maxlat)
										Img[m].maxlat=lat;
									if(lon>Img[m].maxlon)
										Img[m].maxlon=lon;
									if(lat<Img[m].minlat)
										Img[m].minlat=lat;
									if(lon<Img[m].minlon)
										Img[m].minlon=lon;
								m+=1;
							}
						}while(strcmpi(string1,"end_image")!=0);
						M.Num_Plot=m;
					}
				}
			}while(strcmpi(string1,"end_collage")!=0);
			numread=3;
		}
		else
		{
			if(numread==1&&strcmpi(M.Group_Name[i],"end_vector")!=0)
			{
				numread=fscanf(fp,"%s%d%s",
					string1,&M.Ns[i],string2);
				strcpy(T_Menu_L[i][0],M.Group_Name[i]);
				strcat(T_Menu_L[i][0]," OFF");
				strcpy(T_Menu_L[i][1],M.Group_Name[i]);
				strcat(T_Menu_L[i][1]," ON");
				if(strcmpi(string2,"ON")==0)
					M.Mm[i]=1;
				else
					M.Mm[i]=0;
				if(M.Ns[i]==0||M.Ns[i]>NUM_SIZE)
				{
					printf("Bad M.Ns = %d\n",M.Ns[i]);
					return(-4);	/* too many vectors in a group */
				}
			}
			for(k=0;k<M.Ns[i];k++)
			{
				fscanf(fp,"%s%f%f%s",M.ColFile[i][k].filename,
					&M.ColFile[i][k].max_pix,&M.ColFile[i][k].min_pix,
					string1);
				val=get_color(string1);
				if(val>=0&&val<MAX_COLORS)
					M.ColFile[i][k].color=val;
				else
				{
					printf("'%s' %f %f '%s'\n",
						M.ColFile[i][k].filename,
						M.ColFile[i][k].max_pix,M.ColFile[i][k].min_pix,
						string1);
					return(-5);	/* bad color name */
				}
			}
			i+=1;
		}
	}while(numread==3&&strcmpi(M.Group_Name[i-1],"end_vector")!=0&&i<NUM_TYPE);
	i-=1;
	M.Num_Type=i;
	strcpy(T_Menu_L[i+0][0],"all ON");
	strcpy(T_Menu_L[i+0][1],"all ON");
	strcpy(T_Menu_L[i+1][0],"all OFF");
	strcpy(T_Menu_L[i+1][1],"all OFF");
	strcpy(T_Menu_L[i+2][0],"exit");
	strcpy(T_Menu_L[i+2][1],"exit");
	if(fp)
		fclose(fp);
	return(1);
}


/**************************************************************************
**
**
**
************************************************************************* */

int annotate(ix,iy,size,color)

int *ix,*iy,*size,*color;

{
	int i,j,k;
	char string[STR_LEN],ans,ans2;
	int xc=*ix,yc=*iy,xs=ScreenXs-(*ix),ys=28/(*size),speed=16;
	int cxc=0,cyc=ScreenYs-28/(*size),cxs=ScreenXs,cys=28/(*size);
	int background=0;

	if(*color==0)
		background=M.Back;
if((long)cxs*(long)cys>Mbuff_Size)
{
video_off();
printf("box too big at 3\n");
exit(0);
}
	save_box(0,background,
				(unsigned char *)Mbuff,cxc,cyc,cxs,cys);
	i=0;
	do
	{
		ans=getch();
		if(ans==8&&i>0)
		{
			i-=1;
			string[i]='\0';
if((long)cxs*(long)cys>Mbuff_Size)
{
video_off();
printf("box too big at 4\n");
exit(0);
}
			unsave_box(0,background,
				(unsigned char *)Mbuff,cxc,cyc,cxs,cys);
if((long)cxs*(long)cys>Mbuff_Size)
{
video_off();
printf("box too big at 5\n");
exit(0);
}
			save_box(0,background,
				(unsigned char *)Mbuff,cxc,cyc,cxs,cys);
			plot_font_h(*color,cxc,cyc,string,*size,Font);
		}
		if(ans>=0x20)
		{
			string[i]=ans;
			string[i+1]='\0';
			plot_font_h(*color,cxc,cyc,string,*size,Font);
			i+=1;
		}
		if(ans==0)
		{
			ans2=getch();
			if(ans2==77)
				*color+=1;
			if(ans2==75)
				*color-=1;
			if(*color>15)
				*color=0;
			if(*color<0)
				*color=15;
			if(*color==0)
				background=M.Back;
			else
				background=0;
if((long)cxs*(long)cys>Mbuff_Size)
{
video_off();
printf("box too big at 6\n");
exit(0);
}
			unsave_box(0,background,
				(unsigned char *)Mbuff,cxc,cyc,cxs,cys);
			if(ans2==80&&*size<4)
				*size+=1;
			if(ans2==72&&*size>1)
				*size-=1;
			cyc=ScreenYs-28/(*size);
			ys=cys=28/(*size);
if((long)cxs*(long)cys>Mbuff_Size)
{
video_off();
printf("box too big at 7\n");
exit(0);
}
			save_box(0,background,
				(unsigned char *)Mbuff,cxc,cyc,cxs,cys);
			plot_font_h(*color,cxc,cyc,string,*size,Font);
		}
	}while(ans!=27&&ans!=13);
if((long)cxs*(long)cys>Mbuff_Size)
{
video_off();
printf("box too big at 8\n");
exit(0);
}
	unsave_box(0,background,
				(unsigned char *)Mbuff,cxc,cyc,cxs,cys);
	if(ans==27)
		return(ans);
	xs=strlen(string)*15/(*size);
	if(limit_area(&xc,&yc,&xs,&ys,&speed,ScreenXs,0,
				(unsigned char *)Mbuff)!=27)
		plot_font_h(*color,xc,yc,string,*size,Font);
	*ix=xc;
	*iy=yc;
	return(ans);
}

/**************************************************************************
**
**
**
************************************************************************* */

int draw_line(ix,iy,color)

int *ix,*iy,*color;

{
	int i,j,k;
	char string[STR_LEN],ans,ans2;
	int x1=*ix,x2,y1=*iy,y2,speed=16,xo=*ix,yo=*iy;
	int val;

	val=getpt(0,x1,y1);
	tcursor(3,x1,y1,7,(unsigned char *)Mbuff);
	cursor(0,x1,y1,M.Comp_Color[val],7);
	do
	{
		ans=getch();
		if(ans==0)
		{
			ans2=getch();
			if(ans2==71)
			{
				x1-=speed;
				y1-=speed;
			}
			if(ans2==73)
			{
				x1+=speed;
				y1-=speed;
			}
			if(ans2==79)
			{
				x1-=speed;
				y1+=speed;
			}
			if(ans2==81)
			{
				x1+=speed;
				y1+=speed;
			}
			if(ans2==72)
				y1-=speed;
			if(ans2==80)
				y1+=speed;
			if(ans2==75)
				x1-=speed;
			if(ans2==77)
				x1+=speed;
			if(x1<0)
				x1=0;
			if(x1>=ScreenXs)
				x1=ScreenXs-1;
			if(y1<0)
				y1=0;
			if(y1>=ScreenYs)
				y1=ScreenYs-1;
		}
		if(ans=='-'&&speed>2)
			speed/=2;
		if(ans=='+'&&speed<128)
			speed*=2;
		uncursor(3,xo,yo,7,(unsigned char *)Mbuff);
		val=getpt(0,x1,y1);
		tcursor(3,x1,y1,7,(unsigned char *)Mbuff);
		cursor(0,x1,y1,M.Comp_Color[val],7);
		xo=x1;
		yo=y1;
	}while(ans!=27&&ans!=13);
	uncursor(3,xo,yo,7,(unsigned char *)Mbuff);
	if(ans==27)
		return(ans);
	xo=x2=x1;yo=y2=y1;
	tplotln_inv_dot(0,x1,y1,x2,y2,(unsigned char *)Mbuff,ScreenXs);
	tcursor(3,x2,y2,7,(unsigned char *)Buffer);
	cursor(0,x2,y2,*color,7);
	do
	{
		ans=getch();
		if(ans==0)
		{
			ans2=getch();
			if(ans2==71)
			{
				x2-=speed;
				y2-=speed;
			}
			if(ans2==73)
			{
				x2+=speed;
				y2-=speed;
			}
			if(ans2==79)
			{
				x2-=speed;
				y2+=speed;
			}
			if(ans2==81)
			{
				x2+=speed;
				y2+=speed;
			}
			if(ans2==72)
				y2-=speed;
			if(ans2==80)
				y2+=speed;
			if(ans2==75)
				x2-=speed;
			if(ans2==77)
				x2+=speed;
			if(x2<0)
				x2=0;
			if(x2>=ScreenXs)
				x2=ScreenXs-1;
			if(y2<0)
				y2=0;
			if(y2>=ScreenYs)
				y2=ScreenYs-1;
		}
		if(ans=='c')
			*color-=1;
		if(ans=='C')
			*color+=1;
		if(*color>15)
			*color=0;
		if(*color<0)
			*color=15;
		if(ans=='-'&&speed>2)
			speed/=2;
		if(ans=='+'&&speed<128)
			speed*=2;
		uncursor(0,xo,yo,7,Buffer);
		unplotln(0,x1,y1,xo,yo,(unsigned char *)Mbuff);
		xo=x2;
		yo=y2;
		tplotln_inv_dot(0,x1,y1,x2,y2,(unsigned char *)Mbuff,ScreenXs);
		plotln(0,x1,y1,x2,y2,*color);
		tcursor(0,x2,y2,7,Buffer);
		cursor(0,x2,y2,*color,7);
	}while(ans!=27&&ans!=13);
	uncursor(3,xo,yo,7,Buffer);
	unplotln(0,x1,y1,xo,yo,(unsigned char *)Mbuff);
	if(ans==27)
		return(ans);
	plotln(0,x1,y1,x2,y2,*color);
	*ix=x2;
	*iy=y2;
	return(ans);
}


/**************************************************************************
**
**
**
************************************************************************* */

int vector_plot(pixsize)

double pixsize;

{
	int i,j,k;
	int v_num=0,val;

	for(i=0;i<M.Num_Type;i++)
		Menu_V[i]=M.Group_Name[i];
	v_num=M_do_menu(Menu_V,M.Num_Type,MENUXC,25,v_num,
							M.Mback,M.Text,M.High,Font);
	i=v_num;
	if(i>=0&&i<M.Num_Type)
	{
		for(j=0;j<M.Ns[i];j++)
		{
			if(M.ColFile[i][j].max_pix*PixScale>pixsize
				&&M.ColFile[i][j].min_pix*PixScale<=pixsize)
			{
				if(kbhit()>0)
				{
					val=getch();
					if(val==27)
						return(-2);
				}
				convert_bin(M.ColFile[i][j].color,
					M.ColFile[i][j].filename);
			}
		}
	}
}


/**************************************************************************
**
**
**
************************************************************************* */

int search_list(list,string)

char *list,*string;

{
	int i,j,k;
	int p=-1;
	int val,kbval;

	for(j=0;j<NumPath;j++)
	{
		if(kbhit()>0)
		{
			kbval=getch();
			if(kbval==27)
				return(-2);
		}
		sprintf(String,"%s%s",Path[j],list);
		if(load_names(String)>0)
			val=get_file_name(String,string);
		else
			val=-1;
		if(val>=0)
			return(val);
	}
	return(val);
}


/**************************************************************************
**
**
**
************************************************************************* */

int save_col(name)

char *name;

{
	int i,j,k;
	FILE *fp;
	double lat,lon;

	ScreenXs=MaxXs;
	ScreenYs=MaxYs;
	xy_ll((double)(ScreenXs/2),(double)(ScreenYs/2),&lat,&lon);
	miv.indat[0]=M.Pixsize;
	miv.indat[1]=M.Clat=lat;
	miv.indat[2]=M.Clon=lon;
	miv.indat[3]=M.Clon;
	miv.indat[4]=M.Clat+10;
	miv.indat[5]=M.Clat-10;
	map_pos.xc=0;	
	map_pos.yc=0;
	map_pos.xs=ScreenXs;
	map_pos.ys=ScreenYs;
	auto_set_cc(miv.type,miv.indat);
	fp=open_to_write_binary(name);
	if(!fp)
		return(-1);
	setbuf(fp,Inbuff);
	M.screen_xs=ScreenXs;
	M.screen_ys=ScreenYs;
	fwrite((char *)&M,sizeof(struct col),1,fp);
	fwrite((char *)Img,sizeof(struct image_name),M.Num_Plot,fp);
	for(i=0;i<MaxYs;i++)
	{
		getrow(0,0,MaxXs-1,i,Buffer);
		fwrite((char *)Buffer,sizeof(char),MaxXs,fp);
	}
	if(fp)
		fclose(fp);
	return(1);
}

/**************************************************************************
**
**
**
************************************************************************* */

int unsave_col(name)

char *name;

{
	int i,j,k;
	FILE *fp;

	ScreenXs=MaxXs;
	ScreenYs=MaxYs;
	fp=open_to_read_binary(name);
	if(!fp)
		return(-1);
	setbuf(fp,Outbuff);
	fread((char *)&M,sizeof(struct col),1,fp);
	fread((char *)Img,sizeof(struct image_name),M.Num_Plot,fp);
if(M.Num_Plot>=MAX_IMG)
{
	video_off();
	printf("in 'unsave_col()':  Too many images\n");
	exit(0);
}
	ScreenXs=M.screen_xs;
	ScreenYs=M.screen_ys;
	WritePalette(M.lut); 
	for(i=0;i<MaxYs;i++)
	{
		fread((char *)Buffer,sizeof(char),MaxXs,fp);
		plotrow(0,0,MaxXs-1,i,Buffer);
	}
	if(fp)
		fclose(fp);
	miv.indat[0]=M.Pixsize;
	miv.indat[1]=M.Clat;
	miv.indat[2]=M.Clon;
	miv.indat[3]=M.Clon;
	miv.indat[4]=M.Clat+10;
	miv.indat[5]=M.Clat-10;
	miv.type=M.Type;
	map_pos.xc=0;	
	map_pos.yc=0;
	map_pos.xs=ScreenXs;
	map_pos.ys=ScreenYs;
	auto_set_cc(miv.type,miv.indat);
	screen_mm();
	for(i=0;i<M.Num_Type;i++)
	{
		strcpy(T_Menu_L[i][0],M.Group_Name[i]);
		strcat(T_Menu_L[i][0]," OFF");
		strcpy(T_Menu_L[i][1],M.Group_Name[i]);
		strcat(T_Menu_L[i][1]," ON");
	}
	i=M.Num_Type;
	strcpy(T_Menu_L[i+0][0],"all ON");
	strcpy(T_Menu_L[i+0][1],"all ON");
	strcpy(T_Menu_L[i+1][0],"all OFF");
	strcpy(T_Menu_L[i+1][1],"all OFF");
	strcpy(T_Menu_L[i+2][0],"exit");
	strcpy(T_Menu_L[i+2][1],"exit");
	return(1);
}


/**************************************************************************
**
**
**
************************************************************************* */

int video_on()

{
	int i,row;

	i=GetVideoBoardID();
	i=GetVideoBoardID();
	M.Num_Color=256;
	if(VideoType=='X')
	{
		row=SetVideoMode(480,&B_Id);
		if(B_Id.row<400)
			VideoType='V';
		else
		{
			ScreenXs=640;
			ScreenYs=B_Id.row;
		}
		if(B_Id.row==480)
			strcpy(Suffix,".xcl");
		else
			strcpy(Suffix,".ycl");
	}
	if(VideoType=='Y')
	{
		row=SetVideoMode(400,&B_Id);
		if(B_Id.row<400)
			VideoType='V';
		else
		{
			ScreenXs=640;
			ScreenYs=400;
		}
		strcpy(Suffix,".ycl");
	}
	if(VideoType=='V')
	{
		row=SetVideoMode(0x12,&B_Id);
		if(B_Id.row!=480)
			VideoType='E';
		else
		{
			ScreenXs=640;
			ScreenYs=480;
			M.Num_Color=16;
			strcpy(Suffix,".vcl");
			Dither=1;
		}
	}
	if(VideoType=='S')
	{
		row=SetVideoMode(0x13,&B_Id);
		if(B_Id.row!=200)
		{
			SetVideoMode(0,&B_Id);
			printf("Could not boot color board.\n");
			exit(0);
		}
		ScreenXs=320;
		ScreenYs=200;
		M.Num_Color=256;
		strcpy(Suffix,".scl");
		FontSize=3;
	}
	if(VideoType=='E')
	{
		row=SetVideoMode(0x10,&B_Id);
		if(B_Id.row!=350)
		{
			SetVideoMode(0,&B_Id);
			printf("Could not boot color board.\n");
			exit(0);
		}
		ScreenXs=640;
		ScreenYs=350;
		M.Num_Color=16;
		strcpy(Suffix,".ecl");
		Dither=1;
	}
	if(B_Id.row<0)
	{
		SetVideoMode(0,&B_Id);
		printf("Could not boot board -- row = %d\n\n",B_Id.row);
		exit(0);
	}
	MaxXs=ScreenXs;
	MaxYs=ScreenYs;
	PixScale=480.0;
	PixScale/=(float)ScreenYs;
	WritePalette(M.lut); 
}



/********************************************************************
**
**	WARNING!!!!  YOU MUST CALL decode_font() or set_files() before using
**
**     options:
**
**       -1 -- remove menu but get no answer
**        0 -- return answer and set menu colors to greys
**        1 -- return answer but leave colors alone
**
********************************************************************* */

int M_do_menu(menu,num,xc,yc,start,back,words,boxs,font)

char *menu[];
int num,xc,yc,start,back,words,boxs;
int font[128][25];

{
	int i,j,k;
	char ans,ans2;
	int len=0,l,size=FontSize,val,valo;
	int black=0,dgrey=back,lgrey=words,white=boxs;
	int wide;

	for(k=0;k<num;k++)
		if((l=strlen(menu[k]))>len)len=l;
	if(len==0)return(-1);
	wide=(len+1)*15/size+1;
	if((ScreenXs-1-wide)<xc)xc=ScreenXs-1-wide;

	if((xc+(len+1)*15/size+1)<ScreenXs)
	{
if((long)((len+1)*15/size+1)*(long)(30/size*num+1)>Mbuff_Size)
{
	video_off();
	printf("box too big at 9\n");
	exit(0);
}
		save_box(0,dgrey,
				(unsigned char *)Mbuff,
			xc,yc,(len+1)*15/size+1,30/size*num+1);

		for(k=0;k<num;k++)
		{	
			box(0,xc,yc+k*(30/size),dgrey,(len+1)*15/size,30/size);
			plot_font_h(lgrey,
					xc+15/size,yc+k*30/size+5/size,menu[k],size,font);
		}
		box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);

		val=valo=start;
		box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		do
		{
			if((ans=getch())==0)
			{
				ans2=getch();
				if(ans2==50)
				{
					unsave_box(0,dgrey,
						(unsigned char *)Mbuff,
						xc,yc,(len+1)*15/size+1,30/size*num+1);
					getch();
					paint_box(0,dgrey,
						(unsigned char *)MT_Buff,
						xc,yc,(len+1)*15/size+1,30/size*num+1);
					for(k=0;k<num;k++)
					{	
						plot_font_h(lgrey,
					xc+15/size,
									yc+k*30/size+5/size,menu[k],size,font);
					}
				}
				if(ans2=='H')
				{
					if(val>0)val-=1;
					else val=num-1;
				}
				if(ans2=='P')
				{
					if(val<num-1)val+=1;
					else val=0;
				}
			}

			for(i=0;i<num;i++)
				if(ans==menu[i][0])
				{
					val=i;
					ans=13;
				}
			box(0,xc,yc+valo*(30/size),dgrey,(len+1)*15/size,30/size);
			valo=val;
			box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);
			box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
			if(ans==27)
			{
				val=num-1;
				ans=13;
			}
		}while(ans!=13);
	}
	box(0,xc,yc,dgrey,(len+1)*15/size,30/size*num);
	box(0,xc,yc+val*(30/size),lgrey,(len+1)*15/size,30/size);
if((long)((len+1)*15/size+1)*(30/size*num+1)>Mbuff_Size)
{
video_off();
printf("box too big at 10\n");
exit(0);
}
	unsave_box(0,dgrey,
				(unsigned char *)Mbuff,
			xc,yc,(len+1)*15/size+1,30/size*num+1);

	return(val);
}



/********************************************************************
**
**	WARNING!!!!  YOU MUST CALL decode_font() or set_files() before using
**
**     options:
**
**       -1 -- remove menu but get no answer
**        0 -- return answer and set menu colors to greys
**        1 -- return answer but leave colors alone
**
********************************************************************* */

int T_do_menu(menu,num,xc,yc,start,back,words,boxs,font,off_on)

char menu[][2][50];
int num,xc,yc,start,back,words,boxs;
int font[128][25],*off_on;

{
	int i,j,k;
	char ans,ans2;
	int len=0,l,size=FontSize,val,valo;
	int black=0,dgrey=back,lgrey=words,white=boxs;
	int wide;

	for(k=0;k<num;k++)
		if((l=strlen(menu[k][0]))>len)len=l;
	if(len==0)return(-1);
	wide=(len+1)*15/size+1;
	if((639-wide)<xc)xc=639-wide;

	if((xc+(len+1)*15/size+1)<640)
	{
		paint_box(0,dgrey,
				(unsigned char *)Mbuff,xc,yc,(len+1)*15/size+1,30/size*num+1);
		for(k=0;k<num-3;k++)
		{	
			box(0,xc,yc+k*(30/size),dgrey,(len+1)*15/size,30/size);
			plot_font_h(lgrey,xc+15/size,yc+k*30/size+5/size,menu[k][off_on[k]],
				size,font);
		}
		for(k=num-3;k<num;k++)
		{	
			box(0,xc,yc+k*(30/size),dgrey,(len+1)*15/size,30/size);
			plot_font_h(lgrey,xc+15/size,yc+k*30/size+5/size,menu[k][0],
				size,font);
		}
		box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);

		val=valo=start;
		box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		do
		{
			ans=getch();
			if(ans==13)
			{
				if(val<num-3)
				{
					if(off_on[val]==0)
						off_on[val]=1;
					else
						off_on[val]=0;
				}
				if(val==num-3)
					for(k=0;k<num-3;k++)
						off_on[k]=1;
				if(val==num-2)
					for(k=0;k<num-3;k++)
						off_on[k]=0;
				paint_box(0,dgrey,
					(unsigned char *)Mbuff,xc,yc,
					(len+1)*15/size+1,30/size*num+1);
				for(k=0;k<num-3;k++)
				{	
					box(0,xc,yc+k*(30/size),dgrey,(len+1)*15/size,30/size);
					plot_font_h(lgrey,xc+15/size,yc+k*30/size+5/size,
							menu[k][off_on[k]],size,font);
				}
				for(k=num-3;k<num;k++)
				{	
					box(0,xc,yc+k*(30/size),dgrey,(len+1)*15/size,30/size);
					plot_font_h(lgrey,xc+15/size,yc+k*30/size+5/size,
							menu[k][0],size,font);
				}
				box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);
			}
			if(ans==13&&val==num-1)
				ans=27;
			if(ans==0)
			{
				ans2=getch();
				if(ans2=='H')
				{
					if(val>0)val-=1;
					else val=num-1;
				}
				if(ans2=='P')
				{
					if(val<num-1)val+=1;
					else val=0;
				}
			}
			for(i=0;i<num;i++)
				if(ans==menu[i][0][0])
				{
					val=i;
					ans=27;
				}
			box(0,xc,yc+valo*(30/size),dgrey,(len+1)*15/size,30/size);
			valo=val;
			box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);
			box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		}while(ans!=27);
	}
	box(0,xc,yc,dgrey,(len+1)*15/size,30/size*num);
	box(0,xc,yc+val*(30/size),lgrey,(len+1)*15/size,30/size);

	return(val);
}


/**************************************************************************
**
**
**
************************************************************************* */

int get_color(string)

char *string;

{
	int i,j,k;
	int val=-1;

	for(i=0;i<MAX_COLORS;i++)
		if(strcmpi(M.Color_Name[i],string)==0)
			return(i);
	return(-1);
}

/********************************************************************
**
**
**
********************************************************************* */

char zoom(xc,yc,xs,ys,pixsize,clat,clon,space)

int xc,yc,xs,ys;
float *pixsize,*clat,*clon,*space;

{
	int i,j,k,k1,k2;
	char ans,ans2;
	int ix[4],iy[4],speed=16;
	float m_ps=*pixsize,m_clon=*clon,m_clat=*clat,m_space=*space;
	float cur_ps=*pixsize/1.7320508;		/* 3**1/2 */
	float cur_clon=*clon,cur_clat=*clat,cur_space=*space;
	float cur_scale=1.200937;	/* 3**1/6 */
	int cur_ix=xc+xs/2,cur_iy=yc+ys/2;
	double dlat,dlon;
	int txs,screen_xs,lsize=FontSize;

	if(VideoType=='S')
		lsize=3;
	if(cur_ps<M.Min_Pix)cur_ps=M.Min_Pix;

	xy_ll((double)cur_ix,(double)cur_iy,&dlat,&dlon);
	cur_clat=dlat;cur_clon=dlon;
	get_corners(xc,yc,xs,ys,m_ps,m_clat,m_clon,cur_ps,cur_clat,cur_clon,ix,iy);
	tplot_line(3,ix[0],iy[0]+1,ix[1],iy[1],MT_Buff[0]);
	tplot_line(3,ix[1]+1,iy[1],ix[2],iy[2],MT_Buff[1]);
	tplot_line(3,ix[2],iy[2]-1,ix[3],iy[3],MT_Buff[2]);
	tplot_line(3,ix[3]-1,iy[3],ix[0],iy[0],MT_Buff[3]);
	do
	{
		ans=getch();
		if(ans==0)
		{
			ans2=getch();
			if(ans2==59)		/* F1 */
				ans='H';
			else
			{
				if(ans2=='G'||ans2=='H'||ans2=='I')cur_iy-=speed;
				if(ans2=='I'||ans2=='M'||ans2=='Q')cur_ix+=speed;
				if(ans2=='O'||ans2=='P'||ans2=='Q')cur_iy+=speed;
				if(ans2=='O'||ans2=='K'||ans2=='G')cur_ix-=speed;
				if(cur_iy<yc)cur_iy=yc;
				if(cur_ix<xc)cur_ix=xc;
				if(cur_iy>yc+ys-1)cur_iy=yc+ys-1;
				if(cur_ix>xc+xs-1)cur_ix=xc+xs-1;
			}
		}
		if(ans=='h'||ans=='H')
		{
			txs=ScreenXs;
			ScreenXs=MaxXs;
			save_box(0,M.Back,
				(unsigned char *)Mbuff,
				0,0,MaxXs,32/lsize);
			paint_box(0,M.Back,
				(unsigned char *)MT_Buff,0,0,ScreenXs,32/lsize);
			sprintf(String,
"(s)maller (l)arger 'Enter'=plot  'Esc'=exit without plotting");
			plot_font_h(M.White,1,1,String,FontSize,Font);
			ans=getch();
			unsave_box(0,M.Back,
				(unsigned char *)Mbuff,0,0,MaxXs,32/lsize);
			ScreenXs=txs;
		}		

		if(ans=='l')cur_ps*=cur_scale;
		if(ans=='s')cur_ps/=cur_scale;
		if(cur_ps<M.Min_Pix)cur_ps=M.Min_Pix;
		if(ans=='-')
		{
			if(speed>1)
				speed/=2;
			else
				cur_scale=sqrt((double)cur_scale);
		}
		if(ans=='+'&&speed<256)speed*=2;
		unplot_line(3,ix[0],iy[0]+1,ix[1],iy[1],MT_Buff[0]);
		unplot_line(3,ix[1]+1,iy[1],ix[2],iy[2],MT_Buff[1]);
		unplot_line(3,ix[2],iy[2]-1,ix[3],iy[3],MT_Buff[2]);
		unplot_line(3,ix[3]-1,iy[3],ix[0],iy[0],MT_Buff[3]);
		xy_ll((double)cur_ix,(double)cur_iy,&dlat,&dlon);
		cur_clat=dlat;cur_clon=dlon;
		get_corners(xc,yc,xs,ys,
			m_ps,m_clat,m_clon,cur_ps,cur_clat,cur_clon,ix,iy);
		tplot_line(3,ix[0],iy[0]+1,ix[1],iy[1],MT_Buff[0]);
		tplot_line(3,ix[1]+1,iy[1],ix[2],iy[2],MT_Buff[1]);
		tplot_line(3,ix[2],iy[2]-1,ix[3],iy[3],MT_Buff[2]);
		tplot_line(3,ix[3]-1,iy[3],ix[0],iy[0],MT_Buff[3]);
	}while(ans!=83&&ans!=27&&ans!=13);
	unplot_line(3,ix[0],iy[0]+1,ix[1],iy[1],MT_Buff[0]);
	unplot_line(3,ix[1]+1,iy[1],ix[2],iy[2],MT_Buff[1]);
	unplot_line(3,ix[2],iy[2]-1,ix[3],iy[3],MT_Buff[2]);
	unplot_line(3,ix[3]-1,iy[3],ix[0],iy[0],MT_Buff[3]);
	M.Pixsize=*pixsize=cur_ps;
	M.Clat=*clat=cur_clat;
	M.Clon=*clon=cur_clon;
	if(cur_ps<20)
	{	
		*space=30.0;
		return(ans);
	}
	if(cur_ps<10)
	{	
		*space=15.0;
		return(ans);
	}
	if(cur_ps<2)
	{	
		*space=5.0;
		return(ans);
	}
	*space=1.0;
	return(ans);
}


/********************************************************************
**
**
**
********************************************************************* */

void get_corners(xc,yc,xs,ys,m_pixsize,m_clat,m_clon,
		cur_pixsize,cur_clat,cur_clon,x,y)

int xc,yc,xs,ys;
double m_pixsize,m_clat,m_clon,cur_pixsize,cur_clat,cur_clon;
int x[4],y[4];

{
	int i,j,k;
	double lat[4],lon[4],dx,dy;

	miv.indat[0]=cur_pixsize;
	miv.indat[1]=cur_clat;
	miv.indat[2]=cur_clon;
	miv.indat[3]=cur_clon;
	miv.indat[4]=cur_clat+10;
	miv.indat[5]=cur_clat-10;
	map_pos.xc=xc;	
	map_pos.yc=yc;
	map_pos.xs=xs;
	map_pos.ys=ys;
	auto_set_cc(miv.type,miv.indat);
	
	xy_ll((double)xc,(double)yc,lat+0,lon+0);
	xy_ll((double)xc,(double)yc+ys-1,lat+1,lon+1);
	xy_ll((double)xc+xs-1,(double)yc+ys-1,lat+2,lon+2);
	xy_ll((double)xc+xs-1,(double)yc,lat+3,lon+3);

	miv.indat[0]=m_pixsize;
	miv.indat[1]=m_clat;
	miv.indat[2]=m_clon;
	miv.indat[3]=m_clon;
	miv.indat[4]=m_clat+10;
	miv.indat[5]=m_clat-10;
	map_pos.xc=xc;	
	map_pos.yc=yc;
	map_pos.xs=xs;
	map_pos.ys=ys;
	auto_set_cc(miv.type,miv.indat);

	for(i=0;i<4;i++)
	{
		ll_xy(&dx,&dy,lat[i],lon[i]);
		x[i]=dx;
		y[i]=dy;
	}
}

/*******************************************************************
**
**	draw a line on the image and save data destroyed in buffer
**
**	returns the number of points ploted
**
********************************************************************* */

int tplot_line(hue,x1,y1,x2,y2,buffer)

int hue;	/* image plane */
int x1,y1;	/* coordinates of 1st point */
int x2,y2;	/* coordinates of 2nd point */
unsigned char *buffer;

{
	int numpts=0,val;
	int   i, j, k, numx, numy;
	float x, y, dy, dx;

	if(hue<0 || hue>3) return(-1);

	numx = ( x2 > x1 ) ? x2-x1 : x1-x2;
	numy = ( y2 > y1 ) ? y2-y1 : y1-y2;

	if(numx==0 && numy==0) return(-1);

	if( numx>numy ) 
	{
		dy = (float)(y2-y1)/(float)(x2-x1);
		dx = (x2>x1) ? 1.0 : -1.0;
		i = x = x1;
		j = y = y1;
		for(k=0;k<=(numx);k++)
		{
			if(i>=0&&i<=ScreenXs-1&&j>=0&&j<=ScreenYs-1)
			{
				val=buffer[numpts]=getpt(hue,i,j);
				numpts+=1;
				val=(val==M.High)?M.Black:M.High;
				plotpt(hue,i,j,val);
			}
			x += dx;
			y += dy*dx;
			i = x+0.5;
			j = y+0.5;
		}
	}
	else
	{
		dx = (float)(x2-x1)/(float)(y2-y1);
		dy = (y2>y1) ? 1.0 : -1.0;
		i = x = x1;
		j = y = y1;
		for(k=0;k<=(numy);k++)
		{
			if(i>=0&&i<=ScreenXs-1&&j>=0&&j<=ScreenYs-1)
			{
				val=buffer[numpts]=getpt(hue,i,j);
				numpts+=1;
				val=(val==M.High)?M.Black:M.High;
				plotpt(hue,i,j,val);
			}
			x += dx*dy;
			y += dy;
			i = x+0.5;
			j = y+0.5;
		}
	}
	return(numpts);
}

/******************************************************************
**
**	undraw a line on the image using data in buffer
**
**	returns the number of points unploted
**
********************************************************************* */

int unplot_line(hue,x1,y1,x2,y2,buffer)

int hue;	/* image plane */
int x1,y1;	/* coordinates of 1st point */
int x2,y2;	/* coordinates of 2nd point */
unsigned char *buffer;

{
	int numpts=0,val;
	int   i, j, k, numx, numy;
	float x, y, dy, dx;

	if(hue<0 || hue>3) return(-1);

	numx = ( x2 > x1 ) ? x2-x1 : x1-x2;
	numy = ( y2 > y1 ) ? y2-y1 : y1-y2;

	if(numx==0 && numy==0) return(-1);

	if( numx>numy ) 
	{
		dy = (float)(y2-y1)/(float)(x2-x1);
		dx = (x2>x1) ? 1.0 : -1.0;
		i = x = x1;
		j = y = y1;
		for(k=0;k<=(numx);k++)
		{
			if(i>=0&&i<=ScreenXs-1&&j>=0&&j<=ScreenYs-1)
			{
				plotpt(hue,i,j,buffer[numpts]);
				numpts+=1;
			}
			x += dx;
			y += dy*dx;
			i = x+0.5;
			j = y+0.5;
		}
	}
	else
	{
		dx = (float)(x2-x1)/(float)(y2-y1);
		dy = (y2>y1) ? 1.0 : -1.0;
		i = x = x1;
		j = y = y1;
		for(k=0;k<=(numy);k++)
		{
			if(i>=0&&i<=ScreenXs-1&&j>=0&&j<=ScreenYs-1)
			{
				plotpt(hue,i,j,buffer[numpts]);
				numpts+=1;
			}
			x += dx*dy;
			y += dy;
			i = x+0.5;
			j = y+0.5;
		}
	}
	return(numpts);
}

/********************************************************************
**
**
**
********************************************************************* */

void screen_mm()

{
	double lat,lon,x,y;
	float flat,flon,lon_r,lon_l;

	MaxLat=-360.0;
	MaxLon=-360.0;
	MinLat= 360.0;
	MinLon= 360.0;

	x=0.0;y=0.0;
	xy_ll(x,y,&lat,&lon);
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=0.0;y=ScreenYs/2.0;
	xy_ll(x,y,&lat,&lon);lon_l=lon;
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=0.0;y=ScreenYs;
	xy_ll(x,y,&lat,&lon);
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=320.0;y=ScreenYs;
	xy_ll(x,y,&lat,&lon);
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=ScreenXs;y=ScreenYs;
	xy_ll(x,y,&lat,&lon);
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=ScreenXs;y=ScreenXs/2;
	xy_ll(x,y,&lat,&lon);lon_r=lon;
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=ScreenXs;y=  0.0;
	xy_ll(x,y,&lat,&lon);
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	x=ScreenXs/2;y=  0.0;
	xy_ll(x,y,&lat,&lon);
	flat=lat;flon=lon;
	if(flat>MaxLat)MaxLat=flat;
	if(flon>MaxLon)MaxLon=flon;
	if(flat<MinLat)MinLat=flat;
	if(flon<MinLon)MinLon=flon;
	if(lon_l>180.0)
		lon_l-=360.0;
	if(lon_r>180.0)
		lon_r-=360.0;

	lat=-89.999;	/* south pole check */
	ll_xy(&x,&y,lat,lon);
	if(x>=0.0&&x<640.0&&y>0.0&&y<480.0)
	{		
		MinLat=-90.001;
		MinLon=-360.0;
		MaxLon= 360.0;
	}
	lat=89.999;	/* north pole check */
	ll_xy(&x,&y,lat,lon);
	if(x>=0.0&&x<640.0&&y>0.0&&y<480.0)
	{		
		MaxLat= 90.001;
		MinLon=-360.0;
		MaxLon= 360.0;
	}
	if(lon_l>lon_r)	/* date line on screen */
	{
		MinLon=-360.0;
		MaxLon= 360.0;
	}
}


/***********************************************************************
**
**
**
***********************************************************************/

int convert_bin(val,region)

char *region;
int val;

{
	int i,j,k,m,n=0,p;
	double x,y,xo,yo;
	int ix,iy,ixo=-1,iyo=-1;
	double dx,dy,dist;
	int secnum,numpt,numsec,ival;
	FILE *fp,*fphdr,*fpatr;
	float latlon[2],mll[4],mnln,mxln,mnlt,mxlt;
	char string[40],pth[40],name[40],type[40];
	int doit,numplot=0;
	int first_seg=-1,last_seg=-1,atr=1;
	long offset,attrib;

	strcpy(string,region);
	strcat(string,".hdr");
	fcloseall();
	fphdr=open_to_read_binary(string);
	if(!fphdr)
		return(-1);
	setbuf(fphdr,Hdrbuff);
	strcpy(string,region);
	strcat(string,".bin");
	fp=open_to_read_binary(string);
	if(!fp)
		return(-1);
	setbuf(fp,Inbuff);
	fread((char *)&numsec,sizeof(int),1,fphdr);
	fread((char *)&numsec,sizeof(int),1,fp);
	for(j=0;j<numsec;j++)
	{
		if(kbhit()>0)
		{
			ival=getch();
			if(ival==27)
			{
				if(fp)
					fclose(fp);
				if(fpatr)
					fclose(fpatr);
				if(fphdr)
					fclose(fphdr);
				return(-2);
			}
		}
		fread((char *)&offset,sizeof(long),1,fphdr);
		fread((char *)mll,sizeof(float),4,fphdr);
		doit=1;
		mnln=mll[0];mxln=mll[1];mnlt=mll[2];mxlt=mll[3];
		if(mnln>MaxLon||mnlt>MaxLat||mxln<MinLon||mxlt<MinLat)
		{
			doit=0;
		}
		if(doit==1)
		{
			numplot+=1;
			fseek(fp,offset,SEEK_SET);
			fread((char *)&numpt,sizeof(int),1,fp);
			fread((char *)mll,sizeof(float),4,fp);
			m=0;
			for(i=0;i<numpt;i++)
			{
				fread((char *)latlon,sizeof(float),2,fp);
				if(doit==1)
				{
					ll_xy(&x,&y,(double)latlon[0],(double)latlon[1]);
					if(i==0)
					{
						xo=x;yo=y;
						ixo=ix;iyo=iy;
					}
					ix=x;iy=y;
					dist=(xo-x)*(xo-x)+(yo-y)*(yo-y);
					if(dist<1000000.0)
					{
						plotpt(3,ix,iy,val);
						if(i>0)
							plotln(3,ix,iy,ixo,iyo,val);
						ixo=ix;iyo=iy;
						xo=ix;yo=iy;
					}
				}
			}
		}
	}
	if(fp)
		fclose(fp);
	if(fphdr)
		fclose(fphdr);
	return(numplot);
}

/**************************************************************************
**
**
**
************************************************************************* */

int split(string,path,name,type)

char *string,*path,*name,*type;

{
	int i,j,k;
	int dot=-1,last_slash=-1,len=strlen(string),num=0;

	if(strlen(string)>STR_LEN)
	{
		SetVideoMode(0,&B_Id);
		printf("In split() -- string 1 too long!\n\n");
		exit(0);
	}

	for(i=0;i<len;i++)
	{
		if(string[i]=='.')
			dot=i;
		if(string[i]=='\\')
			last_slash=i;
	}
	last_slash+=1;
	if(dot==-1)
		dot=len-1;
	if(last_slash>0)
	{
		for(i=0;i<last_slash;i++)
			path[i]=string[i];
	}
	path[last_slash]='\0';
	for(i=last_slash;i<dot;i++)
		name[i-last_slash]=string[i];
	name[dot-last_slash]='\0';
	dot+=1;
	for(i=dot;i<len;i++)
		type[i-dot]=string[i];
	type[len-dot]='\0';
	if(strlen(name)>0)
		num+=1;
	if(strlen(type)>0)
		num+=1;

	return(num);
}


/********************************************************************
**
**	type  g -- grey all lut[] files
**			G -- grey only lut[]
**			i -- initial header col
**			r -- reset lut[] to lutc[]
**
**	iop == 1 don't print RGB etc.
**
**
********************************************************************* */

void set_lut(type,iop)

char type;
int iop;

{
	int i,j,k;
	int hue,brite,m,n,p,q;
	double dbrite,dval;
	long mindist,dist,r,g,b,r0,g0,b0;
	long mind1,d1,mind2,d2,r1,g1,b1,r2,g2,b2;
	int color=0,greyval[16],greynum=0;

	if(type=='c')
	{
		for(k=0;k<MAX_COLORS;k++)
		{		
			M.lut[ k].r=M.Color_Val[k][0];
			M.lut[ k].g=M.Color_Val[k][1];
			M.lut[ k].b=M.Color_Val[k][2];
		}
	}
	if(M.Num_Color==16)
	{
		if(Dither==1)
		{
			for(i=0;i<256;i++)
			{
				k=M.assignment[i];
				r0=M.lut[k+16].r;
				g0=M.lut[k+16].g;
				b0=M.lut[k+16].b;
				if(r0!=g0||r0!=b0||b0!=g0)
					color+=1;
			}
			if(color==0)
			{
				k=0;
				for(i=0;i<16;i++)
				{
					if(M.lut[i].r==M.lut[i].g&&M.lut[i].g==M.lut[i].b)
					{
						greyval[greynum]=i;
						greynum+=1;
					}
				}
				if(greynum<3)	/* no greys in VGA colors */
					color=1;
				else
				{
					for(i=0;i<256;i++)
					{
						mind1=mind2=mindist=16777217;
						k=M.assignment[i];
						r0=M.lut[k+16].r;
						g0=M.lut[k+16].g;
						b0=M.lut[k+16].b;
						for(p=0;p<greynum;p++)
						{
							r1=M.lut[m].r;
							g1=M.lut[m].g;
							b1=M.lut[m].b;
							d1=(r1-r0)*(r1-r0)+(g1-g0)*(g1-g0)+(b1-b0)*(b1-b0);
							m=greyval[p];
							for(q=0;q<greynum;q++)
							{
								r2=M.lut[m].r;
								g2=M.lut[m].g;
								b2=M.lut[m].b;
								d2=(r2-r0)*(r2-r0)+(g2-g0)*(g2-g0)+(b2-b0)*(b2-b0);
								n=greyval[q];
								r=((long)M.lut[m].r+(long)M.lut[n].r)/2;
								g=((long)M.lut[m].g+(long)M.lut[n].g)/2;
								b=((long)M.lut[m].b+(long)M.lut[n].b)/2;
								dist=(r0-r)*(r0-r)+(g0-g)*(g0-g)+(b0-b)*(b0-b);
								if(dist<mindist||(dist==mindist&&d1+d2<mind1+mind2))
								{
									Assignment[i][0]=m;
									Assignment[i][1]=n;
									mindist=dist;
									mind1=d1;
									mind2=d2;
								}
							}
						}	
					}
				}
			}
			if(color!=0)
			{
				for(i=0;i<256;i++)
				{
					mindist=16777217;
					k=M.assignment[i];
					r0=M.lut[k+16].r;
					g0=M.lut[k+16].g;
					b0=M.lut[k+16].b;
					for(m=0;m<16;m++)
					{
						if(m!=M.Back)
						{
							for(n=0;n<16;n++)
							{
								if(n!=M.Back)
								{
									r=((long)M.lut[m].r+(long)M.lut[n].r)/2;
									g=((long)M.lut[m].g+(long)M.lut[n].g)/2;
									b=((long)M.lut[m].b+(long)M.lut[n].b)/2;
									dist=(r0-r)*(r0-r)+(g0-g)*(g0-g)+(b0-b)*(b0-b);
									if(dist<mindist)
									{
										Assignment[i][0]=m;
										Assignment[i][1]=n;
										mindist=dist;
									}
								}
							}	
						}
					}
				}
			}
		}
		else
		{
			for(i=0;i<256;i++)
			{
				m=-1;
				mindist=16777217;
				k=M.assignment[i];
				r0=M.lut[k+16].r;
				g0=M.lut[k+16].g;
				b0=M.lut[k+16].b;
				for(j=0;j<16;j++)
				{
					if(j!=M.Back)
					{
						dist=(r0-(long)M.lut[j].r)*(r0-(long)M.lut[j].r)+
							  (g0-(long)M.lut[j].g)*(g0-(long)M.lut[j].g)+
							  (b0-(long)M.lut[j].b)*(b0-(long)M.lut[j].b);
						if(dist<mindist)
						{
							m=j;
							mindist=dist;
						}
					}
				}
				M.assignment[i]=m-16;
			}
		}
	}
	WritePalette(M.lut); 
}

                    