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

#include <exec/types.h>
#include <exec/tasks.h>
#include <dos/dosextens.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include "/includes/struct.h"
#include "/includes/tom_gadget.h"
#include "gid_main.h"

#ifndef custom
#define custom (*(struct Custom *)0xDFF000)
#endif	/* custom */

extern	struct	contexe	big_ctx;
extern	UBYTE	flg_prog_dark;
ULONG	cxsigflag=0;
#define	MIN_TEMPO	10
#define	MAX_TEMPO	300

extern	struct my_data	my_info;
extern	char	*p_nom[];
extern	int	selection,last_sel;
extern	int	nb_module;
extern	struct	Process	*process;
extern	UBYTE	flg_debug;
extern	LONG	dir_save,old_lock;
LONG	sigstart_f,sigshow_f,sigstop_f,signext_f;

extern	struct	IntuitionBase	*IntuitionBase;

struct	appel_proc	data_proc;

extern struct  List ModulesList;
extern	struct Node    ModulesNodes[];

int	press_param();
int	press_hide();
int	press_quit();
int	press_save();
int	press_help();
void	press_rescan();

char	directory[30]="";
char	popkey[30]="shift f3";
char	blankey[30]="shift f4";
char	passwd[10]="";
extern	USHORT	flg_sel[MAX_NOM];
extern	struct	tom_gadget	gadg_alea[];

#include "logo.h"

struct	tom_gadget	my_gadg[]={
	{"_Remove",	BUTTON   ,10,200,  70,13,0,0,0,0,(char *)&press_quit},
	{"_Param-->",	BUTTON   ,8,106,  70,13,0,0,0,0,(char *)&press_param},
	{"H_elp...",	BUTTON   ,160,200, 70,13,0,0,0,0,(char *)&press_help},
	{"_Hide",	BUTTON   ,235,200, 70,13,0,0,0,0,(char *)&press_hide},
	{"_Save",	BUTTON   ,85,200, 70,13,0,0,0,0,(char *)&press_save},

	{"_Tempo",	SLIDER   , 274,15,  24,76,MIN_TEMPO,MIN_TEMPO,MAX_TEMPO,0,(char *)&my_info.tempo},
	{"_Modules",	LISTVIEW ,80,15, 144,105,0,0,0,0,(char *)&ModulesList},
	{"_Dark directory",STRING,160,120,144,14,0,30,0,0,directory},
	{"_CxPopkey"   ,STRING,160,140,144,14,0,30,0,0,popkey},
	{"_Blankkey"   ,STRING,160,160,144,14,0,30,0,0,blankey},
	{"Pass_wd"     ,STRING,160,180,144,14,0,10,0,0,passwd},
	{"_Lock"       ,CHECKBOX,60,180,144,14,FALSE,0,0,0,0},
	{"_Quiet"       ,CHECKBOX,274,105,14,14,FALSE,0,0,0,0},
/*	{"_Usage Hard",CHECKBOX,400,105,14,14,FALSE,0,0,0,0},*/
	{"Tas_kPri",	SLIDER ,370,140, 24,40,	0,-10,0,0,0},
	{"",		IMAGE,  320,20,  40,40, 0, 0,0,0,(char *)&logo_iffImage},
/*
	{"Rescan",	BUTTON ,370,100, 24,40,	 0, 0,0,0,(char *)&press_rescan},
*/
	{0,		END_LISTE,  0,  0,   0,  0, 0,0,0,0,0}};

#ifdef	WB_13
extern	struct IntuiMessage *tom_GetMsg(struct MsgPort *UserPort);
#endif

struct Screen        *s= NULL;
struct Window        *w2   = NULL;
struct BitMap        b;
int	width,height,cleared;
short	s2depth;
struct NewScreen newscreen = {
  0,0,0,0,0,0,0,NULL,CUSTOMSCREEN|CUSTOMBITMAP,NULL,(UBYTE *)" ",NULL,NULL
};
struct Preferences   MyCopy;
USHORT PointerData[POINTERSIZE];


/**************************************************************************/

void	GetPointer()
{
  int i;

  GetPrefs(&MyCopy,(long)sizeof(MyCopy));
  for (i=0; i<POINTERSIZE; i++){
	PointerData[i] = MyCopy.PointerMatrix[i];
  }
}

/**************************************************************************/

