/*
	getfile.c

	uses interupts to get directory information

	R. Ambroziak USGS/OMG

*/

#include <stdio.h>
#include <ctype.h>
#include <memory.h>
#include <dos.h>
#include <string.h>
#include "mouseg.h"

#define MAX_NUM 300
#define PAUSE printf("HIT ANY KEY TO CONTINUE.\n");getch()
#define SCREEN_WIDTH 160
#define EQLIST 0x410
#define MEMSIZ 0x413
#define NAME_SIZE 100
#define S_SIZE 40
#define F_SIZE 20
#define T_SIZE 15

extern int Mouse;
int TabSize=5;
struct file_id
{
	char name[S_SIZE];
	long size;
	unsigned date,time;
}GF_File[MAX_NUM];
long Tsize=0;
int NumEmpty;
int GF_Order[MAX_NUM];

unsigned char far *Video_Buffer[4]=
	{(unsigned char *)0xb8000000,(unsigned char *)0xb8000000,
	 (unsigned char *)0xb8000000,(unsigned char *)0xb0000000};
int Monitor;

union REGS regs;
char GF_String[MAX_NUM][S_SIZE];
struct equipment
{
	int printers; 		/* number present */
	int sprinter;		/* serial printer installed?  0=no  1=yes */
	int game;			/* game adapter installed? */
	int sports;			/* number of serial ports */
	int dma;				/* DMA chip installed? */
	int drives;			/* number of disk drives */
	int video;			/* video mode 1=40 color 2=80 color 3=80 B/W */
	int disk;			/* any disk drives? */
	int memory;			/* memory size in Kbytes */
}Eq;

int check_equip(struct equipment *);
void ClearBox(int,int,int,int,int);
void ClearScreen(int);
void date_convert(unsigned,int *,int *,int *);
void DoubleBox(int,int,int,int,int);
void file_name(char *,char *,char *);
int get_file_name(char *,char *);
int get_name(int,char *);
int get_num(void);
int load_File(char *);
int load_names(char *);
void print_files(int);
void ScrollDown(int,int,int,int,int,int);
int scroll_list(int,int,int,int,char [MAX_NUM][S_SIZE],int,char *);
void ScrollUp(int,int,int,int,int,int);
void SetCursor(int,int);
void sort_date(int);
void sort_name(int);
void sort_size(int);
void sort_time(int);
void time_convert(unsigned,int *,int *);
void WriteStringAtxy(int,int,int,unsigned char,unsigned char *);

/********************************************************************
**
**		returns:
**
**			-3 -- too many files of type given
**			-2 -- no such files
**			-1 -- no file chosen
**		  >=0 -- number of file chosen = n of String[n]
**
**
********************************************************************* */

int get_file_name(file_id,file_name)

char *file_id,*file_name;

{
	int i,j,k;
	int num_files;
	int val=-2;
	char string[NAME_SIZE],file[F_SIZE],type[T_SIZE],directory[NAME_SIZE];
	int t=0,d=0,ls=-1;

	Monitor=check_equip(&Eq);

	for(i=0;i<strlen(file_id);i++)
		if(file_id[i]=='\\')
			ls=i;
	if(ls>0)
	{
		d=1;
		strcpy(directory,file_id);
		directory[ls+1]='\0';
	}
	else
		directory[0]='\0';

	num_files=load_File(file_id);

	if(num_files<=0)
		return(-1);
	else
	{
		ClearBox(40,79,0,0,112);
		sprintf(string," %s",file_id);
		WriteStringAtxy(40,0,39,(char)112,string);
		val=scroll_list(40,1,40,21,GF_String,num_files,file_name);
		if(val>=0)
		{
			sscanf(file_name,"%s%s",file,type);
			if(file_name[9]!=' ')
				t=1;
			if(d==1)
			{
				strcpy(file_name,directory);
				strcat(file_name,file);
			}
			else
				strcpy(file_name,file);
			if(t==1)
			{
				strcat(file_name,".");
				strcat(file_name,type);
			}
			if(file_name[strlen(file_name)-1]=='.')
				file_name[strlen(file_name)-1]='\0';
		}	
	}
	return(val);
}


/********************************************************************
**
**
**
********************************************************************* */

int scroll_list(xc,yc,xs,ys,string,num,out_string)

int xc,yc,xs,ys,num;
char string[NAME_SIZE][S_SIZE],*out_string;

{
	if(Mouse==0)
		keyboard_scroll_list(xc,yc,xs,ys,string,num,out_string);
	else
		mouse_scroll_list(xc,yc,xs,ys,string,num,out_string);

}

