/*
	glum_bin.c

	gb1.bat = cl /AL glum_bin.c getfile

*/
#include <stdio.h>
#include <string.h>
#include "getfile.h"
#include "nomouse.h"

#define MaxSeg 10000
#define MaxPts 1000

int MaxNum=10;
float LatLon[MaxPts][2];
float Lat1[MaxSeg],Latn[MaxSeg],Lon1[MaxSeg],Lonn[MaxSeg];
long Atr[MaxSeg],Ptr[MaxSeg];
int Num[MaxSeg],Order[1000],Used[MaxSeg];

int check_num(int num,FILE *fpbin,FILE *fphdr,FILE *fpatr);
int set_glum(int num,int numseg);
int process(char *name,int *oldnum,int *newnum);
int Auto=0;

main(int argc,char *argv[])

{
	int i,j,k,n;
	char string[100],name[100];
	FILE *fpbin=NULL,*fpbat,*fptxt;
	int num=0,oldnum,newnum,maxnum,numfile,totseg=0,glumnum=0,tnum=0;
	float ftotold=0.0,ftotnew;

	if(argc>1&&sscanf(argv[1],"%d",&maxnum)==1)
		MaxNum=maxnum;
	else if(argc>2&&sscanf(argv[2],"%d",&maxnum)==1)
		MaxNum=maxnum;
	if(argv[1][0]=='*')
	{
		Auto=1;
		strcpy(name,"*.bin");
	}
	else
	{
		for(k=0;k<strlen(argv[1]);k++)
			if(argv[1][k]=='*'||argv[1][k]=='?')
				Auto=1;
		if(Auto>0)
		{
			strcpy(string,argv[1]);
			for(k=0;k<strlen(string);k++)
				if(string[k]=='.')
					string[k]='\0';
			sprintf(name,"%s.bin",string);
		}
	}
	if(Auto>0)
	{
		numfile=load_names(name);
		if(numfile<=0)
		{
			printf("All Process chosen but no BIN files in directory.\n\n");
			exit(0);
		}
		printf("There are %d files for Auto Processing.\n",numfile);
	}	
	else
	{
		if(argc>1)
		{
			sprintf(name,"%s.bin",argv[1]);
			fpbin=fopen(name,"rb");
		}
		if(!fpbin&&argc>2)
		{
			sprintf(name,"%s.bin",argv[2]);
			fpbin=fopen(name,"rb");
		}
		if(!fpbin)
		{
			if(get_file_name("*.bin",name,num)<0)
				exit(0);
		}
		fpbin=fopen(name,"rb");
		if(!fpbin)
		{
			printf("Could not open '%s'\n\n",name);
			exit(0);
		}
		fclose(fpbin);
	}
	if(Auto==0)
		process(name,&oldnum,&newnum);
	else
	{
		fpbat=fopen("glum.bat","wt");
		if(fpbat)
		{
			printf("\nSee file GLUM.BAT for combining RAW files.\n\n");
			fprintf(fpbat,"del glum*.raw\n");
			fprintf(fpbat,"copy ");
		}
		fptxt=fopen("glum.txt","wt");
		if(fptxt)
		{
			printf("\nSee file GLUM.TXT for summary of processing.\n\n");
		}
		for(n=0;n<numfile;n++)
		{
			printf("\nWorking file '%s' -- %d of %d\n",
				GF_File[n].name,n+1,numfile);
			for(i=0;i<MaxSeg;i++)
				Used[i]=0;
			process(GF_File[n].name,&oldnum,&newnum);
			ftotold+=oldnum;
			ftotnew+=newnum;
			printf("TOTAL SEGMENTS: %0.0f of %0.0f -- %0.1f percent\n",
				ftotnew,ftotold,ftotnew/ftotold*100.0);
			if(fptxt)
			{
				fprintf(fptxt,"\nFile '%s' -- %d of %d\n",
					GF_File[n].name,n+1,numfile);
				fprintf(fptxt,"      SEGMENTS: %d of %d -- %0.1f percent\n",
					newnum,oldnum,(float)newnum/(float)oldnum*(float)100.0);
				fprintf(fptxt,"TOTAL SEGMENTS: %0.0f of %0.0f -- %0.1f percent\n",
					ftotnew,ftotold,ftotnew/ftotold*100.0);
			}
			totseg+=newnum;
			if(totseg<9000)
			{
				if(fpbat&&tnum==0)
					fprintf(fpbat,"%s.raw",GF_File[n].name);
				else if(fpbat)
					fprintf(fpbat,"+%s.raw",GF_File[n].name);
				tnum+=1;
			}
			else if(fpbat)
			{
				tnum=1;
				fprintf(fpbat," glum%02d.raw\ncopy ",++glumnum);
				fprintf(fpbat,"%s.raw",GF_File[n].name);
			}
		}
	}
	if(fpbat)
		fprintf(fpbat," glum%02d.raw\n",++glumnum);
	fclose(fpbat);
}