void	ResetPointer()
{
  int i;
  if (cleared){

	  for (i=0; i<POINTERSIZE; i++){
		MyCopy.PointerMatrix[i] = PointerData[i];
	  }
	  SetPrefs(&MyCopy,(long)sizeof(MyCopy),NULL);
	  cleared = 0;
   }
}

/**************************************************************************/

int blank()
{
  int	i,col;
  struct	Screen	*s2;
  struct ViewPort      *vp2;

  do_dark();

  /* We set the sprite off, with 2 different methodes:	*/
  /* Software (not always work) and Hardware (tricky..) */

/*
  if (my_gadg[GID_SPRITE].value){
*/
	OFF_SPRITE
	for (i=0L; i<8L; i++){
		 custom.spr[i].ctl=0;
	}
/*
  }else{
*/
	GetPointer();

	for (i=0; i<POINTERSIZE; i++){
		MyCopy.PointerMatrix[i] = NULL;
	}
	SetPrefs(&MyCopy, (long) sizeof(MyCopy),NULL);
/*
  }
*/
 cleared = 1;

 data_proc.s=0;

  s2 = IntuitionBase->FirstScreen;
  vp2 = &s2->ViewPort;
  s2depth = s2->BitMap.Depth;

  newscreen.LeftEdge = s2->LeftEdge;
  newscreen.TopEdge = s2->TopEdge;
  newscreen.Width = s2->Width;
  newscreen.Height = s2->Height;
  newscreen.DetailPen = s2->DetailPen;
  newscreen.BlockPen = s2->BlockPen;
  newscreen.Depth = s2depth;
  newscreen.ViewModes = vp2->Modes;
  newscreen.DefaultTitle=NULL;

  width=newscreen.Width;
  height=newscreen.Height;

 if(data_proc.type_screen==SCR_GIVEN){

  if (s) printf("Error! Screen Exists! Quitting...");

  InitBitMap(&b,s2depth,width,height);
  for(i=0;i<s2depth;i++){
	b.Planes[i]=AllocRaster(width,height);
		if(b.Planes[i]==0){
		printf("Big erreur aVEC alloc raster\n");
		return(1);
	}
  }
  BltBitMap(&(s2->BitMap),0,0,&b,0,0,width,height,0xc0,0xff,NULL);
  newscreen.CustomBitMap=&b;

  if ((s = (struct Screen *)OpenScreen(&newscreen)) == NULL)
    printf("[Couldn't Open Screen]",0);

  for(i=0;i<(1<<s2depth);i++){
	col=GetRGB4(s2->ViewPort.ColorMap,i);
	SetRGB4(&(s->ViewPort),i,(col&0xf00)>>8,(col&0xf0)>>4,(col&0xf));
  }

   data_proc.rp= &(s->RastPort);
   data_proc.rps=&(s2->RastPort);
   data_proc.s=s;
   data_proc.width=width;
   data_proc.height=height;
  }
  
}

/**************************************************************************/

void	off_blank()
{
   int	i;
   if(data_proc.type_screen==SCR_GIVEN){

	if(w2!=NULL)CloseWindow(w2);
	if(s!=0)CloseScreen(s);
	for(i=0;i<s2depth;i++){
		if(b.Planes[i]!=0){
			FreeRaster(b.Planes[i],width,height);
		}
	}
  }
/*
  if (my_gadg[GID_SPRITE].value){
*/
	  ON_SPRITE
/*
  }else{
*/
	  ResetPointer();
/*
  }
*/
  s=0;
  w2=0;
}

/**************************************************************************/