/********************************************************************
**
**
**
********************************************************************* */

int mouse_scroll_list(xc,yc,xs,ys,string,num,out_string)

int xc,yc,xs,ys,num;
char string[NAME_SIZE][S_SIZE],*out_string;

{
	int i,j,k;
	int x1=xc,x2=xc+xs-1,y1=yc,y2=yc+ys-1;
	int row,col,rowo=-1,colo,left,right;
	int n=0,n1,n2,nlines=ys-2,no=-1;
	char instring[NAME_SIZE];
	char ans=27,ansc=27;
	int mousemove=MouseMove,topbot;

	MouseMove=8;
	if(num<ys-2)
	{
		ys=num+2;
		y2=yc+ys-1;
		nlines=ys-2;
	}
	n1=n-nlines/2;
	if(n1<0)n1=0;
	n2=n1+nlines-1;
	if(n2>num-1)
	{
		n2=num-1;
		n1=n2-(nlines-1);
	}
	ClearBox(x1+1,x2-1,y1+1,y2+2,3);
	DoubleBox(xc,xc+xs-1,yc,yc+ys-1,3);
	WriteStringAtxy(x1,y2+2,xs,15,"'Esc'=Quit  'Enter'=Choose file");
	mouse_horizontal_range(x1+1,x2-1);
	mouse_vertical_range(y1,y2);
	row=(y1+y2)/2;
	col=(x1+x2)/2;
	mouse_information(&right,&left,&row,&col);
	rowo=row;
	colo=col;

	for(i=0;i<nlines;i++)
	{
		WriteStringAtxy(xc+1,yc+i+1,xs-2,3,GF_String[i+n1]);
	}
	i=0;
	do
	{
		mouse_information(&right,&left,&row,&col);
		topbot=(row==y1||row==y2)?1:0;
		if(rowo!=row||topbot==1)
		{
			rowo=row;
			colo=col;
			n=n1+row-(y1+1);
			if(n<0)
				n=0;
			if(n>num-1)	
				n=num-1;
			if(n!=no)
			{
				if((no-n1)>=0||no<num)
					WriteStringAtxy(xc+1,yc+1+(no-n1),xs-2,3,GF_String[no]);
				if(n>n2)
				{
					n2=n;
					n1=n2-(nlines-1);
					ScrollUp(1,x1+1,x2-1,y1+1,y2-1,3);
				}
				if(n<n1)
				{
					n1=n;
					n2=n1+nlines-1;
					ScrollDown(1,x1+1,x2-1,y1+1,y2-1,3);
				}
				if((n-n1)>=0||n<num)
					WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,112,GF_String[n]);
			}
			no=n;
		}
	}while(left==0&&right==0);
	ClearBox(xc,xc+xs-1,yc-1,yc+ys+1,3);
	MouseMove=mousemove;
	if(right==0)		/* 'Del or 'Ins' or 'Enter' */
	{
		strcpy(out_string,GF_String[n]);
		return(n);
	}
	else				/* 'Esc' */
	{
		out_string[0]='\0';
		return(-1);
	}
}


/********************************************************************
**
**
**
********************************************************************* */

int keyboard_scroll_list(xc,yc,xs,ys,string,num,out_string)

int xc,yc,xs,ys,num;
char string[NAME_SIZE][S_SIZE],*out_string;

