#include <vdi.h>
#include <aes.h>
#include <stdio.h>
#include <stdlib.h>
#include <tos.h>
#include <string.h>
#include <process.h>
#include <time.h>
#include <ext.h>
#include "hi_gfa_.h"

#define min(a, b)             ((a) < (b) ? (a) : (b))
#define max(a, b)             ((a) > (b) ? (a) : (b))

typedef enum
{
    FALSE,
    TRUE
}
boolean;

int work_in[12],work_out[57],pxyarray[8];
int msg_buf[16];
int handle,phys_handle;

int gl_hchar, gl_wchar, gl_hbox, gl_wbox;
int gl_apid;	


/* Window*/
int wix,wiy,wiw,wih, wiwx,wiwy,wiwh,wiww ,w_handle;
int wi2x,wi2y,wi2w,wi2h, wiw2x,wiw2y,wiw2h,wiw2w ,w_handle2;

/*resoure */
OBJECT *dial;
char	comp[256]="C:\\GFA_BCOMP.PRG", link[256]="C:\\GL.PRG",
		inter[256]="C:\\GFABASIC.PRG", lib[256]="C:\\GFA3BLIB",
		rcs[256]="C:\\RCS.PRG",
		input[256]="C:\\TEST.GFA", object[256]="C:\\TEST.O", output[256]="C:\\TEST.PRG",
		c_opt[26]="S& S< F<", l_opt[256]="-s";
int   buttons[9]={AUSWAHL,COMPILE,LINK,CUNDL,INTER,RCS,TEST,SONST,ENDE};
char 	strings[8][20]={"Compiler","Linker","Interpreter","Library","RCS",
					       "Input File","Object File","Output File"};
int 	pos,ob_ed=0;

/* Ausgabefenster */
int char_height,lines;
char msgs[10][80];

/* Execution */
char com[256], link_opt[80], inter_cmd[256], rcs_cmd[256], env[256];

/* Funktionsprototypen */
boolean open_vwork( void );
void   close_vwork( void );
void   gem_prg( void );
int	 get_char_height( void );   /* Textzeichenh”he bestimmen */
void 	 win1_update( void );		 /* Fenster 1 wiederherstellen */		
void	 win2_update( void );		 /* Fenster 2 wiederherstellen */
void	 white_box(int x, int y, int w, int h); /* weisses Rechteck zeichnen */
long 	 my_clock( void ); 			 /* Systemtimer */
void   auswahl( void ); 			 /* Input File ausw„hlen */
void 	 suchen( int num ); 			 /* Compiler e.t.c finden */
void	 compiler( void );		    /* Compiler aufrufen */
void	 linker( void );				 /* Linker aufrufen */
void 	 interpreter( void );		 /* Interpreter aufrufen */
void 	 rcs_exec( void );			 /* RCS ausfhren */
void 	 test_prog( void ); 			 /* Compiliertes Programm testen */
void   exec_other( void );			 /* anderes Programm ausfhren */
void   msg_out( char *msg_text ); /* Texte in Fenster 2 ausgeben */
void	 rsrc_init( void );			 /* rsc_file initialisieren */
void   do_dial( void );				 /* Dialog managen */

boolean open_vwork( void )
{
   register int i;

   if (( gl_apid = appl_init() ) != -1 )
   {
      for ( i = 1; i < 10; work_in[i++] = 1 );
      work_in[10] = 2;
      phys_handle = graf_handle( &gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox );
      work_in[0]  = handle = phys_handle;

      v_opnvwk( work_in, &handle, work_out );

      return ( TRUE );
   }
   else
      return ( FALSE );
}

void close_vwork( void )
{
   v_clsvwk( handle );

   appl_exit( );
}

int get_char_height( void ) /* Zeichenh”he holen */
{
	int extend[8];
	vqt_extent(handle,"M",extend);
	return(extend[7]-extend[3]);
}

long my_clock( void ) /*systemtimer */
{
	long *old_sp, clkticks, *clkptr;
	
	old_sp=(long *)Super(0L);
	clkptr=(long *)0x4baL;
	clkticks=*clkptr;
	Super(old_sp);
	return(clkticks);
}

