/*
 *  Source generated with GadToolsBox V1.0
 *  which is (c) Copyright 1991 Jaba Development
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include	"bug.c"
#include <clib/exec_protos.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <clib/dos_protos.h>
#include <workbench/startup.h>
#include	"struct.h"
#include	"tom_gadget.h"

#ifndef	WB_13
struct	Library *CxBase;
struct	Library	*GadToolsBase;
#endif
struct	Library	*IconBase;
struct	Library	*IntuitionBase;
struct	Library	*GfxBase;

extern	struct my_data	my_info;
extern	struct	tom_gadget	my_gadg[];
extern	struct	tom_gadget	gadg_alea[];

#define	GID_DEBUT	GID_TEMPO
#define	GID_TEMPO	5
#define	GID_MODULES	6
#define GID_DIR		7
#define	GID_PASSWD	9
#define	GID_LOCK	10
#define	GID_QUIET	11

#define	STRLEN_DARK	5		/* Equivalent to strlen(".dark") */
struct	contexe	big_ctx;

/* Structure qui sauvegarde les parametres */

int	selection=0;			/* Numero de l'effet selectionne */
int	last_sel=-1;			/* dernier numero selecitonne	 */
BPTR	segment=0;
int	flg_end;			/* Drapeau indiquant la sortie du prog */
UBYTE	flg_debug=FALSE;
char	*p_name;
UBYTE	flg_prog_dark;
UBYTE	flg_port_created;
struct	WBStartup	my_msg;

struct	Process	*process;
extern	struct	appel_proc	data_proc;
char	p_dark[]="That's Dark!";
int	nb_module=0;
char	*p_nom[MAX_NOM];
struct	Node ModulesNodes[MAX_NOM];
char	*p_alea="aleatoire";
struct	Node alea_node={0,0,0,0,"aleatoire"};
BPTR	old_lock=-1;
struct	MsgPort	*rep=0;
char	buffer[100];

struct List ModulesList = {
    &ModulesList.lh_Tail, ( struct Node * )0l, &ModulesList.lh_Head,0,0 };

aff_error(char *p_texte)
{
	affiche_texte(p_texte,NULL,NULL);

}

void	set_ext(char *pc)
{
	pc[strlen(pc)]='.';
}
void	unset_ext(char *pc)
{
	pc[strlen(pc)-STRLEN_DARK]=0;
}
int	find_mod(char *name_dir)
{
	struct Process *process;
	int	flg_err;
	int	etape,i,len;
	struct	FileInfoBlock	*fib;
	BPTR	lt;
	char	*p;
	UBYTE	flg_deuxieme_passe;

	flg_err=FALSE;
	etape=0;
	lt=0;
	flg_deuxieme_passe=FALSE;
	do{
		printd("find mod,etape:%d\n",etape);
		switch(etape){
			case	0:
				/* Allocation memoire pour le FileInfo Block	*/
				/* Je rapelle aue le fib doit etre aligne sur	*/
				/* un mot long....merci les BPTR			*/
				if((fib=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0))==0){
					flg_err=TRUE;
				}
				break;
			case	1:
				/* On cherche le repertoire courant */
				if(name_dir!=0){
				   if(*name_dir!=0){
					len=strlen(name_dir);
					if(name_dir[len-1]=='/'){
						name_dir[len-1]=0;
					}
					lt=Lock(name_dir,ACCESS_READ);
					if(lt!=0){
						printd("new dir ok\n");
						old_lock=CurrentDir(lt);
					}else{
						printd("Lock de %s failed!\n",name_dir);
					}
				   }
				}
				break;
			case	2:
				/* Si on n'a pas reussi a locke le repertoire donne */
				/* on cherche dans le repertoire courant 	    */
				if(lt==0){
					flg_deuxieme_passe=TRUE;
				        process = (struct Process *)FindTask(0);
					lt=process->pr_CurrentDir;
					if(lt==0){
						flg_err=TRUE;
						aff_error("Erreur avec current dir");
					}
				}
				break;
			case 3:
				/* On examine le repertoire */
				printd("Avant le examine:lt:%lx fib:%lx\n",lt,fib);
				if(Examine(lt,fib)==0){
					aff_error("Erreur examine....\n");
					flg_err=TRUE;
				}
				break;
			case 4:
				/* On examine d'abord les fichiers	*/
				while(ExNext(lt,fib)!=NULL){
					
					if(fib->fib_DirEntryType<0){
					    if(strlen(fib->fib_FileName)>5){
						p=fib->fib_FileName+strlen(fib->fib_FileName)-5;
						if(strcmp(p,".dark")==0){
							if(nb_module<MAX_NOM){
								p_nom[nb_module]=(char *)malloc(strlen(fib->fib_FileName)+1);
								strcpy(p_nom[nb_module],fib->fib_FileName);
								unset_ext(p_nom[nb_module]);
								nb_module++;
							}else{
								SPrintF(buffer,"ERREUR:Nombre maximum de modules atteint(%d)\n",MAX_NOM);
								aff_error(buffer);
							}
						}
					}
				   }
				}
				break;
			case 5:
				/* Si on n'avait trouve aucun module, on re-essaye */
				/* une deuxieme fois dans le repertoire courant	   */

				if((nb_module==0)&&(flg_deuxieme_passe==FALSE)&&(lt!=0)){
					CurrentDir(lt);
					old_lock=-1;
					lt=0;
					etape=3-1;
				}
				break;

		}
		etape++;
	/* Tant qu'il y a des etapes a effectuer	*/
	}while((etape<6)&&(flg_err==FALSE));

	if(nb_module!=0){

		tqsort(p_nom,nb_module);

		p_nom[nb_module]=p_alea;

		for(i=0;i<nb_module;i++){
			ModulesNodes[i].ln_Name=p_nom[i];
			ModulesNodes[i].ln_Type=0;
			AddTail(&ModulesList,&ModulesNodes[i]);
			if(strcmp(p_nom[i],p_nom[my_gadg[GID_MODULES].value])==0){
				selection=i;
			}
		}

		AddTail(&ModulesList,&alea_node);
		my_info.tempo_end=10;
		if(strcmp(p_alea,p_nom[my_gadg[GID_MODULES].value])==0){

			my_info.flg_alea=TRUE;
			selection=nb_module;
		}
	}else{
/*
		flg_err=1;
*/
		if(name_dir!=0){
			SPrintF(buffer,"No dark modules was found in the dir:\n\n%s\n\nHave you put the good directory in the\nTool type DARK DIRECTORY ?\n",name_dir);
		}else{
			SPrintF(buffer,"No dark modules was found!\nHave you put the good directory in the\nTool type DARK DIRECTORY ?\n",name_dir);
		}
		aff_error(buffer);
	}

	if(fib!=0)FreeMem(fib,sizeof(struct FileInfoBlock));
	return(flg_err);
}