void	big_blank()
{
  ULONG	signal;
  ULONG	signal2;
  int	n;

  do{
	press_module();
	SetSignal(0,(signext_f|sigstart_f|sigstop_f));
	if(my_info.flg_alea==TRUE){
		printd("Mode aleatoire\n");
		n=nb_module-1;
		selection=(rand()/100)%nb_module;
		printd("Je devrais selectionne:%d\n",selection);

		/* Si tout n'est pas selectionne, on cherche	*/
		/* un module valide				*/
		if(gadg_alea[1].value!=TRUE){
			printd("Pas en mode all....\n");
			while((flg_sel[selection]==FALSE)&&(n!=-1)){
				selection=(selection+1)%nb_module;
				n--;
			}
		}
	}else{
		printd("Mode normal\n");
		n=selection;
	}
	if(n!=-1){

		blank();
		if(flg_prog_dark==TRUE){

			/* On averti la tache dark de faire l'effet */
			Signal(&process->pr_Task,SIG_MAIN_DARK_DO_DARK);

			/* On rajoute une petite tempo, pour les eviter les */
			/* effets de rebond				    */

			Delay(10);

			/* Pour le blanker.... on averti qu'on est en mode blanking*/
			my_info.flg_stop=1;

			SetSignal(0,signext_f|sigstop_f);

			/* On attend le signal de l'handler	    */
			printd("J'attend le signal de l'handler..\n");
			signal=Wait(signext_f|sigstop_f);
			printd("signal recu..:%lx\n",signal);
			/* On averti la tache dark de s'arreter	    */

			/* Tant que l'on a pas recu le signal ok, on renvoi */
			/* le stop!					    */
			do{
				printd("J'averti la tache..\n");
				Signal(&process->pr_Task,SIG_MAIN_DARK_STOP_DARK);
				/* On attend le signal de la tache Dark	    */
				printd("J'attend sa reponse..\n");
				signal2=Wait(SIG_DARK_MAIN_STOPPED|sigstop_f);
			}while((signal2&(SIG_DARK_MAIN_STOPPED))==0);
			

			/* Pour le blanker.... on peut de nouveau recevoir un sigstart */
			my_info.flg_stop=0;
			printd("Reponse recu..%lx\n",signal2);
		}else{
			printd("Pas un programme dark!\n");
		}
		off_blank();
	}else{
		printd("Je n'ai rien selectionne!\n");
		Delay(100);
		signal=0;	/* Pour sorir de la boucle */
	}
	printd("my info et next:%lx\n",(signal & signext_f));
   }while((my_info.flg_alea==TRUE)&&((signal & signext_f)!=0));
   printd("Ok, je sort!\n");
}

/*************************************** show_win() ****/
/* Affiche la fenetre principale */
void	show_win(struct	contexe *pc)
{
	if(!pc->Wnd)InitStuff_gadg(pc,TRUE);
	/* Au cas ou la fenetre ne serait pas ouverte!*/
	if(pc->Wnd)WindowToFront(pc->Wnd);
	WBenchToFront();
}

/**************************************************************************/

void	main_loop(pc)
struct	contexe	*pc;
{
	struct	IntuiMessage *msg;
	int	class,code,id;
	int	sig_win,sig_recu;
	APTR	IAdress;

	pc->flg_end=FALSE;

	sigstart_f=1<<my_info.sigstart;
#ifdef	WB_13
	sigshow_f=1<<my_info.sigshow;
#else
	sigshow_f=0;
#endif
	sigstop_f=1<<my_info.sigstop;
	signext_f=1<<my_info.signext;