{
	int i,j,k;
	int x1=xc,x2=xc+xs-1,y1=yc,y2=yc+ys-1;
	int n=0,n1,n2,nlines=ys-2,no;
	char instring[NAME_SIZE];
	char ans,ansc;

	if(num<ys-2)
	{
		ys=num+2;
		y2=yc+ys-1;
		nlines=ys-2;
	}
	n1=n-nlines/2;
	if(n1<0)n1=0;
	n2=n1+nlines-1;
	if(n2>num-1)
	{
		n2=num-1;
		n1=n2-(nlines-1);
	}
	ClearBox(x1+1,x2-1,y1+1,y2+2,3);
	DoubleBox(xc,xc+xs-1,yc,yc+ys-1,3);
	WriteStringAtxy(x1,y2+2,xs,15,"'Esc'=Quit  'Enter'=Choose file");

	for(i=0;i<nlines;i++)
	{
		WriteStringAtxy(xc+1,yc+i+1,xs-2,3,GF_String[i+n1]);
	}
	WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,112,GF_String[n]);

	i=0;
	do
	{
		ans=getch();
		if((ans>='a'&&ans<='z')||(ans>='A'&&ans<='Z')||
			(ans>='0'&&ans<='9')||ans=='_'||ans=='-')
		{
			n=0;
			i=1;
			instring[0]=ans;
			instring[1]='\0';
			ClearBox(x1,x2,y2+1,y2+1,3);
			WriteStringAtxy(x1,y2+1,xs,15,instring);
			do
			{
				if(i>0)
				{
					for(j=n;j<num;j++)
					{
						if(strnicmp(instring,GF_String[j],i)>=0)
						{
							n=j;
							if(strnicmp(instring,GF_String[j],i)==0)
								break;
						}
						else
							break;
					}
					n1=n-nlines/2;
					if(n1<0)n1=0;
					n2=n1+nlines-1;
					if(n2>num-1)
					{
						n2=num-1;
						n1=n2-(nlines-1);
					}
					ClearBox(x1+1,x2-1,y1+1,y2-1,3);
					for(j=0;j<nlines;j++)
						WriteStringAtxy(xc+1,yc+j+1,xs-2,3,GF_String[j+n1]);
					WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,112,GF_String[n]);
				}
				ansc=getch();
				if(ansc==0)
				{
					ansc=getch();
					if(ansc!=83&&ans!=82)
						ansc=13;
				}
				if(ansc>31&&ansc<127)
				{
					instring[i]=ansc;
					i+=1;
					instring[i]='\0';
					ClearBox(x1,x2,y2+1,y2+1,3);
					WriteStringAtxy(x1,y2+1,xs,15,instring);
				}
				if(ansc==8)
				{
					n=0;
					if(i>0)
					{
						i-=1;
						instring[i]='\0';
						ClearBox(x1,x2,y2+1,y2+1,3);
						WriteStringAtxy(x1,y2+1,xs,15,instring);
					}
				}
			}while(ansc!=13&&ansc!=27&&ansc!=83&&ans!=82);
			if(ansc==27||ansc==83||ansc==82)
				ans=ansc;
			ClearBox(x1,x2,y2+1,y2+1,3);
		}
		if(ans==0)
		{
			ans=getch();
			WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,3,GF_String[n]);
			if(ans==80&&n<num-1)		/* 2 */
				n+=1; 
			if(ans==72&&n>0)			/* 8 */
				n-=1;
			if(n>n2)
			{
				n2=n;
				n1=n2-(nlines-1);
				ScrollUp(1,x1+1,x2-1,y1+1,y2-1,3);
			}
			if(n<n1)
			{
				n1=n;
				n2=n1+nlines-1;
				ScrollDown(1,x1+1,x2-1,y1+1,y2-1,3);
			}
			if(ans==73)
			{
				if(n1>0&&n==n1)
				{
					n1-=nlines;
					if(n1<0)n1=0;
					n2=n1+nlines-1;
					n=n1;
					ClearBox(x1+1,x2-1,y1+1,y2-1,2);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,3,GF_String[i+n1]);
				}
				else if(n>n1)
					n=n1;
			}
			if(ans==71)
			{
				if(n1>0)
				{
					n1=0;
					n2=n1+nlines-1;
					n=0;
					ClearBox(x1+1,x2-1,y1+1,y2-1,2);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,3,GF_String[i+n1]);
				}
				else if(n>0)
					n=0;
			}
			if(ans==81)
			{
				if(n2<num-1&&n==n2)
				{
					n2+=nlines;
					if(n2>num-1)n2=num-1;
					n1=n2-(nlines-1);
					n=n2;
					ClearBox(x1+1,x2-1,y1+1,y2-1,2);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,3,GF_String[i+n1]);
				}
				else if(n<n2)
					n=n2;
			}
			if(ans==79)
			{
				if(n2<num-1)
				{
					n2=num-1;
					n1=n2-(nlines-1);
					n=n2;
					ClearBox(x1+1,x2-1,y1+1,y2-1,2);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,3,GF_String[i+n1]);
				}
				else if(n<n2)
					n=num-1;
			}
			WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,112,GF_String[n]);
		}
	}while(ans!=83&&ans!=27&&ans!=82&&ans!=13);
	ClearBox(xc,xc+xs-1,yc-1,yc+ys+1,3);

	if(ans==83||ans==82||ans==13)		/* 'Del or 'Ins' or 'Enter' */
	{
		strcpy(out_string,GF_String[n]);
		return(n);
	}
	else				/* 'Esc' */
	{
		out_string[0]='\0';
		return(-1);
	}
}

/********************************************************************
**
**
**
********************************************************************* */