/************************************************************ init_port *****/

int	init_port()
{
	struct	MsgPort	*mp;
	struct	appel_proc *ap;

	my_info.sigstart=-1;
	my_info.sigshow=-1;
	my_info.sigstop=-1;
	my_info.signext=-1;
	rep=CreatePort("Reponse",NULL);
	my_info.flg_alea=FALSE;
	flg_port_created=FALSE;
	if((ap=(struct appel_proc *)FindPort(p_dark))==0){
		mp=&data_proc.mp;
		mp->mp_Node.ln_Name=p_dark;
		mp->mp_Node.ln_Pri=0;
		mp->mp_Node.ln_Type=NT_MSGPORT;
/*
		mp->mp_SigBit=AllocSignal(-1);
		if(mp->mp_SigBit==-1){
			printf("Erreur Alloc Signal!\n");
		}
*/
		mp->mp_Flags=PA_IGNORE;
		AddPort(&data_proc.mp);	

		my_info.tempo=100;
		data_proc.p_info=&my_info;
		flg_port_created=TRUE;

		return(FALSE);
	}else{
		printd("Dark deja demarre!\n");

		/**********************************/
		/* On force la fenetre a s'ouvrir */
		/**********************************/

		Signal(ap->p_info->task,1<<(ap->p_info->sigshow));
		return(TRUE);
	}
}

/*************************************************************** do_dark() **/

void	do_dark()
{
	int	num_module;
	struct	Task	*mt;
	int	i;

	if(((last_sel!=selection)||(segment==0))&&(nb_module!=0)){
		if(segment!=0){
			Signal(&process->pr_Task,SIG_MAIN_DARK_EXIT);
			printd("J'attend le message de l'exit!\n");
			WaitPort(rep);
			GetMsg(rep);
			UnLoadSeg(segment);
		}
		num_module=selection%nb_module;
		last_sel=selection;

		data_proc.p_texte=0;
		set_ext(p_nom[num_module]);
		printd("Je charge le %d qui est:[%s]\n",num_module,p_nom[num_module]);
		segment=LoadSeg(p_nom[num_module]);

		if(segment!=0){
	
			process=(struct Process *)((char *)CreateProc(p_nom[num_module],-20,segment,8192)-sizeof(struct Task));
			mt=FindTask(0);
			my_msg.sm_Message.mn_ReplyPort=&data_proc.mp;
			my_msg.sm_Message.mn_ReplyPort=rep;

			my_msg.sm_ToolWindow=0;
			my_msg.sm_ArgList=0;
			my_msg.sm_NumArgs=0;
			process->pr_Task.tc_UserData=mt;
			my_info.task_dark=&process->pr_Task;
			PutMsg(&process->pr_MsgPort,(struct Msg *)&my_msg);
	
			/***********************************************************/
			/* On positionne le code retour, et on attend qu'il change */
			/* d'etat, indiquant que l'init est OK. On ne peut pas     */
			/* de 'meilleur' type de communication, car on n'est pas   */
			/* sur que c'est un module pour dark, et on risquerqais    */
			/* alors de bloquer en attente de reponse		   */
			/***********************************************************/
	
			i=100;
			data_proc.code_ret=-1;
			flg_prog_dark=TRUE;
			while((data_proc.code_ret==-1)&&(i-->0)){
				Delay(1);
			}
			if(data_proc.code_ret==-1){
				aff_error("ERROR:This is not a Dark Module!\n");
				flg_prog_dark=FALSE;
			}else{
				printd("Je charge la config\n");
				LoadConfig(p_nom[num_module],data_proc.p_gadg);
			}
#ifdef	WB_13
			/* Si c'est un module qui a besoin du WB2.0 */
			/* il ne faut pas l'executer...		    */
			if((data_proc.code_ret==DARK_WB_20)){
				aff_error("This one need 2.0 to run!\n");
				flg_prog_dark=FALSE;			
			}
#endif
		}else{
			aff_error("segment not found\n");
		}
		unset_ext(p_nom[num_module]);
	}
}