void win1_update( void )
{
	int r[4],clp[4];

	wind_update(BEG_UPDATE);
	wind_get(w_handle,WF_FIRSTXYWH,&r[0],&r[1],&r[2],&r[3]);
	clp[0]=r[0]; clp[1]=r[1];
	clp[2]=r[0]+r[2]; clp[3]=r[1]+r[3];
	vs_clip(handle,1,clp);
	white_box(r[0],r[1],r[2],r[3]); 
	objc_draw(dial,0,MAX_DEPTH,r[0],r[1],r[2],r[3]);
	vs_clip(handle,0,clp);
	do
	{
		wind_get(w_handle,WF_NEXTXYWH,&r[0],&r[1],&r[2],&r[3]);
		if(r[2]!=0)
		{
			clp[0]=r[0]; clp[1]=r[1];
			clp[2]=r[0]+r[2]; clp[3]=r[1]+r[3];
			vs_clip(handle,1,clp);
		 	white_box(r[0],r[1],r[2],r[3]);  
			objc_draw(dial,0,MAX_DEPTH,r[0],r[1],r[2],r[3]);
			vs_clip(handle,0,clp);
		}
	}while(r[2]!=0);
	objc_edit(dial,S1+ob_ed,0,&pos,1);
	wind_update(END_UPDATE);
}

void win2_update( void )
{
	int i,r[4],clp[4];

	for(i=0;i<lines;i++) 
		if(strlen(msgs[i])<79)
			do{strcat(msgs[i]," ");} while(strlen(msgs[i])<79);
	
	wind_update(BEG_UPDATE);
	wind_get(w_handle2,WF_FIRSTXYWH,&r[0],&r[1],&r[2],&r[3]);
	clp[0]=r[0]; clp[1]=r[1];
	clp[2]=r[0]+r[2]; clp[3]=r[1]+r[3];
	vs_clip(handle,1,clp);
	white_box(r[0],r[1],r[2],r[3]);
	for(i=0;i<lines;i++) 
		v_gtext(handle,wiw2x,wiw2y+(i+1)*char_height,msgs[i]);	
	vs_clip(handle,0,clp);
	do
	{
		wind_get(w_handle2,WF_NEXTXYWH,&r[0],&r[1],&r[2],&r[3]);
		if(r[2]!=0)
		{
			clp[0]=r[0]; clp[1]=r[1];
			clp[2]=r[0]+r[2]; clp[3]=r[1]+r[3];
			vs_clip(handle,1,clp);
		 	white_box(r[0],r[1],r[2],r[3]);
		 	for(i=0;i<lines;i++) 
		 		v_gtext(handle,wiw2x,wiw2y+(i+1)*char_height,msgs[i]);	
			vs_clip(handle,0,clp);
		}
	}while(r[2]!=0);
	wind_update(END_UPDATE);
}

void white_box(int x, int y, int w, int h) /* weisses Rechteck zeichnen */
{
	int pxy_array[8];
	
	vsf_interior(handle,FIS_SOLID);
	vsf_color(handle,0);
	vsf_perimeter(handle,0);
	pxy_array[0]=x;   pxy_array[1]=y;
	pxy_array[2]=x+w; pxy_array[3]=y+h;
	v_bar(handle,pxy_array);
}

void msg_out( char *msg_text) /* Texte in Fenster 2 ausgeben */
{
	int i;
	
	for(i=0;i<lines-1;i++) 
		strcpy(msgs[i],msgs[i+1]);
	strcpy(msgs[lines-1],msg_text);
	win2_update();
}
	
void save_settings( void ) /* Einstellungen Sichern */
{
	int i;
	FILE *settings;
	
	settings = fopen("HI_GFA.INF","w");
	if(settings!=NULL)
	{
		for(i=0; i<10; i++)
			fprintf(settings,"%s\n",dial[S1+i].ob_spec.tedinfo->te_ptext);
		fclose(settings);
	}
}

