/*******************************************************************************************

            Disc File Selector Menu

            (c) MHG 1992,1997

*******************************************************************************************/
#include	<stdio.h>
#include	<dos.h>
#include	"keys.h"
#include	<string.h>
#include	"menu.h"
/*******************************************************************************************


      DEFINES


*******************************************************************************************/
#pragma aux masm "*" parm caller [];

#pragma	aux (masm) SwapModeX_ \
parm [eax]

#define  XMAX           40          // width of screen in characters
#define	GAME_MENU		2
#define  MAX_FILES      1000        // maximum disc files
/*******************************************************************************************


      EXTERNALS


*******************************************************************************************/
extern "C"  int    LookKey(void);
extern "C"  char   get_ascii_key();
extern "C"  int    find_all_games(char *,char *,int);
extern "C"  void   CursorOff(void);
extern "C"  int    num_games;
extern "C"  char  keyx[256];
extern      char   *mode7fontRaw[];
/*******************************************************************************************


		PROTOTYPES


*******************************************************************************************/
void		sort_list(char *buff,int size,int number);
void		print(char a);
int		find_all_files(char *path,char *names,int max);
void		print_entry(int i);
void		printx(char *);
void		clear_screen(int a);
int		find_all_files(char *path,char *names,int max);
void     cprintx(char *t);
char     ifkey(int a);
char     inkey(int a);
/*******************************************************************************************


			DATA


*******************************************************************************************/
char		dummy[4*320*256*2];
int		xstart=0;
int		ystart=2;
int		ynumber=21;
int		xgap=14;
int		xtab,ytab,col=0xff;
int		cursor_pos=0;
char     namebuff[16*MAX_FILES];
char		*nameptr;
int		cursor_base=0;
int		maxrow;
int      menutype=0;
int      num_discs=0;
int      num=0;
/*******************************************************************************************

      'menu'

      display disc select menu

      in:   char * filespec
      out:  filename selected


*******************************************************************************************/
char  *menu(char *p)
{
   int   i;
	int	exitflag=0;
	char	a;
	int	xval,yval;
	char	*ss=&dummy[0];
   char  search_name[64];
   int   search_index=0;
   char  title[40];
   int   refresh;

 	a=ifkey(RETURN);   		//clear keys
   a=ifkey(1);
	nameptr=&namebuff[0];

  	clear_screen(0);
  	exitflag=0;
  	xtab=0;
  	ytab=0;
  	col=0x1f;

   sprintf(title,"Beebem (c)D.A.Gilbert 1994 Dos V1.2  MHG");

	printx(title);
	xtab=0;
	ytab=24;
	printx("     RETURN load, F12 menu, ESC quit    ");
  	SwapModeX_(ss);
//
//    Look for files
//
   num_discs=find_all_files(p,nameptr,MAX_FILES);
   if (num_discs) sort_list(nameptr,16,num_discs);
   xgap=50;
   ynumber=1;
   maxrow=20;

   if (menutype==GAME_MENU)
		num=num_games;
  	else
  		num=num_discs;


   if (num_discs)
	{
 		while(exitflag==0)
 		{
			if (refresh==2)
			{
				clear_screen(1);
				xtab=0;
	  	 		ytab=24;
				col=0x1f;
	   		printx("     RETURN load, F12 menu, ESC quit    ");
			}

			col=15;

			for(i=0;i<num;i++)
				print_entry(i);

			col=12;
         print_entry(cursor_pos);
			col=15;
	  		refresh=0;


			SwapModeX_(ss);

         search_index=0;

	  		while(refresh==0)
			{
				if (a=get_ascii_key())
				{
					search_name[search_index]=a;
				   search_name[search_index+1]=0;
					search_index++;
					for(i=0;i<num;i++)
					{
                  if (menutype==GAME_MENU)
                  {
                     if (strncmp(search_name,game[i].name.title,search_index)==0)
                     {
                        cursor_pos=i;
                        refresh=2;
                        break;   //break out from for loop
                     }
                  }
                  else
                  {
                     if (strncmp(search_name,nameptr+16*i,search_index)==0)
                     {
                        cursor_pos=i;
                        refresh=2;
                        break;   //break out from for loop
                     }
                  }
					}

               if (refresh!=2) search_index=0;


                if (cursor_pos<cursor_base)
                   cursor_base=cursor_pos;
                if (cursor_pos>cursor_base+maxrow)
                   cursor_base=cursor_pos;
				}

		 	  	if (ifkey(UP))
		  		{
		  		  	cursor_pos--;
		  			refresh=1;
               search_index=0;
		  		}

            if (ifkey(HOME))
		  		{
               cursor_pos=0;
               cursor_base=0;
               refresh=2;
               search_index=0;
		  		}

            if (ifkey(ENDKY))
		  		{
               cursor_pos=num-1;
               cursor_base=cursor_pos-maxrow;
               refresh=2;
               search_index=0;
		  		}

            if (ifkey(PGUP))
		  		{
               if (cursor_pos!=cursor_base)
                  cursor_pos=cursor_base;
               else
               {
                  cursor_base-=maxrow;
                  cursor_pos=cursor_base;
               }
               if (cursor_base<0) cursor_base=0;
               refresh=2;
               search_index=0;
		  		}

            if (ifkey(PGDN))
		  		{
               if (cursor_pos!=cursor_base+maxrow)
                  cursor_pos=cursor_base+maxrow;
               else
               {
                  cursor_base+=maxrow;
                  cursor_pos=cursor_base+maxrow;
                  if (cursor_base>num-maxrow) cursor_base=num-maxrow;
               }
               refresh=2;
               search_index=0;
		  		}

		  		if (ifkey(DOWN))
		  		{
		  		 	cursor_pos++;
		  			refresh=1;
               search_index=0;
		  		}


		 		if (cursor_pos<0)
		  			cursor_pos=0;

		  	 	if (cursor_pos>=num)
		  			cursor_pos=num-1;


		  	 	yval=cursor_pos;

		 		if (yval-cursor_base>maxrow)
		 		{
		  			cursor_base++;
		  			refresh=2;
		 		}

		 		if (yval < cursor_base)
		  		{
		  			cursor_base--;
		  			refresh=2;
		  		}


		 		if (ifkey(RETURN))
		  		{
		  			refresh=1;
	 	  		  	exitflag=1;
		  		}

			   if (ifkey(TAB))
		  		{
		  			refresh=2;
               menutype^=GAME_MENU;
					if (menutype==GAME_MENU)
               {
                  if (num_games)
                     num=num_games;
                  else
                     menutype^=GAME_MENU;
               }
					else
						num=num_discs;
               cursor_base=0;
               cursor_pos=0;
		  		}

		 		if (inkey(1))
		 		{
		  			return(0);
		 		}
	  		}    //refresh loop
		}	 	//exit flag loop

	clear_screen(0);

   if (menutype==GAME_MENU)
   	return(game[cursor_pos].name.disc_name);
	else
		return(16*cursor_pos+nameptr);
	}
	else
	{
		while(1)
		{
	 		col=15;
         xtab=20;
	 		ytab=12;
         cprintx("No files present");
         xtab=20;
         ytab=14;
         cprintx("press <RETURN> to continue");
		 	SwapModeX_(ss);

	   	if (inkey(1))
			{
            return(0);
			}

	   	if (inkey(RETURN))
			{
            return(0);
			}
		}
	}
}
/*******************************************************************************************


      print string with leading capital


*******************************************************************************************/
void  xprintx(char *text)
{
	char	a;
	int	flag=0;

	while(a=*text++)
	{
		if (a>='A' && a<='Z')
		{
			if (flag==1)
			{
				a|=0x20;
			}
			else
				a&=~0x20;
		}

	  	flag|=1;
		print(a);
		if (a==32) flag=0;
	}
}
/*******************************************************************************************


      print menu entry


*******************************************************************************************/
void	print_entry(int i)
{
	char	*p;
	char	a;

   if (menutype==GAME_MENU)
   	p=game[i].name.title;
	else
	  	p=16*(i)+nameptr;
   i=i-cursor_base;
	if (i<0) return;
	ytab=(i)+ystart;
	if (ytab>22) return;
	xtab=20-strlen(p)/2;
	xprintx(p);
}
/*******************************************************************************************


		Find all disc files


*******************************************************************************************/
int   find_all_files(char *path,char *names,int max_files)
{
	struct find_t	find;
	int		attr=0;
	int		num=0;
	int		res;

	res=_dos_findfirst(path,attr,&find);

	if (res==0) 		//ok
	{
 		strcpy(names,&find.name[0]);
  		names+=16;
  		num++;
	}
   else
      return(0);

	while(1)
	{
 	  	res=_dos_findnext(&find);
		if (res!=0) break;
 	  	strcpy(names,&find.name[0]);
  		names+=16;
  		num++;
      if (num>=max_files) break;
	}

	return(num);
}
/*******************************************************************************************


		print a string

		IN:	char *text

*******************************************************************************************/
void	printx(char *t)
{
	char	a;

	while(a=*t++)
	{
		print(a);
	}
}
/*******************************************************************************************

      cprintx

      print a string centred

		IN:	char *text

*******************************************************************************************/
void  cprintx(char *t)
{
	char	a;
   int   len;

   len=strlen(t);
   xtab-=len/2;

	while(a=*t++)
	{
		print(a);
	}
}