int scroll_list_color(xc,yc,xs,ys,string,num,out_string,
		menu,cursor,box,highlight,base)

int xc,yc,xs,ys,num;
char string[MAX_NUM][S_SIZE],*out_string;
int menu,cursor,box,highlight,base;

{
	int i,j,k;
	int x1=xc,x2=xc+xs-1,y1=yc,y2=yc+ys-1;
	int n=0,n1,n2,nlines=ys-2,no;
	char instring[NAME_SIZE];
	char ans,ansc;

	if(num<ys-2)
	{
		ys=num+2;
		y2=yc+ys-1;
		nlines=ys-2;
	}
	n1=n-nlines/2;
	if(n1<0)n1=0;
	n2=n1+nlines-1;
	if(n2>num-1)
	{
		n2=num-1;
		n1=n2-(nlines-1);
	}
	ClearBox(x1+1,x2-1,y1+1,y2+2,menu);
	DoubleBox(xc,xc+xs-1,yc,yc+ys-1,box);
	WriteStringAtxy(x1,y2+2,xs,highlight,"'Esc'=Quit  'Enter'=Choose file");

	for(i=0;i<nlines;i++)
	{
		WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,GF_String[i+n1]);
	}
	WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,cursor,GF_String[n]);

	i=0;
	do
	{
		ans=getch();
		if((ans>='a'&&ans<='z')||(ans>='A'&&ans<='Z'))
		{
			n=0;
			i=1;
			instring[0]=ans;
			instring[1]='\0';
			ClearBox(x1,x2,y2+1,y2+1,menu);
			WriteStringAtxy(x1,y2+1,xs,highlight,instring);
			do
			{
				if(i>0)
				{
					for(j=n;j<num;j++)
					{
						if(strnicmp(instring,GF_String[j],i)>=0)
						{
							n=j;
							if(strnicmp(instring,GF_String[j],i)==0)
								break;
						}
						else
							break;
					}
					n1=n-nlines/2;
					if(n1<0)n1=0;
					n2=n1+nlines-1;
					if(n2>num-1)
					{
						n2=num-1;
						n1=n2-(nlines-1);
					}
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(j=0;j<nlines;j++)
						WriteStringAtxy(xc+1,yc+j+1,xs-2,menu,GF_String[j+n1]);
					WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,cursor,GF_String[n]);
				}
				ansc=getch();
				if(ansc==0)
				{
					ansc=getch();
					if(ansc!=83&&ans!=82)
						ansc=13;
				}
				if(ansc>31&&ansc<127)
				{
					instring[i]=ansc;
					i+=1;
					instring[i]='\0';
					ClearBox(x1,x2,y2+1,y2+1,menu);
					WriteStringAtxy(x1,y2+1,xs,highlight,instring);
				}
				if(ansc==8)
				{
					n=0;
					if(i>0)
					{
						i-=1;
						instring[i]='\0';
						ClearBox(x1,x2,y2+1,y2+1,menu);
						WriteStringAtxy(x1,y2+1,xs,highlight,instring);
					}
				}
			}while(ansc!=13&&ansc!=27&&ansc!=83&&ans!=82);
			if(ansc==27||ansc==83||ansc==82)
				ans=ansc;
			ClearBox(x1,x2,y2+1,y2+1,menu);
		}
		if(ans==0)
		{
			ans=getch();
			WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,menu,GF_String[n]);
			if(ans==80&&n<num-1)		/* 2 */
				n+=1; 
			if(ans==72&&n>0)			/* 8 */
				n-=1;
			if(n>n2)
			{
				n2=n;
				n1=n2-(nlines-1);
				ScrollUp(1,x1+1,x2-1,y1+1,y2-1,menu);
			}
			if(n<n1)
			{
				n1=n;
				n2=n1+nlines-1;
				ScrollDown(1,x1+1,x2-1,y1+1,y2-1,menu);
			}
			if(ans==73)
			{
				if(n1>0&&n==n1)
				{
					n1-=nlines;
					if(n1<0)n1=0;
					n2=n1+nlines-1;
					n=n1;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,GF_String[i+n1]);
				}
				else if(n>n1)
					n=n1;
			}
			if(ans==71)
			{
				if(n1>0)
				{
					n1=0;
					n2=n1+nlines-1;
					n=0;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,GF_String[i+n1]);
				}
				else if(n>0)
					n=0;
			}
			if(ans==81)
			{
				if(n2<num-1&&n==n2)
				{
					n2+=nlines;
					if(n2>num-1)n2=num-1;
					n1=n2-(nlines-1);
					n=n2;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,GF_String[i+n1]);
				}
				else if(n<n2)
					n=n2;
			}
			if(ans==79)
			{
				if(n2<num-1)
				{
					n2=num-1;
					n1=n2-(nlines-1);
					n=n2;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,GF_String[i+n1]);
				}
				else if(n<n2)
					n=num-1;
			}
			WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,cursor,GF_String[n]);
		}
	}while(ans!=83&&ans!=27&&ans!=82&&ans!=13);
	ClearBox(xc,xc+xs-1,yc-1,yc+ys+1,base);

	if(ans==83||ans==82||ans==13)		/* 'Del or 'Ins' or 'Enter' */
	{
		strcpy(out_string,GF_String[n]);
		return(n);
	}
	else				/* 'Esc' */
	{
		out_string[0]='\0';
		return(-1);
	}
}

