/* PopDir v1.5 © Copyright 1989 Jonathan Potter */

#include "PopDir.h"

void closeup();

main()
{
	struct Gadget *Gadget;
	int GadgetID,whichwin,file,x,y,a,Class,ox=31,oy=11;
	ULONG prevsec=0,prevmic=0,sec,mic;

	IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0);
	GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0);
	if (!(finfo=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),
		MEMF_CHIP|MEMF_CLEAR))) closeup();
	if (!(Window=(struct Window *) OpenWindow(&small))) closeup();
	whichwin=1;
	for (;;) {
		if (whichwin==2) ActivateGadget(&StrGad,Window);
		Wait(1<<Window->UserPort->mp_SigBit);
		while (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) {
			Class=Msg->Class; sec=Msg->Seconds; mic=Msg->Micros;
			if (Class==GADGETDOWN || Class==GADGETUP) {
				Gadget=(struct Gadget *) Msg->IAddress;
				GadgetID=Gadget->GadgetID;
			}
			ReplyMsg((struct Message *) Msg);
			switch (Class) {
				case INACTIVEWINDOW:	
					if (Window->LeftEdge!=ox && Window->LeftEdge!=small.LeftEdge)
						small.LeftEdge=Window->LeftEdge;
					if (Window->TopEdge!=oy && Window->TopEdge!=small.TopEdge)
						small.TopEdge=Window->TopEdge;
					CloseWindow(Window);
					if (!(Window=(struct Window *) OpenWindow(&small))) closeup();
					whichwin=1;
					break;

				case CLOSEWINDOW:
					CloseWindow(Window);
					if (whichwin==2) closeup();
					if (!(Window=(struct Window *) OpenWindow(&med))) closeup();
					SetWindowTitles(Window,-1,titlestring);
					whichwin=2;
					break;

				case GADGETUP:
				case GADGETDOWN:
					if (whichwin==1) {
						if (!(DoubleClick(prevsec,prevmic,sec,mic))) {
							prevsec=sec; prevmic=mic;
							break;
						}
						small.LeftEdge=Window->LeftEdge;
						small.TopEdge=Window->TopEdge;
						if (Window->LeftEdge+med.Width>Window->WScreen->Width)
							med.LeftEdge=Window->WScreen->Width-med.Width;
						else med.LeftEdge=Window->LeftEdge;
						if (Window->TopEdge+med.Height>Window->WScreen->Height)
							med.TopEdge=Window->WScreen->Height-med.Height;
						else med.TopEdge=Window->TopEdge;
						ox=med.LeftEdge; oy=med.TopEdge;
						CloseWindow(Window);
						if (!(Window=(struct Window *) OpenWindow(&med))) closeup();
						SetWindowTitles(Window,-1,titlestring);
						whichwin=2;
						break;
					}
					if (GadgetID>1 && GadgetID<14) {
						sprintf(dobuffer,Gadget->GadgetText->IText);
						RefreshGList(&StrGad,Window,NULL,1);
						break;
					}
					else if (GadgetID==14) {
						do_parent();
						RefreshGList(&StrGad,Window,NULL,1);
						break;
					}
					if (dobuffer[(strlen(dobuffer)-1)]!='/' &&
						dobuffer[(strlen(dobuffer)-1)]!=':')
						strcat(dobuffer,'/');
					whichwin=3;
					med.LeftEdge=Window->LeftEdge;
					med.TopEdge=Window->TopEdge;
					CloseWindow(Window);
					if (!(Window=(struct Window *) OpenWindow(&big))) closeup();
					SetWindowTitles(Window,dobuffer,titlestring);
 					if ((lock=(struct FileLock *) Lock(dobuffer,ACCESS_READ))==0) {
						sprintf(ToPrint,"Can't lock requested directory!");
						PrintIText(Window->RPort,&Files,10,12);
						sprintf(ToPrint,"Click on Close Gadget to continue");
						WriteStatus();
						goto finalquit;
					}
					Examine(lock,finfo);
					file=0; y=12; x=10; a=0;
					if (finfo->fib_DirEntryType<0) {
						sprintf(ToPrint,"%-30s",finfo->fib_FileName);
						PrintIText(Window->RPort,&Files,x,y);
						sprintf(ToPrint,"%-7d",finfo->fib_Size);
						PrintIText(Window->RPort,&Files,x+242,y);
						sprintf(ToPrint,"Click on Close Gadget to continue");
						WriteStatus();
						goto finalquit;;
					}
					oldlock=(struct FileLock *) CurrentDir(lock);
					Forbid(); 
					while ((ExNext(lock,finfo))!=0) {
						a=1;
						if (file==0) {
							sprintf(ToPrint,"Reading directory.. Close gadget to cancel");
							WriteStatus();
						}
						if (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) {
							Class=Msg->Class;
							ReplyMsg((struct Message *) Msg);	
							if (Class==CLOSEWINDOW) {
								CloseWindow(Window);
								if (!(Window=(struct Window *) OpenWindow(&med))) closeup();
								SetWindowTitles(Window,-1,titlestring);
								whichwin=2;
								goto quit;
							}
						}
						if (finfo->fib_DirEntryType>0)
							Files.FrontPen=3;
						sprintf(ToPrint,"%-30s",finfo->fib_FileName);
						PrintIText(Window->RPort,&Files,x,y);
						if (finfo->fib_DirEntryType<0) {
							sprintf(ToPrint,"%-7d",finfo->fib_Size);
							PrintIText(Window->RPort,&Files,x+242,y);
						}
						Files.FrontPen=1; 
						if (x==10) x=330;
						else {
							x=10;
							y+=8;
						}
						++file;
						if (file>43) {
							sprintf(ToPrint,"Press any key to continue, or click on Close Gadget to cancel");
							WriteStatus();
							Wait(1<<Window->UserPort->mp_SigBit);
							while (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) {	
								Class=Msg->Class;
								ReplyMsg((struct Message *) Msg);
								if (Class==CLOSEWINDOW) {
									CloseWindow(Window);
									if (!(Window=(struct Window *) OpenWindow(&med))) closeup();
									SetWindowTitles(Window,-1,titlestring);
									whichwin=2;
									goto quit;
								}
							}
							SetAPen(Window->RPort,0);
							RectFill(Window->RPort,9,10,637,198);
							file=0; y=12; x=10;
						}
					}
					if (a==0) {
						sprintf(ToPrint,"Requested directory is empty");
						PrintIText(Window->RPort,&Files,10,12);
					}
					sprintf(ToPrint,"Click on close gadget to continue");
					WriteStatus();
					quit:
					Permit();
					CurrentDir(oldlock);
					UnLock(lock);
					finalquit:
					break;

				default:
					break;
			}
		}
	}
}

WriteStatus()
{
	SetAPen(Window->RPort,0);
	RectFill(Window->RPort,2,189,637,198);
	Files.FrontPen=3;
	PrintIText(Window->RPort,&Files,10,189);
	Files.FrontPen=1;
	return(0);
}

do_parent()
{
	int i,b;
	if (strlen(dobuffer)==0) return(0);
	i=strlen(dobuffer)-1;
	if (dobuffer[i]==':') return(0);
	if (dobuffer[i]=='/') --i;
	for (b=i;b>-1;b--) if (dobuffer[b]=='/' || dobuffer[b]==':') break;
	if (dobuffer[b]==':') dobuffer[++b]='\0';
	if (b<0) b=0;
	dobuffer[b]='\0';
}

void closeup()
{
	if (finfo) FreeMem(finfo,sizeof(struct FileInfoBlock));
	CloseLibrary((struct Library *) IntuitionBase);
	CloseLibrary((struct Library *) GfxBase);
	OpenWorkBench();
	exit(0);
}