/*******************************************************************************************


		Sort list of filenames into alphabetical order


*******************************************************************************************/
void	sort_list(char *buff,int size,int number)
{

	int	i,j,k;
	char	tmp[16];
	char	*p,*q;
	unsigned int	jsum,indx,isum;

  	for(j=0;j<number;j++)
	{
		q=(char *)&buff[size*j];
		indx=j;

		for(i=j+1;i<number;i++)
		{
			p=(char *)&buff[size*i];

			if (strcmp(p,q)<0)
			{
				indx=i;
				q=p;
			}
		}

		for(k=0;k<size;k++)
		{
			tmp[k]=buff[k+size*j];
			buff[k+size*j]=buff[k+size*indx];
		 	buff[k+size*indx]=tmp[k];
		}
	}
}
/*******************************************************************************************


		clear the screen

		IN:	number of lines at the bottom not to clear

*******************************************************************************************/
void	clear_screen(int y)
{
	char	*dest=&dummy[0]+(320*9*y);

 	memset(dest,0x0,320*(256-9*y));
}
/*******************************************************************************************


		Print a character at position (xtab,ytab)

		IN:		ascii

*******************************************************************************************/
void	print(char a)
{
	char	*dest=&dummy[0]+(320*9*ytab)+(8*xtab);
	char	*row;
	int	index;
	int	sub,block;
	int	i,x;

	if (xtab>=XMAX) return;
   if (ytab>=25) return;


	if (a<32) return;			//no symbol

	index=a-32;
	sub=index &15;
	block= index/16;

	for(i=0;i<9;i++)
	{
		row=mode7fontRaw[block*9+i];    //address of row
		row=row+8*sub;
		for(x=0;x<8;x++)
		{
			a=*row++;
			if (a==32)
				*dest++=(col>>4)&7;
			else
				*dest++=col&7;
		}
		dest+=320-8;
	}

	xtab++;

  	if (xtab>=XMAX)
	{
		xtab=0;
		ytab++;
	}
}
/*******************************************************************************************


      inkey

      check if a key is pressed


*******************************************************************************************/
char  inkey(int a)
{
   return(keyx[a]);
}
/*******************************************************************************************


      ifkey

      check if a key is pressed and zero it


*******************************************************************************************/
char	ifkey(int a)
{
   char  b=keyx[a];
   keyx[a]=0;
	return(b);
}