/**********************************************************************
**
**
**
**********************************************************************/

int process(char *name,int *oldnum,int *newnum)

{
	int i,j,k;
	char string[100],cr=0xd;
	FILE *fpbin=NULL,*fphdr,*fpatr,*fpraw;
	int num=0,numseg,newseg,maxnum;

	fpbin=fopen(name,"rb");
	if(!fpbin)
	{
		printf("Could not open '%s'\n\n",name);
		return(-1);
	}
	fread((char *)&numseg,sizeof(int),1,fpbin);
	for(k=0;k<strlen(name);k++)
		if(name[k]=='.')
			name[k]='\0';
	sprintf(string,"%s.hdr",name);
	fphdr=fopen(string,"rb");
	if(!fphdr)
	{
		printf("Could not open '%s'\n\n",string);
		return(-1);
	}
	sprintf(string,"%s.atr",name);
	fpatr=fopen(string,"rb");
	if(!fpatr)
	{
		printf("Could not open '%s'\n\n",string);
		return(-1);
	}
	printf("Checking '%s' for qualifying segments:\n",name);
	num=check_num(MaxNum,fpbin,fphdr,fpatr);
	if(num<2)
	{
		printf("No segments of %d points or less to process.\n\n");
		return(-1);
	}
	printf("There are %d segments of length %d or less.\n",num,MaxNum);
	printf("Assigning segments to GLUM together:\n");
	newseg=set_glum(MaxNum,numseg);
	printf("%cThere are only %d segments left out of %d -- %0.2f percent\n",
		cr,newseg,numseg,(float)newseg/(float)numseg*(float)100.0);
	fclose(fpatr);
	fclose(fphdr);
	sprintf(string,"%s.raw",name);
	fpraw=fopen(string,"wt");
	if(!fpraw)
	{
		printf("Could not open '%s'\n\n",string);
		return(-1);
	}
	printf("Making new RAW file:\n");
	make_raw(newseg,fpraw,fpbin);
	fclose(fpbin);
	fclose(fpraw);
	unlink("glum_bin.dir");
	*oldnum=numseg;
	*newnum=newseg;
}


/**********************************************************************
**
**
**
**********************************************************************/

int make_raw(int newseg,FILE *fpraw,FILE *fpbin)

{
	int i,j,k,n;
	FILE *fpdir;
	char cr=0xd;
	int id,num,avid;
	long atr,offset;
	int numpt;
	float mll[4];

	fpdir=fopen("glum_bin.dir","rt");
	if(!fpdir)
	{
		printf("Could not open 'glum_bin.dir' to read.\n\n");
		exit(0);
	}
	for(i=0;i<newseg;i++)
	{
		if(fscanf(fpdir,"%d%d%ld",&id,&num,&atr)<2)
		{
			printf("EOF in 'glum_bin.dir'\n");
			exit(0);
		}
		printf("%6d %4d %6ld%c",id,num,atr,cr);
		if(id!=i+1)
		{
			printf("Bad id -- i=%d  id=%d\n",i,id);
			exit(0);
		}
		fprintf(fpraw,"%6d",atr);
		n=0;
		for(j=0;j<num;j++)
		{
			fscanf(fpdir,"%d",&id);
			if(id>0)
				avid=id;
			else
				avid=-id;
			avid-=1;
			offset=Ptr[avid];
			fseek(fpbin,offset,SEEK_SET);
			fread((char *)&numpt,sizeof(int),1,fpbin);
			fread((char *)mll,sizeof(float),4,fpbin);
			fread((char *)LatLon,sizeof(float),numpt*2,fpbin);
			if(id>0)
			{
				if(j==0)
				{
					fprintf(fpraw,"\n%10.6lf %11.6lf",LatLon[0][0],LatLon[0][1]);
					n+=1;
				}
				for(k=1;k<numpt;k++)
				{
					if(n%3==0)
						fprintf(fpraw,"\n");
					else
						fprintf(fpraw,"  ");
					n+=1;
					fprintf(fpraw,"%10.6lf %11.6lf",LatLon[k][0],LatLon[k][1]);
				}
			}
			else
			{
				if(j==0)
				{
					n+=1;
					fprintf(fpraw,"\n%10.6lf %11.6lf",LatLon[numpt-1][0],LatLon[numpt-1][1]);
				}
				for(k=numpt-2;k>=0;k--)
				{
					if(n%3==0)
						fprintf(fpraw,"\n");
					else
						fprintf(fpraw,"  ");
					n+=1;
					fprintf(fpraw,"%10.6lf %11.6lf",LatLon[k][0],LatLon[k][1]);
				}
			}
		}
		fprintf(fpraw,"//\n");
	}
	fprintf(fpraw,"\n");
	fclose(fpdir);
}