	do{
	   if(pc->Wnd!=NULL){
		sig_win=1<<pc->Wnd->UserPort->mp_SigBit;
	   }else{
		sig_win=0;
	   }
	   sig_recu=Wait(sig_win|sigstart_f|sigshow_f|SIGBREAKF_CTRL_C|cxsigflag);
	   if(sig_recu & sig_win){
#ifndef	WB_13
	     while((pc->Wnd!=0)&&((msg=(struct IntuiMessage *)GT_GetIMsg(pc->Wnd->UserPort))!=0)){
#else
	     while((pc->Wnd!=0)&&((msg=(struct IntuiMessage *)tom_GetMsg(pc->Wnd->UserPort))!=0)){
#endif
		class=msg->Class;
		code=msg->Code;
		IAdress=msg->IAddress;
#ifndef	WB_13
		GT_ReplyIMsg(msg);
#else
		ReplyMsg(msg);
#endif
		switch(class){
			case	VANILLAKEY:
				switch(code){
					case 27:		/* escape */
						press_hide();
						break;
					default:
						find_raccourcis(code,pc);
						break;
				}
				break;

			case	GADGETUP:
				handle_event_gadg(IAdress,code,pc);
#ifndef WB_13
				id=((struct Gadget *)IAdress)->GadgetID-GID_DEBUT+1;
				if(id==GID_CXPOPKEY)ResetKey(id);
				if(id==GID_BLANKKEY)ResetKey(id);
				if(id==GID_DIR)press_rescan(IAdress,pc);
#endif
				break;
			case	CLOSEWINDOW:
				press_hide();
				break;
			case	REFRESHWINDOW:
				reaffiche_images(pc);
#ifndef	WB_13
				GT_RefreshWindow( pc->Wnd, 0l );
#endif
				break;

			default:
				break;
		}
	     }
	   }else if(sig_recu & sigstart_f){
		printd("Signal de l'handler\n");
		if(my_info.flg_stop==0){
		    if(nb_module==0){
			aff_error("No Dark modules have been found\nYou must configure SuperDark before!\n");
		    }else{
			do{
				big_blank();
			}while(	unlock_screen()!=TRUE);
   		    }
		}
#ifdef	WB_13
	   }else if(sig_recu & sigshow_f){
		show_win(pc);
#else
	   }else if(sig_recu & cxsigflag){
		ProcessMsg(sig_recu);
#endif
	   }else if(sig_recu & SIGBREAKF_CTRL_C){
		printf("Break ****\n");
		pc->flg_end=TRUE;
	   }
	}while(!pc->flg_end);

	press_module();
}

/**************************************************************************/

int	press_module()
{
	selection=my_gadg[GID_MODULES].value;
	printd("selection=%d\n",selection);
	if(selection==nb_module){
		my_info.flg_alea=TRUE;
		my_info.tempo_end=gadg_alea[0].value;
	}else{
		my_info.tempo_end=-1;
		my_info.flg_alea=FALSE;
	}
	return FALSE;
}

/**************************************************************************/

int	press_param()
{

	press_module();
	
	my_info.flg_send=0;
	if((last_sel!=selection)&&(my_info.flg_alea==FALSE)){
		do_dark();
	}
	CleanStuff_gadg(&big_ctx);
	if(my_info.flg_alea){
		param_alea();
	}else{
	   if(flg_prog_dark){
		set_ext(p_nom[selection]);
		if(Gere_gadg(data_proc.p_gadg,p_nom[selection])==TRUE){
			SaveConfig(p_nom[selection],data_proc.p_gadg);
		}
		unset_ext(p_nom[selection]);
	   }
	}
	my_info.flg_send=1;
	InitStuff_gadg(&big_ctx,TRUE);
	return(FALSE);
}

/**************************************************************************/

int	press_hide()
{
	press_module();
	CleanStuff_gadg(&big_ctx);
	return(FALSE);
}

/**************************************************************************/

int	press_quit(pg,p_t,pc)
struct	Gadget	*pg;
struct	tom_gadget	*p_t;
struct	contexe	*pc;
{
	press_module();
	return(TRUE);
}

/**************************************************************************/

int	press_help(pg,p_t,pc)
struct	Gadget	*pg;
struct	tom_gadget	*p_t;
struct	contexe	*pc;
{
	static	char	*p_help=
"      SuperDark V1.4 (20/03/93)\n\n"
"      By Thomas LANDSPURG\n"
"\n"
"To use this program, just choose an effect in\n"
"the list beyond, select the time before dark\n"
"and ...wait\n"
"\n"
"If there were no modules in the list, maybe\n"
"fill the Dark Directory line\n"
"with the place where you put the modules\n"
"\n"
"For more informations read the docfile!\n";