void auswahl( void ) /* Input File Ausw„hlen */
{
	char path[110],name[15], *hptr;
	int ex_bttn;

	msg_out("Input File w„hlen");
	strcpy(path,dial[S1+5].ob_spec.tedinfo->te_ptext);
	strcpy(name,strrchr(path,'\\')+1); 
	strrchr(path,'\\')[1]='\0'; 
	strcat(path,"*.GFA");
	fsel_input(path,name,&ex_bttn);
   msg_out(path); msg_out(name);
	if(ex_bttn==1) /* OK Button */
	{
		hptr=strrchr(path,'\\'); hptr++; strcpy(hptr,name); /*Input name */
		strcpy(dial[S1+5].ob_spec.tedinfo->te_ptext,path); 
		strcpy(dial[S1+6].ob_spec.tedinfo->te_ptext,path); /*object name*/
		hptr=strrchr(dial[S1+6].ob_spec.tedinfo->te_ptext,'.');
		strcpy(hptr,".O");
		strcpy(dial[S1+7].ob_spec.tedinfo->te_ptext,path); /*output_name */
		hptr=strrchr(dial[S1+7].ob_spec.tedinfo->te_ptext,'.');
		strcpy(hptr,".PRG");
		save_settings();
		win1_update();
	}
}   

void suchen(int num) /* Compiler e.t.c finden */
{
	char hint[80],path[110],name[15], *hptr;
	int ex_bttn;

	strcpy(hint,"Searching for "); strcat(hint,strings[num]);
	msg_out(hint);

	strcpy(path,dial[S1+num].ob_spec.tedinfo->te_ptext);
	strcpy(name,strrchr(path,'\\')+1); 
	strrchr(path,'\\')[1]='\0'; 
	strcat(path,"*"); 
	hptr=strrchr(name,'.');
	hptr==NULL ? strcat(path,".*") : strcat(path,hptr);
	fsel_input(path,name,&ex_bttn);
   msg_out(path); msg_out(name);
	if(ex_bttn==1) /* OK Button */
	{
		hptr=strrchr(path,'\\'); hptr++; strcpy(hptr,name); /*Programm name */
		strcpy(dial[S1+num].ob_spec.tedinfo->te_ptext,path); 
		win1_update();
	}
}

void get_com_env( void ) /* Command und environment Strings basteln */
{
	char *hptr;
	
	com[0]=' '; com[1]='\0';
	strcat(com,dial[S1+5].ob_spec.tedinfo->te_ptext); /*inpath */
	strcat(com," ");
	strcat(com,dial[S1+8].ob_spec.tedinfo->te_ptext); /*comp options */
	strcat(com," -O "); /* -o */
	strcat(com,dial[S1+6].ob_spec.tedinfo->te_ptext); /*object file */
	
	strcpy(env,"G3OBJ=");
	strcat(env,dial[S1+6].ob_spec.tedinfo->te_ptext); /*object file */
	hptr=env+strlen(env)+1L;
	strcpy(hptr,"G3PRG=");
	strcat(hptr,dial[S1+7].ob_spec.tedinfo->te_ptext); /*out file */
	hptr+=(strlen(hptr)+1L);
	strcpy(hptr,"G3LIB=");
	strcat(hptr,dial[S1+3].ob_spec.tedinfo->te_ptext); /* library */
	strcpy(l_opt,"X");
	strcpy(l_opt,dial[S1+9].ob_spec.tedinfo->te_ptext);/* Linker Options*/
	strcpy(inter_cmd,"X");
	strcpy(inter_cmd,dial[S1+5].ob_spec.tedinfo->te_ptext);/* Input File fr den Interpreter */
	strcpy(rcs_cmd,inter_cmd);
	strcpy(strrchr(rcs_cmd,'.'),".RSC"); /*Commandline fr das RCS */
}

