/* http://www.brlspeak.net
 * brlspeak.c - brlspeak installer
 * (C) 2002 sebfrance <sebfrance@ifrance.com>.
 * This file may be redistributed as described in the GPL. */
#include "brlspeak.h"
#define _(String) gettext(String)
//#include <process.h>


int main (int argc, char **argv)
{
	start();
	promptlang();

	local();
	promptpart();
	promptbraille();
	promptbrailledev();
	promptbrailletable();
	promptpath();
	installtype();
	confirm();
	exit(0);
}

void start()
{
	getcwd(root,3);		/* where are we ? */
	sprintf(localespath,"%slocal/",root);
#ifdef DEBUG
	debugfd = fopen("debug.log","w+");
	debuglog("root",root);
	debuglog("localespath",localespath);
#endif
	printf ("Welcome to brlspeak installation\nplease input the language of your installation\n");
}


void promptlang ()
{
	char lang[9];
	DIR *dir;
	struct dirent *direntry;
	
	fflush (stdin);
	dir=opendir (localespath);
	if(dir==NULL)
	{
		printf ("No local/ directory found, assuming you want to use the English language\n");
		strcpy(lang,"en");
	}
else {
	printf("en");
	while ((direntry = readdir (dir))!=NULL)
	{
		if(!cmpn(direntry->d_name,"..",2)&&(*direntry->d_name!='.'))
			printf(" %s",direntry->d_name);
	}
	closedir (dir);

	printf ("\nLanguage [en] ");
	prompt (lang, 9);
	if (*lang=='\0')
		strcpy (lang,"en");
	if(cmp(lang,"ru")) {
		system("cyrillic.com");
	}
	setlocale (LC_ALL, lang);
	setenv("LANG",lang,1);
	bindtextdomain ("brlspeak", "local");
	textdomain ("brlspeak");
}			     
	sprintf (conf.lang,"%s_",tolow(lang));
	sprintf (conf.lang,"%s%s",conf.lang,toup(lang));
#ifdef DEBUG
	        debuglog("lang",conf.lang);
#endif
		
	strncpy(conf.keymap,conf.lang,2);
}

/*void open()
{
	FILE *messagesfd;

	sprintf(file,"%s%s.txt",localespath,conf.lang);
	messagesfd = fopen(file,"r");
	if (messagesfd==NULL) {
		if(errno==22) {
			printf ("Language %s is not available, please select one among the list\nor press enter for english default\n",conf.lang);
			promptlang();
			return;
		}
		else
		{
			error();
		}
	}
	stat(file, &buf);
	if (buf.st_size>7000) {
		printf ("file is too big\n");
		exit(-1);
	}
	messages = alloc(buf.st_size);
	fread (messages,buf.st_size, 1, messagesfd);
	fclose(messagesfd);
}*/


void local()
{
	char var[15];
	if(!cmp(conf.lang,"en"))
	{	
		sprintf(var,"xkeyb key\\%s > nul",conf.keymap);
		system(var);
#ifdef DEBUG
	debuglog("var",var);
#endif
	}
	printf(_("English installation\n"));
	printf(_("You can always stop it by pressing Ctrl + C and Enter\n"));
}


void promptpart()
{
	/*int pipe_fds[2];
	  int stdin_save, stdout_save;
	char *mem;
	  mem = alloc(150);
		
	stdin_save = dup(STDIN_FILENO);
	stdout_save = dup(STDOUT_FILENO);
	dup2(pipe_fds[1], STDOUT_FILENO);

	spawnl(P_WAIT, "bin/detect.exe", "detect.exe", NULL);
	read(pipe_fds[1],mem,10);
	close(pipe_fds[1]);
	close(pipe_fds[0]);
	dup2(stdout_save, STDOUT_FILENO);
	dup2(stdin_save, STDIN_FILENO);
	   printf("'%s'\n",mem); */
	system("detect.exe");												/* partitions detection */
	printf(_("Install on which device?\n"));
	prompt(conf.winpart, 16);
	if(strlen(conf.winpart)<9) {											/*   name's too short   */
		printf(_("Device name must be at least 9 characters long\n"));
		promptpart();
	}
	if(strlen(conf.winpart)>9)
	{
		printf(_("Device name must be at max 9 characters long\n"));
		promptpart();
	}
	if(!cmpn(conf.winpart,"/dev/",5)) 
	{
		printf(_("Device name must start with /dev/\n"));
		promptpart();
	}
	if((!cmpn(conf.winpart,"/dev/hd",7)&&!cmpn(conf.winpart,"/dev/sd",7))&&!cmpn(conf.winpart,"/dev/ed",7)) {
		printf(_("This device is not supported\n"));
		promptpart();
	}
#ifdef DEBUG
	debuglog("winpart",conf.winpart);
#endif
}