/**********************************************************************
**
**
**
**********************************************************************/

int set_glum(int num,int numseg)

{
	int i,j,k;
	int hit=0,glum;
	float mll[4];
	int newseg=numseg,n,count=0;
	FILE *fpdir;
	char cr=0xd;

	fpdir=fopen("glum_bin.dir","wt");
	if(!fpdir)
	{
		printf("Could not open 'glum_bin.dir'\n\n");
		exit(0);
	}
	for(i=0;i<numseg;i++)
	{
		printf("%6d left of %6d (%6d)%c",newseg,numseg,count+1,cr);
		Order[0]=i+1;
		if(Used[i]==0)
		{
			n=1;
			if(Num[i]<=MaxNum)
			{
				do
				{
					hit=0;
					for(j=i+1;j<numseg;j++)
					{
						if(Num[j]<=MaxNum&&Used[j]==0
							&&Atr[i]==Atr[j]&&n+Num[j]<MaxPts/2)
						{
						/* add to end */
							if(Latn[i]==Lat1[j]&&Lonn[i]==Lon1[j])
							{	
								hit+=1;
								newseg-=1;
								Order[n]=j+1;
								n+=1;
								Latn[i]=Latn[j];
								Lonn[i]=Lonn[j];
								Used[j]=1;
							}
						/* add to end -- reverse */
							if(Used[j]==0&&Latn[i]==Latn[j]&&Lonn[i]==Lonn[j])
							{
								hit+=1;
								newseg-=1;
								Order[n]=-(j+1);
								n+=1;
								Latn[i]=Lat1[j];
								Lonn[i]=Lon1[j];
								Used[j]=1;
							}
						/* add to beginning */
							if(Used[j]==0&&Lat1[i]==Latn[j]&&Lon1[i]==Lonn[j])
							{
								hit+=1;
								newseg-=1;
								for(k=n;k>0;k--)
									Order[k]=Order[k-1];
								Order[0]=j+1;
								n+=1;
								Lat1[i]=Lat1[j];
								Lon1[i]=Lon1[j];
								Used[j]=1;
							}
						/* add to beginning -- reverse */
							if(Used[j]==0&&Lat1[i]==Lat1[j]&&Lon1[i]==Lon1[j])
							{
								hit+=1;
								newseg-=1;
								for(k=n;k>0;k--)
									Order[k]=Order[k-1];
								Order[0]=-(j+1);
								n+=1;
								Lat1[i]=Latn[j];
								Lon1[i]=Lonn[j];
								Used[j]=1;
							}
						}
					}
				}while(hit>0);
			}
			count+=1;
			fprintf(fpdir,"%d %d   %ld\n",count,n,Atr[i]);
				for(k=0;k<n;k++)
					fprintf(fpdir,"%d ",Order[k]);
			fprintf(fpdir,"\n");
		}
	}
	fclose(fpdir);
	return(newseg);
}


/**********************************************************************
**
**
**
**********************************************************************/

int check_num(int num,FILE *fpbin,FILE *fphdr,FILE *fpatr)

{
	int i,numseg,numpt,hit=0;
	float mll[4];

	rewind(fpbin);
	rewind(fphdr);
	rewind(fpatr);
	fread((char *)&numseg,sizeof(int),1,fpbin);
	fread((char *)&numseg,sizeof(int),1,fphdr);
	if(numseg>MaxSeg)
	{
		printf("Too many segments.\n");
		exit(0);
	}
	for(i=0;i<numseg;i++)
	{
		fread((char *)&Atr[i],sizeof(long),1,fpatr);
		fread((char *)&Ptr[i],sizeof(long),1,fphdr);
		fread((char *)mll,sizeof(float),4,fphdr);
		fread((char *)&numpt,sizeof(int),1,fpbin);
		if(numpt>MaxPts)
		{
			printf("Too many points in segment %d\n",i+1);
			exit(0);
		}
		Num[i]=numpt;
		fread((char *)mll,sizeof(float),4,fpbin);
		fread((char *)LatLon,sizeof(float),numpt*2,fpbin);
		if(numpt<=num)
			hit+=1;
		Lat1[i]=LatLon[0][0];
		Lon1[i]=LatLon[0][1];
		Latn[i]=LatLon[numpt-1][0];
		Lonn[i]=LatLon[numpt-1][1];
	}
	return(hit);
}                     