void compiler( void ) /* Compiler Starten */
{
	char hint[80];
	int err,retcode,fi_handle,fi_dup,i;
	FILE *tmp;
	extern int errno;
	long exe_time;
	
	msg_out("Starting compiler");
	save_settings();
	get_com_env();
	exe_time=my_clock();
	fi_handle=(int)Fcreate("HI_GFA.TMP",0);
	fi_dup = (int)Fdup(1); 
	Fforce(1,fi_handle);
	err=exec(dial[S1].ob_spec.tedinfo->te_ptext, /*pfadname*/
				com,env,&retcode);
	Fclose(fi_handle); Fforce(1,fi_dup);
	tmp=fopen("HI_GFA.TMP","r");
	while(feof(tmp)==0) 
	{
		i=0;
		do{ hint[i]=getc(tmp); } while((hint[i++]!='\012')&&(feof(tmp)==0));
		getc(tmp);
		hint[i-1]='\0'; 
		msg_out(hint);
	}
	unlink("HI_GFA.TMP");
	if(err==0) errno=0;
	sprintf(hint,"Fehler: %d -- Returnwert %d -- Zeit %5f",errno,retcode,(float)((my_clock()-exe_time)/200.0));
	msg_out(hint);
}

void linker( void ) /* Linker Starten */
{
	char hint[120];
	int err,retcode,fi_handle,fi_dup,i;
	FILE *tmp;
	extern int errno;
	long exe_time;
	
	msg_out("Starting linker");
	save_settings();
	get_com_env();
	exe_time=my_clock();
	fi_handle=(int)Fcreate("HI_GFA.TMP",0);
	fi_dup = (int)Fdup(1); Fforce(1,fi_handle);
	err=exec(dial[S1+1].ob_spec.tedinfo->te_ptext, /*pfadname*/
				link_opt,env,&retcode);
	Fclose(fi_handle); Fforce(1,fi_dup);
	tmp=fopen("HI_GFA.TMP","r");
	while(feof(tmp)==0) 
	{
		i=0;
		do{ hint[i]=getc(tmp); }  while((hint[i++]!='\012')&&(feof(tmp)==0));
		getc(tmp);
		hint[i-1]='\0'; 
		msg_out(hint);
	}
	unlink("HI_GFA.TMP");
	if(err==0) errno=0;
	sprintf(hint,"Fehler: %d -- Returnwert %d -- Zeit %5f",errno,retcode,(my_clock()-exe_time)/200.0);
	msg_out(hint);
	sprintf(hint,"Killing %s",dial[S1+6].ob_spec.tedinfo->te_ptext);
	msg_out(hint);
	err=unlink(dial[S1+6].ob_spec.tedinfo->te_ptext);
	(err==0) ? msg_out("done") : msg_out("failed");
}

void interpreter( void ) /* Interpreter starten */
{
	char hint[80],path[110],old_path[110],name[15];
	int retcode,err,old_drv;
	extern int errno;
	long exe_time;
	
	msg_out("Starting Interpreter");
	save_settings();
	get_com_env();
	old_drv=getdisk();
	getcurdir(0,old_path);
	strcpy(path,dial[S1+5].ob_spec.tedinfo->te_ptext);
	strcpy(name,strrchr(path,'\\')+1);
	setdisk((int)(path[0]-'A')); 
	*strrchr(path,'\\')='\0';
	err=Dsetpath(path+2); 
	exe_time=my_clock();
	err=exec(dial[S1+2].ob_spec.tedinfo->te_ptext, /*pfadname*/
				name,"\0",&retcode);
	if(err==0)errno=0;
	sprintf(hint,"Fehler: %d -- Returnwert %d -- Zeit %5f",errno,retcode,(my_clock()-exe_time)/200.0);
	setdisk(old_drv); Dsetpath(old_path);
	wind_set(w_handle2,WF_TOP,0,0,0,0);
	wind_set(w_handle,WF_TOP,0,0,0,0);
	win1_update();
	msg_out(hint);
}