void promptbraille()
{
	FILE *brlttyfd;
	printf(_("Which braille driver should be loaded? (2 characters)\n"));
	printf(BRLTTYDRIVERS);
	prompt(conf.braille, 5);
	/*brlttyfd=fopen("braille.txt","r");													* loading brltty's drivers list *
	if (brlttyfd==NULL) {
		printf ("You need to have braille.txt\n");
		exit(-1);
		}
	stat("braille.txt", &buf);
	if (buf.st_size>7000) {
		printf ("file is too big\n");
		exit(-1);
	}
	brllist = alloc(buf.st_size);
	fread(brllist,buf.st_size, 1, brlttyfd);
	fclose(brlttyfd);*/
	if((*conf.braille == '\n')||strlen (conf.braille)!=2)
		promptbraille();
	if(strstr(BRLTTYDRIVERS,conf.braille)==NULL) {
		printf(_("This code is not supported\n"));
		promptbraille();
	}
#ifdef DEBUG
	debuglog("braille",conf.braille);
#endif
}

void promptbrailledev()
{
	printf(_("Where is it connected?\n"));
	promptcs(conf.brailledev,12);
	if(cmpn(conf.brailledev,"com",3) && strlen(conf.brailledev)==4)
	   sprintf(conf.brailledev,"/dev/ttyS%i",(conf.brailledev[3]&0x0F)-1);
			//extracting port number and converting
			//it from char to int
#ifdef DEBUG
	debuglog("brailledev",conf.brailledev);
#endif
	if(!cmpn(conf.brailledev,"/dev/",5)||cmp(conf.brailledev,"\n"))
		promptbrailledev();
}

void promptbrailletable()
{
	printf(_("Which table should be loaded?\n"));
	printf(BRLTTYTABLES);
	prompt(conf.brailletable,12);
	strcat(conf.brailletable," ");
#ifdef DEBUG
	        debuglog("texttable",conf.brailletable);
#endif
	if (strstr (BRLTTYTABLES,conf.brailletable) == NULL)
	{
		printf (_("This table is not supported\n"));
		promptbrailletable ();
	}
	else
		stripn(conf.brailletable);
}

void promptpath()
{
	printf(_("On which dos drive (ex: c: or c:\\directory ...) ?\n"));
	printf ("[c:\\linux] ");
															/* where should it be installed ? */
	prompt(conf.path,70);
	
	if(*conf.path == '\0')
		strcpy(conf.path,"c:\\linux");
	
	if(!cmpn(conf.path+1,":",1)||strstr(conf.path,"\\\\")!=NULL||strstr(conf.path,"//")!=NULL) {
		promptpath();
	}
	strcpy(conf.directory,extractfolder(conf.path));
	printf("%s\n",conf.directory);
#ifdef DEBUG
	debuglog("dospath",conf.path);
#endif
}