/********************************************************************
**
**
**
********************************************************************* */

int check_equip(eq)

struct equipment *eq;

{
	int far *farptr;
	unsigned int val;

	farptr=(int far *)EQLIST;
	val=*farptr;
	eq->printers=val>>14;
	eq->sprinter=val&0x2000;
	eq->game    =val&0x1000;
	eq->sports  =(val>>9)&7;
	eq->dma     =val&0x0100;
	eq->drives  =((val>>6)&3)+1;
	eq->video   =(val>>4)&3;
	eq->disk    =val&1;
	farptr=(int far *)MEMSIZ;
	eq->memory  =*farptr;

	return(eq->video);
}


/********************************************************************
**
**
**
********************************************************************* */

int load_File(instring)

char *instring;

{
	int i,i1;
	int num_files;
	int mo,da,yr,hr,min;
	char string[100],type[100];

	num_files=load_names(instring);
	if(num_files>=MAX_NUM)
		return(-3);
	if(num_files==0)
		return(-2);
	sort_name(num_files);

	for(i=0;i<num_files;i++)
	{
		i1=GF_Order[i];
		file_name(GF_File[i1].name,string,type);
		date_convert(GF_File[i1].date,&mo,&da,&yr);
		time_convert(GF_File[i1].time,&hr,&min);
		sprintf(GF_String[i],"%s %s%9ld %2d/%02d/%2d %02d%02d  "
			,string,type,GF_File[i1].size,mo,da,yr,hr,min);
	}
	return(num_files);
}





/********************************************************************
**
**
**
********************************************************************* */

void DoubleBox(x1,x2,y1,y2,attrib)

int x1,x2,y1,y2,attrib;

{
	int x,y;
	unsigned char far *VideoBufferLocation;

	VideoBufferLocation=Video_Buffer[Monitor];

	for(x=x1+1;x<x2;x++)
	{
		*(VideoBufferLocation+y1*160+x*2)=205;
		*(VideoBufferLocation+y1*160+x*2+1)=attrib;
	}
	for(x=x1+1;x<x2;x++)
	{
		*(VideoBufferLocation+y2*160+x*2)=205;
		*(VideoBufferLocation+y2*160+x*2+1)=attrib;
	}
	for(y=y1+1;y<y2;y++)
	{
		*(VideoBufferLocation+y*160+x1*2)=186;
		*(VideoBufferLocation+y*160+x1*2+1)=attrib;
	}
	for(y=y1+1;y<y2;y++)
	{
		*(VideoBufferLocation+y*160+x2*2)=186;
		*(VideoBufferLocation+y*160+x2*2+1)=attrib;
	}

	*(VideoBufferLocation+y1*160+x1*2)=201;
	*(VideoBufferLocation+y1*160+x1*2+1)=attrib;
	*(VideoBufferLocation+y2*160+x1*2)=200;
	*(VideoBufferLocation+y2*160+x1*2+1)=attrib;
	*(VideoBufferLocation+y2*160+x2*2)=188;
	*(VideoBufferLocation+y2*160+x2*2+1)=attrib;
	*(VideoBufferLocation+y1*160+x2*2)=187;
	*(VideoBufferLocation+y1*160+x2*2+1)=attrib;
}



/********************************************************************
**
**
**
********************************************************************* */

void ScrollUp(num_lines,x1,x2,y1,y2,attrib)

int num_lines,x1,y1,x2,y2,attrib;

{
	regs.h.ah=6;
	regs.h.al=num_lines;
	regs.h.bh=attrib;
	regs.h.cl=x1;
	regs.h.ch=y1;
	regs.h.dl=x2;
	regs.h.dh=y2;
	int86(0x10,&regs,&regs);
}