void rcs_exec( void ) /* RCS Starten */
{
	char hint[80],path[110],old_path[110],name[15];
	int retcode,err,old_drv;
	extern int errno;
	long exe_time;
	
	msg_out("Starting Resource Construction Set");
	get_com_env();
	old_drv=getdisk();
	getcurdir(0,old_path);
	strcpy(path,dial[S1+4].ob_spec.tedinfo->te_ptext);
	strcpy(name,strrchr(path,'\\')+1);
	setdisk((int)(path[0]-'A')); 
	*strrchr(path,'\\')='\0';
	err=Dsetpath(path+2); 
	exe_time=my_clock();
	err=exec(name, /*pfadname*/
				rcs_cmd,"\0",&retcode);
	if(err==0)errno=0;
	sprintf(hint,"Fehler: %d -- Returnwert %d -- Zeit %5f",errno,retcode,(my_clock()-exe_time)/200.0);
	setdisk(old_drv); Dsetpath(old_path);
	wind_set(w_handle2,WF_TOP,0,0,0,0);
	wind_set(w_handle,WF_TOP,0,0,0,0);
	win1_update();
	msg_out(hint);
}

void test_prog( void ) /* Compiliertes Programm testen */
{
	char hint[80],path[110],old_path[106],name[15];
	int retcode,err,old_drv;
	extern int errno;
	long exe_time;
	
	msg_out("Test");
	save_settings();
	old_drv=getdisk();
	getcurdir(0,old_path);
	strcpy(path,dial[S1+7].ob_spec.tedinfo->te_ptext);
	strcpy(name,strrchr(path,'\\')+1);
	setdisk((int)(path[0]-'A')); 
	*strrchr(path,'\\')='\0';
	err=Dsetpath(path+2); 
	exe_time=my_clock();
	err=exec(name, 
				"\0","\0",&retcode);
	setdisk(old_drv); Dsetpath(old_path);
	if(err==0)errno=0;
	sprintf(hint,"Fehler: %d -- Returnwert %d -- Zeit %5f",errno,retcode,(my_clock()-exe_time)/200.0);
	wind_set(w_handle2,WF_TOP,0,0,0,0);
	wind_set(w_handle,WF_TOP,0,0,0,0);
	win1_update();
	msg_out(hint);
}

void  exec_other( void )			 /* anderes Programm ausfhren */
{
	char hint[80],path[110],name[15], *hptr;
	int ex_bttn,err,errno,retcode;
	int old_drv;
	char old_path[110];
	long exe_time;
	
	msg_out("Executing other Program"); 
	strcpy(path,"C:\\*.PRG"); strcpy(name,"\0");
	fsel_input(path,name,&ex_bttn);
   if(ex_bttn==1) /* OK Button */
	{
		old_drv=getdisk();
		getcurdir(0,old_path);
		setdisk((int)(path[0]-'A')); 
		*strrchr(path,'\\')='\0';
		err=Dsetpath(path+2); 
		hptr=strrchr(path,'\\'); hptr++; strcpy(hptr,name); /*Programm name */
		exe_time=my_clock();
		err=exec(name, /*pfadname*/
				"\0","\0",&retcode);
		if(err==0)errno=0;
		sprintf(hint,"Fehler: %d -- Returnwert %d -- Zeit %5f",errno,retcode,(my_clock()-exe_time)/200.0);
		setdisk(old_drv); Dsetpath(old_path);
		wind_set(w_handle2,WF_TOP,0,0,0,0);
		wind_set(w_handle,WF_TOP,0,0,0,0);
		win1_update();
		msg_out(hint);
	}
}