void installtype()
{
	int minimumsize;
	sprintf(partition.name,"%s\\linux",conf.path);
	sprintf(swap.name,"%s\\swap",conf.path);
	printf (_("Select installation type\n\
mini\tcreates a small ext2 loopback\n\
full\tcreates an ext2 ext3 loopback and swap\n\
fullaudio\tfull + free software speech synthesis\n"));
				
	prompt(conf.type,11);
	tolow(conf.type);
	if(conf.type == '\0')
		installtype();
#ifdef DEBUG
	debuglog("type",conf.type);
#endif
	if(!(cmp(conf.type,"mini")||cmp(conf.type,"full")||cmp(conf.type,"fullaudio")))
		installtype();
	minimumsize=(cmp(conf.type,"mini")) ? MINI : FULL;
	if(cmp(conf.type,"fullaudio"))
		minimumsize=FULLAUDIO;
	printf ("Root loopback\n");
	do
		partition.size=promptsize();
	while(partition.size < minimumsize);
	if(!cmp(conf.type,"mini"))
	{
		promptfs();
		printf ("Swap loopback\n");
		swap.create=1;
		swap.size=promptsize();
	}
	else
	{
		strcpy(partition.fs,"ext2");
		swap.create=0;
	}
}



void confirm()
{
#ifdef DEBUG
	fprintf(debugfd,"size %i\n",partition.size);
	debuglog("partition fs",partition.fs);
#endif
#ifdef DEBUG
	if(swap.create) fprintf(debugfd,"swap size %i\n",swap.size);
#endif
	printf (_("Current configuration :\n%s\n%s\t%s\t%iMB\n"),conf.path,partition.name,partition.fs,partition.size);
	if(!swap.create) {
		printf ("no swap\n");
	}
	else {
		printf ("%s\tswap\t%iMB\n",swap.name,swap.size);
	}
	printf (_("Language : %s\n"),conf.lang);
	printf (_("Windows partition : %s\n"),conf.winpart);
	printf (_("Braille driver : %s on device %s with table %s\n"),conf.braille,conf.brailledev,conf.brailletable);
	printf (_("Are these settings correct, shall I proceed (%s/%s)\n"),_("yes"),_("no"));

	prompt(conf.confirm,7);
	if(cmpn(conf.confirm,_("yes"),1))
	{
		writeconfig();
		return;
	}
	else
	{
		if(cmpn(conf.confirm,_("no"),1))
		{
			exit(0);
			exit(-1);
		}
		else {
			confirm();
		}
	}
}