/*********************************************** Liberation des ressources **/

void	free_all()
{
	if(segment!=0){
		Signal(&process->pr_Task,SIG_MAIN_DARK_EXIT);
		WaitPort(rep);
		GetMsg(rep);
		UnLoadSeg(segment);
	}
	if(flg_port_created)RemPort(&data_proc.mp);
	if(rep)RemPort(rep);

	free_input_ev();
	CleanStuff_gadg(&big_ctx);
	if(old_lock!=-1){
		CurrentDir(old_lock);
	}
	if(IconBase)CloseLibrary(IconBase);
#ifndef	WB_13
	if(GadToolsBase)CloseLibrary(GadToolsBase);
#endif
	if(IntuitionBase)CloseLibrary(IntuitionBase);
	if(GfxBase)CloseLibrary(GfxBase);
}


main(argc,argv)
int	argc;
char	*argv[];
{
	int	etape,flg_err,i;
	struct	WBStartup *WBenchMsg;
	struct	WBArg	*wbarg;
	LONG	olddir;

	i=1;
	while(i<argc){

		if(strcmp(argv[i],"-d")==0){
			printf("Mode debug!\n");
			flg_debug=TRUE;
		}
		i++;
	}
	p_name=argv[0];
	olddir=-1;

        etape=0;
	flg_err=FALSE;
	while((flg_err==FALSE)&&(etape<6)){
		printd("Etape:%d\n",etape);
		switch(etape){

		   case 0:

			/* First, we open all the needed library	*/

			IntuitionBase=(struct Library *)OpenLibrary("intuition.library",0);
			GfxBase=(struct Library *)OpenLibrary("graphics.library",0);
			IconBase=(struct Library *)OpenLibrary("icon.library",0);
#ifndef	WB_13
/*			CxBase=OpenLibrary("commodities.library",37L);*/
			GadToolsBase=(struct Library *)OpenLibrary("gadtools.library",0);
			if(GadToolsBase==0){
				printf("Erreur ouverture lib\n");
			}
#endif
			break;

			/* initialisation du port de communication */
		   case 1:
			flg_err=init_port();
			break;
			/* chargement des parametres de config */
		   case 2:
			/* Du WB? */
			if(argc==0){
				WBenchMsg=(struct WBStartup *)argv;
				for(i=0,wbarg=WBenchMsg->sm_ArgList;
					i<WBenchMsg->sm_NumArgs;
					i++,wbarg++){
					if((wbarg->wa_Lock)&&(*wbarg->wa_Name)){
						p_name=wbarg->wa_Name;
						olddir=CurrentDir(wbarg->wa_Lock);
					}
				}
				
			}
			LoadConfig(p_name,&my_gadg[GID_TEMPO]);
			my_info.tempo=my_gadg[GID_TEMPO].value;
			printd("Tempo:%d\n",my_info.tempo);

			/* Rem: les parametres du module aleatoire sont sauvegarde*/
			/* avec ceux du fichier principal, car le mode aleatoire  */
			/* n'ayant pas d'icone...				  */
			LoadConfig(p_name,gadg_alea);
			break;

			/* recherche des modules existants     */
		   case 3:
			/* initialisation de l'input ev */
		   case 4:
			flg_err=init_input_ev();
			/* We open the main window	*/
			break;
		   }
		   etape++;
	}
	if(flg_err==FALSE){

		/* Si il n'y a aucun module, on ouvre la fentre, pour que  */
		/* l'utilisateur voi qq chose!				   */

		if(nb_module==0){
			InitStuff_gadg(&big_ctx,TRUE);
		}else{
			if(my_gadg[GID_QUIET].value==FALSE){
				affiche_texte("SuperDark Installed...\nPress HotKey for options",NULL,TRUE);
			}
		}
		main_loop(&big_ctx);
		my_gadg[GID_MODULES].value=selection;
		if(big_ctx.flg_save==TRUE){
			SaveConfig(p_name,&my_gadg[GID_DEBUT]);
		}
	}
	if(olddir!=-1)CurrentDir(olddir);
	free_all();

}