void rsrc_init( void ) /* Strings in rsc eintragen und Fenstergr”že bestimmen */
{
	FILE *settings;
	int y_dial, dummx,dummw,dummh;

	wind_get(0,WF_WORKXYWH,&dummx,&y_dial,&dummw,&dummh);
	wind_calc(WC_WORK,NAME|MOVER,dummx,y_dial,dummw,dummh,&dummx,&y_dial,&dummw,&dummh);
	if(!rsrc_load("hi_gfa.rsc"))
	{
		form_alert(1,"[1][RSC-Datei nicht gefunden][Ach so]");
		exit(0);
	}
	rsrc_gaddr(ROOT,DIA0,(void *)&dial);
	form_center(dial,&wiwx,&wiwy,&wiww,&wiwh);
	wiwy=dial[0].ob_y=y_dial;
	settings = fopen("HI_GFA.INF","r");
	if (settings!=NULL) /*inf Datei lesen*/
	{
		fscanf(settings,"%s",comp);
		fscanf(settings,"%s",link);
		fscanf(settings,"%s",inter);
		fscanf(settings,"%s",lib);
		fscanf(settings,"%s",rcs);
		fscanf(settings,"%s",input);
		fscanf(settings,"%s",object);
		fscanf(settings,"%s",output);
		fscanf(settings,"%s",c_opt);
		fscanf(settings,"%s",l_opt);
		fclose(settings);
	}
	strcpy(dial[S1].ob_spec.tedinfo->te_ptext, comp);/* String eintragen */
	strcpy(dial[S1+1].ob_spec.tedinfo->te_ptext, link);/* String eintragen */
	strcpy(dial[S1+2].ob_spec.tedinfo->te_ptext, inter);/* String eintragen */
	strcpy(dial[S1+3].ob_spec.tedinfo->te_ptext, lib);/* String eintragen */
	strcpy(dial[S1+4].ob_spec.tedinfo->te_ptext, rcs);/* String eintragen */			
	strcpy(dial[S1+5].ob_spec.tedinfo->te_ptext, input);/* String eintragen */
	strcpy(dial[S1+6].ob_spec.tedinfo->te_ptext, object);/* String eintragen */	
	strcpy(dial[S1+7].ob_spec.tedinfo->te_ptext, output);/* String eintragen */	
	strcpy(dial[S1+8].ob_spec.tedinfo->te_ptext, c_opt);/* String eintragen */	
	strcpy(dial[S1+9].ob_spec.tedinfo->te_ptext, l_opt);/* String eintragen */	

}

void do_dial() /* Hauptdialog */
{
	int what,mousex,mousey,mbutton,mstate,key,klicks;
	int i, key0, sel, knopf;
		
	do
	{
		knopf=-1;
		what= evnt_multi(MU_KEYBD|MU_BUTTON|MU_MESAG,
				 		   1,1,1,
				 		   1,wiwx,wiwy,wiww,wiwh,
				 		   0,0,0,0,0,
						   msg_buf,0,0,
					  	   &mousex,&mousey,&mbutton,&mstate,&key,&klicks);
		switch(what)
		{
			case MU_KEYBD:		/* Keyboard Event */
				key0=key; key>>=8;  /* nur Ascii interessant */
				if(key>=59 && key<=67) knopf=key-59;	/*Funktion Key*/
				else
				{
					switch(key)
					{
						case 72:	/*CUR UP*/
							objc_edit(dial,S1+ob_ed,0,&pos,3);
							ob_ed--; if(ob_ed==-1)ob_ed=9;
							objc_edit(dial,S1+ob_ed,0,&pos,1);
							break;
						case 80:	/*CUR DN */
							objc_edit(dial,S1+ob_ed,0,&pos,3);
							ob_ed=(ob_ed+1) % 10;
							objc_edit(dial,S1+ob_ed,0,&pos,1);
							break;
						default:
							objc_edit(dial,S1+ob_ed,key0,&pos,2);
					}
				} break;
			case MU_BUTTON:
				sel=objc_find(dial,ROOT,MAX_DEPTH,mousex,mousey);
				if(mstate==0) 			/* Einfachklick */
				{
					for(i=0; i<9;i++)	/* Buttons */
						{if(sel==buttons[i]) knopf=i;}
					for(i=0; i<10;i++) /*Strings */
						if(sel==S1+i) 	 /*Objc_edit „ndern */
						{
						objc_edit(dial,S1+ob_ed,0,&pos,3);
						ob_ed=sel-S1;
						objc_edit(dial,S1+ob_ed,0,&pos,1);
						}
				}
				else
				{
					for(i=0; i<8;i++) /*Strings */
						if(sel==S1+i) 	 /*Entspr. Objekt suchen*/
						{
						/* Falls i=5 -> Auswahl, sonst normal suchen */
						(i==5) ? knopf=0 : suchen(i);
						}
				}	
				break;
			case MU_MESAG: 
				switch(msg_buf[0])
				{
					case WM_REDRAW:
					if(msg_buf[3]==w_handle2) win2_update();
					else
					{
						win1_update();
					}break;
					case WM_MOVED:
					if(msg_buf[3]==w_handle2)
					{
						wi2x=msg_buf[4]; wi2y=msg_buf[5];
						wi2w=msg_buf[6]; wi2h=msg_buf[7];
						wind_calc(NAME|MOVER,WC_WORK,
									 wi2x,wi2y,wi2w,wi2h,&wiw2x,&wiw2y,&wiw2w,&wiw2h);
						wind_set(w_handle2,WF_CURRXYWH,wi2x,wi2y,wi2w,wi2h);
						win2_update();
					}
					else
					{
						wix=msg_buf[4]; wiy=msg_buf[5];
						wiw=msg_buf[6]; wih=msg_buf[7];
						wind_calc(NAME|MOVER,WC_WORK,
									 wix,wiy,wiw,wih,&wiwx,&wiwy,&wiww,&wiwh);
						dial[0].ob_x=wiwx; dial[0].ob_y=wiwy;
						wind_set(w_handle,WF_CURRXYWH,wix,wiy,wiw,wih);
						win1_update();
					}
					break;
				}	
		}
		switch(knopf)
		{
			case 0:	auswahl(); break;
			case 1: 	compiler(); break;
			case 2:	linker(); break;
			case 3:	compiler(); linker(); break;
			case 4: 	interpreter(); break;
			case 5:	rcs_exec(); break;
			case 6:	test_prog(); break;
			case 7:	exec_other(); break;
		}
	}while(knopf!=8);
	save_settings();
}				  