/********************************************************************
**
**
**
********************************************************************* */

void ScrollDown(num_lines,x1,x2,y1,y2,attrib)

int num_lines,x1,y1,x2,y2,attrib;

{
	regs.h.ah=7;
	regs.h.al=num_lines;
	regs.h.bh=attrib;
	regs.h.cl=x1;
	regs.h.ch=y1;
	regs.h.dl=x2;
	regs.h.dh=y2;
	int86(0x10,&regs,&regs);
}



/********************************************************************
**
**
**
********************************************************************* */

void SetCursor(x,y)
int x;
int y;

{
	regs.h.ah=2;
	regs.h.bh=0;
	regs.h.dl=x;
	regs.h.dh=y;
	int86(0x10,&regs,&regs);
	return;
}


/********************************************************************
**
**
**
********************************************************************* */

void ClearBox(x1,x2,y1,y2,attrib)
int(attrib);

{
	regs.h.ah=6;
	regs.h.al=0;
	regs.h.bh=attrib;
	regs.h.cl=x1;
	regs.h.ch=y1;
	regs.h.dl=x2;
	regs.h.dh=y2;
	int86(0x10,&regs,&regs);
	return;
}



/********************************************************************
**
**
**
********************************************************************* */

void ClearScreen(attrib)
int(attrib);

{
	regs.h.ah=6;
	regs.h.al=0;
	regs.h.bh=attrib;
	regs.h.ch=0;
	regs.h.cl=0;
	regs.h.dl=79;
	regs.h.dh=24;
	int86(0x10,&regs,&regs);
	return;
}



/**************************************************************************
**                                                                       **
**  WriteStringAtxy writes the string pointed to at the x,y coordinates  **
**  called with, if count=0 the entire string is plotted, otherwise	    **
**  count number of bytes are plotted											    **
**                                                                       **
**************************************************************************/

void WriteStringAtxy(x,y,count,attrib,pointer_to_string)

int x;
int y;
int count;
unsigned char attrib;
unsigned char *pointer_to_string;

{
	int i,j,k;
	int z;
	unsigned char far *VideoBufferLocation;

	VideoBufferLocation=Video_Buffer[Monitor];
	VideoBufferLocation+=(y*160)+(x*2);

	if(count == 0)
	{
		while(*pointer_to_string != '\0')
		{
			if(*pointer_to_string>=0x20)
			{
				*VideoBufferLocation++=*pointer_to_string++;
				*VideoBufferLocation++=attrib;
			}
			else if(*pointer_to_string==0x9)
			{
				for(i=0;i<TabSize;i++)
				{
					*VideoBufferLocation++=0x20;
					*VideoBufferLocation++=attrib;
				}
				*pointer_to_string++;
			}
			else
				*pointer_to_string++;
		}
		return;
	}
	else
	{
		while(count-->0 && (*pointer_to_string != '\0'))
		{
			if(*pointer_to_string>=0x20)
			{
				*VideoBufferLocation++=*pointer_to_string++;
				*VideoBufferLocation++=attrib;
			}
			else if(*pointer_to_string==0x9)
			{
				for(i=0;i<TabSize;i++)
				{
					*VideoBufferLocation++=0x20;
					*VideoBufferLocation++=attrib;
				}
				*pointer_to_string++;
				count-=TabSize-1;
			}
			else
				*pointer_to_string++;
		}
	}
}



/********************************************************************
**
**
**
********************************************************************* */

int get_name(num,fileout)

int num;
char *fileout;

{
	int i,i1,p,j,k,m;
	int mo,da,yr,hr,min;
	int npage,lpage,nlines=22,pt,plot,ans;
	char string[100],type[50];

	npage=num/(nlines*4);lpage=num%(nlines*4);
	if(lpage>0)npage+=1;

	p=0;
	for(;;)
	{
		for(j=0;j<nlines;j++)
		{
			plot=0;
			i=p*nlines*4+j;
			for(k=0;k<4;k++)
			{
				m=i+nlines*k;
				if(m<num)
				{
					plot+=1;
					i1=GF_Order[m];
					file_name(GF_File[i1].name,string,type);
					printf("%4d %s %s  ",m+1,string,type);
				}
			}
			if(plot>0)
				printf("\n");
		}
		if(npage>1)
			printf(
"There are %d pages -- enter number or PgUp, PgDn, '+' or '-' to change pages.",
			npage);
		else
printf(
"There is only 1 page -- enter number.");
		printf(
"\nUse 'x' or 'Esc' to exit without choosing a file name.\n");
		ans=get_num();
		if(ans==-1)
			return(-1);
		if(ans==-73||ans==-45)
		{
			p-=1;
			if(p<0)p=0;
		}
		if(ans==-81||ans==-43)
		{
			p+=1;
			if(p>npage-1)p=npage-1;
		}
		ans-=1;
		if(ans>=0&&ans<num)
		{
			strcpy(fileout,GF_File[GF_Order[ans]].name);
			return(GF_Order[ans]);
		}
	}
}

