#include "fido.h"
#include "fidomem.h"
#include <ascii.h>
#include <xfbuf.h>
#include "proto.h"

/*

picklang()
	List the available languages, allow the caller to choose one.

loadlang(l)
	Load language(s) into Fido. The number passed is an index into
	the language system table, which specifies which subdirectory
	the language file and the .HLP and .BBS files are contained in.

	Language 0 is handled specially; 0 is the system-default language,
	and the one used for single-language Fidos. When referenced, we
	look in the current directory first for "FIDO.CLN"; if not
	found, then the above process is used.

	Returns 0 is the language could not be loaded.
*/

loadlang(l)
int l;
{
int n,f;
char *cp,buff[SS],fname[SS];

	if (! l) {					/* for system default, */
		makesname(fname,"");			/* system path */
		return(linklang(0,fname));		/* FIDO.CLN */
	}

/* Locate the correct language number in the table. */

	makesname(fname,"LANGUAGE.INI");
	f= open(fname,0);				/* get the language table */
	if (f == -1) {
error:		cprintf(SM+28,fname);			/* CM probably doesnt exist */
		lprintf(LM+31,fname);			/* "file does not exist" */
		return(0);
	}
	while (rline(f,buff,sizeof(buff))) {		/* locate the right language */
		cp= skip_delim(buff);
		n= atoi(cp);				/* look for the ID */
		if (n == l) break;			/* found it! */
	}
	close(f);
	if (n != l) return(0);				/* language not found */
	return(linklang(n,next_arg(cp)));		/* else load it */
}

/* Link in the specified language file. */

static linklang(num,pathname)
int num;
char *pathname;
{
int i,n,f;
char **pp,*cp,fname[SS],buff[SS];
struct _xfbuf xfbuf;

	cpyarg(buff,pathname);				/* make a path prefix */
	fixdir(buff);
	strip_path(fname,buff);
	cp= fname + strlen(fname);			/* (points to filename position) */
	if (num == 0) strcat(fname,"FIDO.CLN");		/* 0 name always FIDO.CLN */
	else {						/* else locate it */
		strcpy(cp,"*.CLN");			/* find first .CLN file */
		xfbuf.s_attrib= 0;
		if (! _find(fname,0,&xfbuf)) goto error;/* none! */
		cpyarg(cp,xfbuf.name);			/* correct filename */
	}
	f= open(fname,0);				/* open the file, */
	if (f == -1) {
error:		cprintf(SM+28,fname);			/* CM probably doesnt exist */
		lprintf(LM+31,fname);			/* "file does not exist" */
		return(0);				/* return an error */
	}

/* Load the language file and link it in. Check the CRC of the file. */

	read(f,mem,sizeof(struct _lang_hdr));		/* read the header, */
	if (((struct _lang_hdr *)mem)-> version != LANGVER) {/* check version */
		clprintf(0,"! WRONG VERSION FILE: %s\377",fname);
		return(0);
	}
	clrcrc();
	for (n= 0; n < sizeof(struct _lang_hdr); n++) 	/* CRC the header portion, */
		updcrc(mem[n]);

	n= read(f,mem,15000);				/* hell if I know */
	close(f);
	texttbl[3]= mem;				/* link it in */

	for (i= 0; i < n; i++) updcrc(mem[i]);		/* CRC the data, */
	if (chkcrc()) {
		clprintf(0,"! DAMAGED FILE: %s\377",fname); /* "bad language file" */
		return(0);
	}
	n -= 4;						/* skip -1 marker, CRC bytes */
	text= mem + n; textsize= memsize - n;		/* set text size */

/* Convert the table of offsets to a table of pointers. */

	for (pp= (char **) mem; (int)*pp != -1; ++pp) {
		*pp += (unsigned) mem;			/* add table base address */
	}
	if (num) {					/* if multi-language */
		strip_path(langpath,fname);		/* change paths */
		strcpy(fname,langpath);
		strcat(fname,"COMMANDS.SYS");		/* load the command names */
		f= open(fname,0);
		if (f != -1) {				/* if OK */
			read(f,&fido.cmd,sizeof(fido.cmd)); /* load them, */
			close(f);

		} else if (fbit(FBIT_LINGUAL)) goto error; /* (file doesnt exist) */

	} else {					/* default language */
		putsys();				/* preserve any new data, */
		getsys();				/* load default commands */
		*langpath= NUL;				/* default paths */
	}
	return(1);
}

/* Pick a language. */

void picklang() {
int l,n,f;
char *cp,buff[SS],fname[SS];
char map[CLR_LAN + 1];

	l= uval(CLR_LAN,CLR_LANS);			/* current language */
	for (n= 1; n < sizeof(map); n++) map[n]= 0;	/* map of ones that exist */
	map[0]= 1;					/* 0th always exists */

	mprintf(CM+8);					/* "wait..." */
	makesname(fname,"");
	linklang(0,fname);				/* system language */
	if (! isargs())
		mprintf(0," 1)    %s\377",string(CM+0)); /* always list it */

	makesname(fname,"LANGUAGE.INI");
	f= open(fname,0);				/* get language table */
	if (f == -1) return;				/* no other languages */

	while (rline(f,buff,sizeof(buff))) {		/* locate the right language */
		cp= skip_delim(buff);
		n= atoi(cp);				/* language ID */
		if (! n) continue;			/* look for an ID */
		if (n >= sizeof(map)) continue;		/* too large! */
		map[n]= 1;
		if (isargs()) continue;			/* dont display if args */

		if (! linklang(n,next_arg(cp))) continue; /* link it in, */			
		mprintf(0,"%2d)    %s %s\377",n + 1,string(CM+0),string(CM+172));	/* list it */
	}
	close(f);					/* close LANGUAGE.INI */
	loadlang(n= l);					/* reload users language */
	cp= skip_delim(getarg(CM+99,l));		/* "choose one" */
	if (isdigit(*cp)) {
		n= atoi(cp);				/* input 1 - N */
		if (n) --n;				/* make 0 - N */
	}
	if (n >= sizeof(map)) n= l;			/* check if for legality */
	if (! map[n]) n= l;
	if (n != l) loadlang(n);			/* load if different */

	setuval(n,CLR_LAN,CLR_LANS);			/* save this */
}