void gem_prg() /* Fenster einrichten und dann dial aufrufen */
{
	void *dummy;
	
	dummy=0;	/* gibt sonst Warning*/
	graf_mouse(M_OFF,(void *)dummy);
	rsrc_init();
	char_height=get_char_height();
	/*Dialog Fenster*/
	wind_update(BEG_UPDATE);
	wind_calc(WC_BORDER,NAME|MOVER,wiwx,wiwy,wiww,wiwh,&wix,&wiy,&wiw,&wih);
	w_handle=wind_create(NAME|MOVER,wix,wiy,wiw,wih);
	wind_set(w_handle,WF_NAME,"HI-Gfa",0,0);
	wind_open(w_handle,wix,wiy,wiw,wih);
	/*Ausgabe Fenster*/
	wind_calc(WC_WORK,NAME|MOVER,0,wiy+wih+10,min(work_out[0],640),min(11*char_height,work_out[1]-10-wiy-wih),
				 &wiw2x,&wiw2y,&wiw2w,&wiw2h);
	wind_calc(WC_BORDER,NAME|MOVER,wiw2x,wiw2y,wiw2w,wiw2h,
				 &wi2x,&wi2y,&wi2w,&wi2h);
	lines=wiw2h/char_height;
	w_handle2=wind_create(NAME|MOVER,wi2x,wi2y,wi2h,wi2w);
	wind_set(w_handle2,WF_NAME,"What's loose",0,0);
	wind_open(w_handle2,wi2x,wi2y,wi2w,wi2h);
	vsf_interior(handle,1); vsf_color(handle,0); 
	pxyarray[0]=wiw2x;pxyarray[1]=wiw2y;pxyarray[2]=wiw2x+wiw2w;pxyarray[3]=wiw2y+wiw2h;
	v_bar(handle, pxyarray );
	wind_set(w_handle,WF_TOP,0,0,0);
	wind_update(END_UPDATE);
	win1_update();
	graf_mouse(M_ON,dummy); graf_mouse(ARROW,dummy);
	do_dial();
}

void main( void ) /* GEM init */
{
   if ( open_vwork( ) == TRUE )
   {
      gem_prg( );
      /* Aufr„umen */
      wind_close(w_handle2); wind_delete(w_handle2);
      wind_close(w_handle);  wind_delete(w_handle);
      rsrc_free();
      close_vwork( );
      exit ( 0 );
   }
   else
   {
      fprintf( stderr, "Fehler bei der Programminitialisierung!" );
      exit ( -1 );
   }
}