/********************************************************************
**
**
**
********************************************************************* */

int get_num()

{
	int i,j,k;
	char string[100],ans;
	int val;

	i=0;
	do
	{
		ans=getch();
		if(ans==0)
		{
			ans=getch();
			if(ans==73)
				return(-73);
			if(ans==81)
				return(-81);
		}
		else if(ans==45)
			return(-45);
		else if(ans==43)
			return(-43);
		else if(ans>='0'&&ans<='9')
		{
			printf("%c",ans);
			string[i]=ans;
			i+=1;
		}
		else if(ans==8)
		{
			printf("%c",ans);
			if(i>0)
				i-=1;
		}
		else if(ans==27||ans=='x')
		{
			printf("\n");
			return(-1);
		}
	}while(ans!=13);
	if(i<=0)
	{
		printf("\n");
		return(-43);
	}
	sscanf(string,"%d",&val);
	printf("\n");
	return(val);
}



/********************************************************************
**
**
**
********************************************************************* */

void sort_name(num)

int num;

{
	int i,i1,i2,j,k;
	int hit,val;
	
	for(i=0;i<num;i++)
		GF_Order[i]=i;

	do
	{
		hit=0;
		for(i=1;i<num;i++)
		{
			i1=GF_Order[i-1];
			i2=GF_Order[i];
			if(strcmp(GF_File[i1].name,GF_File[i2].name)>0)
			{
				val=GF_Order[i];
				GF_Order[i]=GF_Order[i-1];
				GF_Order[i-1]=val;
				hit+=1;
			}
		}
	}while(hit>0);
}


/********************************************************************
**
**
**
********************************************************************* */

void sort_date(num)

int num;

{
	int i,i1,i2,j,k;
	int hit,val;
	
	for(i=0;i<num;i++)
		GF_Order[i]=i;

	do
	{
		hit=0;
		for(i=1;i<num;i++)
		{
			i1=GF_Order[i-1];
			i2=GF_Order[i];
			if(GF_File[i1].date<GF_File[i2].date)
			{
				val=GF_Order[i];
				GF_Order[i]=GF_Order[i-1];
				GF_Order[i-1]=val;
				hit+=1;
			}
		}
	}while(hit>0);
}
/********************************************************************
**
**
**
********************************************************************* */

void sort_time(num)

int num;

{
	int i,i1,i2,j,k;
	int hit,val;
	
	for(i=0;i<num;i++)
		GF_Order[i]=i;

	do
	{
		hit=0;
		for(i=1;i<num;i++)
		{
			i1=GF_Order[i-1];
			i2=GF_Order[i];
			if(GF_File[i1].time<GF_File[i2].time)
			{
				val=GF_Order[i];
				GF_Order[i]=GF_Order[i-1];
				GF_Order[i-1]=val;
				hit+=1;
			}
		}
	}while(hit>0);
}

/********************************************************************
**
**
**
********************************************************************* */

void sort_size(num)

int num;

{
	int i,i1,i2,j,k;
	int hit,val;
	
	for(i=0;i<num;i++)
		GF_Order[i]=i;

	do
	{
		hit=0;
		for(i=1;i<num;i++)
		{
			i1=GF_Order[i-1];
			i2=GF_Order[i];
			if(GF_File[i1].size<GF_File[i2].size)
			{
				val=GF_Order[i];
				GF_Order[i]=GF_Order[i-1];
				GF_Order[i-1]=val;
				hit+=1;
			}
		}
	}while(hit>0);
}





/********************************************************************
**
**
**
********************************************************************* */

void print_files(num)

int num;