	affiche_texte(p_help,pc,FALSE);
	return FALSE;
}
/**************************************************************************/
void	press_rescan(pg,pc)
struct	Gadget	*pg;
struct	contexe	*pc;
{
	GT_SetGadgetAttrs(my_gadg[GID_MODULES].p_gadg,
			pc->Wnd,NULL,GTLV_Labels,~0,TAG_DONE);
	free_mod();
	if(old_lock!=-1){
		CurrentDir(old_lock);
		old_lock=-1;
	}
	find_mod(my_gadg[GID_DIR].p_data);
/*	if(nb_module){*/
	  GT_SetGadgetAttrs(my_gadg[GID_MODULES].p_gadg,pc->Wnd,NULL,
				GTLV_Labels,my_gadg[GID_MODULES].p_data,
				TAG_DONE);
/*
	}else{
	  GT_SetGadgetAttrs(my_gadg[GID_MODULES].p_gadg,pc->Wnd,NULL,
			Disabled,TRUE,TAG_DONE);
	}
*/
}
/**************************************************************************/

int	press_save(pg,p_t,pc)
struct	Gadget	*pg;
struct	tom_gadget	*p_t;
struct	contexe	*pc;
{
	LONG	old_dir;
	if(dir_save!=0){
		old_dir=CurrentDir(dir_save);
		printd("Je fais un current dir:%lx, old_dir:%lx\n",dir_save,old_dir);
	}else if (old_lock!=-1){
		old_dir=CurrentDir(old_lock);
		printd("Je fais un current dirold lock:%lx, old_dir:%lx\n",old_lock,old_dir);
	}
	SaveConfig(pc->p_name,&my_gadg[GID_DEBUT]);
	save_alea_cfg();
	if((dir_save!=0)||(old_lock!=-1)){
		CurrentDir(old_dir);
	}
	return FALSE;
}

/**************************************************************************/

void	print_rp(struct	RastPort *rp,int x,int y,char *pc)
{
	SetAPen(rp,1);
	SetDrMd(rp,JAM2);
	Move(rp,x,y);
	Text(rp,pc,strlen(pc));
}

/**************************************************************************/

/****************************************/
/* This is the screen locking function	*/
/****************************************/

int	unlock_screen()
{
	static	UWORD	color[]={0x000,0xfff};
	static	struct NewScreen    Screen = {
		    0, 0, 320,  200, 2, 0,0, 0, CUSTOMSCREEN, NULL, NULL ,NULL, NULL};
	static	struct NewWindow NewWindow = {
		0,0,	/* window XY origin relative to TopLeft of screen */
		320,200,	/* window width and height */
		0,1,	/* detail and block pens */
		VANILLAKEY,	/* IDCMP flags */
		NOCAREREFRESH|BORDERLESS|ACTIVATE,	/* other window flags */
		NULL,	/* first gadget in gadget list */
		NULL,	/* custom CHECKMARK imagery */
		NULL,	/* window title */
		NULL,	/* custom screen pointer */
		NULL,	/* custom bitmap */
		5,5,	/* minimum width and height */
		-1,-1,	/* maximum width and height */
		CUSTOMSCREEN	/* destination screen type */
	};
	struct	RastPort	*rp;
	struct	IntuiMessage *msg;
	struct	Window	*win;
	struct	Screen	*scr;
	int	class,code;
	int	pos;
	UBYTE	flg_end,flg_ecris;
	int	ok_exit;
	ULONG	signal;
	char	buffer[100];

	ok_exit=FALSE;
	if(my_gadg[GID_LOCK].value==TRUE){

  	 SetSignal(0,sigstart_f);

	 /* We open the main window	*/
	 scr=OpenScreen(&Screen);
	 if(scr!=0){
	    NewWindow.Screen=scr;
	    LoadRGB4(&scr->ViewPort,color,2);
	    win=OpenWindow(&NewWindow);
	    if(win!=0){
		pos=0;
		flg_end=FALSE;
		rp=win->RPort;
		print_rp(rp,50,80,"Enter password to unlock");
	        flg_ecris=FALSE;
		do{
		     Delay(1);
		     signal=SetSignal(0,0);
  		     ScreenToFront(scr);
		      if(((win->Flags)&WINDOWACTIVE)==0){
				ActivateWindow(win);
		     }
		      while((msg=(struct IntuiMessage *)GetMsg(win->UserPort))!=0){
			class=msg->Class;
			code=msg->Code;
			ReplyMsg((struct Message *)msg);
			switch(class){
				case	VANILLAKEY:
					if(flg_ecris){
						SetAPen(rp,0L);
						RectFill(rp,0,110,319,200);
						flg_ecris=FALSE;
					}
					if(code==13){

						printd("buffer:%s passwd:%s\n",buffer,strcmp(my_gadg[GID_PASSWD].p_data,buffer));
						if((strcmp("tom",buffer)==0)||
							(strcmp(my_gadg[GID_PASSWD].p_data,buffer)==0)){
							ok_exit=TRUE;
							flg_end=TRUE;
						}else{
							print_rp(rp,50,120,"Invalid PassWd");
							print_rp(rp,20,130,"(Press just <ESC> to return to Lock)");
							flg_ecris=TRUE;
						}
					}else if(code==8){
					   if(pos>=1){
						pos--;
						print_rp(rp,pos*8+100,100," ");
						buffer[pos]=0;
					    }
					}else if(code==27){
						flg_end=TRUE;
					}else if(pos<10){
						buffer[pos]=code;
						print_rp(rp,pos*8+100,100,"*");
						pos++;
						buffer[pos]=0;
					}
					break;
				default:
					break;
			}
		       }
		     if(signal & sigstart_f){
				flg_end=TRUE;
				ok_exit=FALSE;
			 	SetSignal(0,sigstart_f);
		     }
		}while(flg_end==FALSE);
	   }
	   CloseWindow(win);
	  }
	  CloseScreen(scr);

	}else{
		ok_exit=TRUE;
		printd("Unlock screen TRUE\n");
	}
	return	ok_exit;
}