void writeconfig()
{
	char pathbat[80],pathrbat[80],pathconf[80],linld[80];
	FILE *fdlinux;
	mkdir (conf.path, 777);

	sprintf(pathbat,"%s\\linux.bat",conf.path);
	fdlinux = fopen(pathbat,"w");
	if (fdlinux==NULL) {
		error();
	}
	fprintf (fdlinux,"linld image=vmlinuz initrd=initrd.img vga=0 \"cl=root=700 winpart=%s conf=%s/conf.txt\"\nrem WARNING: critical parameters: see doc/append.txt for documentation", conf.winpart, conf.directory);
	fclose(fdlinux);

	sprintf(pathrbat,"%s\\runonce.bat",conf.path);
	fdlinux = fopen(pathrbat,"w");
	if (fdlinux==NULL) {
		error();
	}
	fprintf (fdlinux,"linld image=vmlinuz initrd=initrd.img vga=0 \"cl=root=700 runonce winpart=%s conf=%s/conf.txt\"\nrem WARNING: critical parameters: see doc/append.txt for documentation", conf.winpart, conf.directory);
	fclose(fdlinux);

	sprintf(pathconf,"%s\\conf.txt",conf.path);
	fdlinux = fopen(pathconf,"w");
	if (!swap.create)
		strcpy(swap.name,"");
	if (fdlinux==NULL) {
			error();
		}
		fprintf (fdlinux,"# generated by brlspeak installer\n
#installation made to %s
#see doc/conf-sample.txt for documentation
loop=%s/linux
loopfs=%s
brldisp=%s
brldev=%s
texttable=text.%s.tbl
lang=%s
keymap=%s
sndmod=
swap=%s
swappart=
swappartfs=
basefile=
basepart=
basepartfs=",conf.directory,conf.directory,partition.fs,conf.braille,conf.brailledev,conf.brailletable,conf.lang,conf.keymap,swap.name);

	fclose(fdlinux);
	
	sprintf(linld,"copy bin\\linld.com %s",conf.path);
	system(linld);
	writelpbck();
	printf (_("Files written\n"));
	printf (_("Configuration finished\n"));
	chdir(conf.path);
}



void promptfs()
{
	printf (_("Input partition type"));
	printf(" ext2/ext3\n[ext3] ");
	prompt(partition.fs,6);
	if(*partition.fs == '\0') strcpy(partition.fs,"ext3");
	if(!(cmp(partition.fs,"ext2")||cmp(partition.fs,"ext3"))) promptfs();
}



unsigned int promptsize()
{
	char size[9];
	int sizei;
	printf(_("Input size in Megabytes"));
	prompt(size,9);
	sizei=atoi(size);
	return sizei;
}



void writelpbck() {
	char mke2[100];
	createlpbck(partition.name,partition.size);
	sprintf(mke2,"mke2fs.exe -L brlspeak -F%s %s",(cmp(partition.fs,"ext3"))? " -j": "",partition.name);
	printf ("%s\n",mke2);	/* send configuration to */
	system(mke2);		/* mke2fs/mkswap         */
	if(swap.create)
	{
		char* mkswap[3]={"mkswap","-c",swap.name};
		createlpbck(swap.name,swap.size);
		
	//	sprintf(mkswap,"mkswap.exe -c -v1 %s",swap.name);
		printf ("%s\n",mkswap);
		mkswapmain(3,mkswap);
		/*system(mkswap);*/
	}
}




#ifdef SOUND
void play(char * nom) {
	printf("playing %s\n",nom);
}

#endif

/*
void prtline (int linenum)
{
	printf ("%s\n",line(linenum));
}


char* line (int ligne)
{
	char *n,*m;
	int position, b;
	n = strchr (messages, '\n'); 	//find first occurence
	if (ligne!=1) {
		for (b=1;b<ligne;b++) {			// b is the number of occurence of \n
			m=n+1;				   		// m is previous match +1 skips the \n
			n = strchr (n+1, '\n');		// we seek the next one
*/		/*	if (n>=messages+buf.st_size) {
				printf ("end of buffer reached, exiting...");
				exit(-1);
			}*/
/*		}
	}
	else m=messages;
	strncpy(linecontent,m,n-m);
	position=n-m;
	linecontent[position]=0;
#ifdef DEBUG
	fprintf(debugfd,"ligne\t%i\t%s\n",ligne,linecontent);
#endif

#ifdef SOUND
	play(ligne);
#endif
	return linecontent;
}
*/

void prompt(char *buffer,int length)
{
	promptcs(buffer,length);
	buffer=tolow(buffer);
}

void promptcs(char *buffer,int length)   //prompt case sensitive
{
	printf(": ");
	fgets(buffer,length,stdin);
	stripn(buffer);
}


unsigned int cmp (char *pointer, char *string)
{
	if(strcmp(pointer, string)==0) {
		return 1;
	}
	else {
		return 0;
	}
}


unsigned int cmpn (char *pointer, char *string, int length)
{
	if(strncmp(pointer, string, length)==0) {
		return 1;
	}
	else {
		return 0;
	}
}




/* part of this, is courtesy from mapleman */
char * tolow ( char * moo )
{
 char *orig = moo;

 for ( ; moo && *moo; moo++ )
   if (isalpha (*moo))
	*moo |= 0x20;
 return orig;
}

char * toup ( char * moo )
{
 char *orig = moo;

 for ( ; moo && *moo; moo++)
   if (isalpha (*moo))
	*moo &= 0xdf;
 return orig;
}

void error ()
{
	printf ("Error occured: errno=%i\n%s\n", errno, strerror(errno));
	exit(-1);
}

#ifdef DEBUG
void debuglog(char *name, char* value) {
	char debugline[100];
	fprintf(debugfd,"%s :  '\n",name,value);
	fflush(debugfd);
}
#endif