{
	int i,i1,i2,p,j,k;
	int mo,da,yr,hr,min;
	int npage,lpage,nlines=23,pt;
	char string[100],type[50];

	npage=num/(nlines*2);lpage=num%(nlines*2);

	for(p=0;p<npage;p++)
	{
		for(j=0;j<nlines;j++)
		{
			i=p*nlines*2+j;
			i1=GF_Order[i];
			i2=GF_Order[i+nlines];
			file_name(GF_File[i1].name,string,type);
			printf("%3d %s %s",i+1,string,type);
			date_convert(GF_File[i1].date,&mo,&da,&yr);
			printf("%7ld %2d/%02d/%2d ",GF_File[i1].size,mo,da,yr);
			time_convert(GF_File[i1].time,&hr,&min);
			printf("%02d%02d  ",hr,min);

			file_name(GF_File[i2].name,string,type);
			printf("%3d %s %s",i+nlines+1,string,type);
			date_convert(GF_File[i2].date,&mo,&da,&yr);
			printf("%7ld %2d/%02d/%2d ",GF_File[i2].size,mo,da,yr);
			time_convert(GF_File[i2].time,&hr,&min);
			printf("%02d%02d\n",hr,min);
		}
		getch();
		printf("\n");
	}
	if(lpage>0)
		for(j=0;j<nlines;j++)
		{
			i=p*nlines*2+j;
			if(i<num)
			{
				i1=GF_Order[i];
				file_name(GF_File[i1].name,string,type);
				printf("%3d %s %s",i+1,string,type);
				date_convert(GF_File[i1].date,&mo,&da,&yr);
				printf("%7ld %2d/%02d/%2d ",GF_File[i1].size,mo,da,yr);
				time_convert(GF_File[i1].time,&hr,&min);
				printf("%02d%02d  ",hr,min);
				if(i+nlines<num)
				{
					i2=GF_Order[i+nlines];
					file_name(GF_File[i2].name,string,type);
					printf("%3d %s %s",i+nlines+1,string,type);
					date_convert(GF_File[i2].date,&mo,&da,&yr);
					printf("%7ld %2d/%02d/%2d ",GF_File[i2].size,mo,da,yr);
					time_convert(GF_File[i2].time,&hr,&min);
					printf("%02d%02d\n",hr,min);
				}
				else
					printf("\n");
			}
		}
		printf("There are %d files.  Total size = %ld  ",num,Tsize);
		if(NumEmpty>0)
			printf("%d files are empty.",NumEmpty);
}

/********************************************************************
**
**
**
********************************************************************* */

void file_name(string,name,type)

char *string,*name,*type;

{
	int k,pt;
	int len=strlen(string);

	strcpy(type,"   ");
	strcpy(name,"        ");
	pt=-1;
	for(k=0;k<len;k++)
	{
		if(string[k]=='.')
			pt=k;
		if(pt<0)
			name[k]=string[k];
		if(pt>0&&pt!=k)
			type[k-pt-1]=string[k];
	}
}


/********************************************************************
**
**
**
********************************************************************* */

int load_names(file_id)

char *file_id;

{
	int i;
	struct find_t c_file;
	int num=0,hr,min,mo,da,yr;
	int len=strlen(file_id),pt=-1;
	char string[100];

	strcpy(string,file_id);

	if(len==0)
		strcpy(string,"*.*");
	for(i=0;i<len;i++)
		if(string[i]=='.')
			pt=i;
	if(pt<0)
		strcat(string,".*");

	Tsize=0;
	NumEmpty=0;
	if(_dos_findfirst(string,_A_NORMAL,&c_file)==0)
	{
		if(c_file.size>0)
		{
			GF_File[num].size=c_file.size;
			GF_File[num].date=c_file.wr_date;
			GF_File[num].time=c_file.wr_time;
			strcpy(GF_File[num++].name,c_file.name);
			Tsize=c_file.size;
		}
		else
			NumEmpty+=1;
		while(_dos_findnext(&c_file)==0&&num<MAX_NUM)
		{
			if(c_file.size>0)
			{
				GF_File[num].size=c_file.size;
				GF_File[num].date=c_file.wr_date;
				GF_File[num].time=c_file.wr_time;
				strcpy(GF_File[num++].name,c_file.name);
				Tsize+=c_file.size;
			}
			else
				NumEmpty+=1;
		}
	}
	if(num>=MAX_NUM)
	{
		printf("\nWarning -- There are more than %d files\n\n",MAX_NUM);
		PAUSE;
	}
	return(num);
}

/********************************************************************
**
**
**
********************************************************************* */

void time_convert(number,hr,min)

unsigned number;
int *hr,*min;

{
	*hr=number/2048;
	*min=number%2048;
	*min/=32;
}

/********************************************************************
**
**
**
********************************************************************* */

void date_convert(days,mo,da,yr)

unsigned days;
int *mo,*da,*yr;

{
	int m;

	*yr=days/512+80;
	m=days%512;
	*mo=m/32;	
	*da=m%32;
}





                                                                                           