; /*
dcc aguide.c dlib:start.o -lagstub -r -o AGuide
quit ; */
/*
**	AGuide.c - an alternative to the original C= AmigaGuide frontend
**	Written & (c) 1994 by AEsoftwares. Freeware.
**
**	Compile info: compile with DICE V2.##.## as
**		dcc start.c aguide.c -lagstub -r -o AGuide
**	Create - if necessary - agstubs.lib with
**		fdtolib amigaguide_lib.fd -o agstubs.lib
**
**	Revision history:
**
**	V1.0 [16/05/94]  Initial release
*/

#include <string.h>
#include <pd/start.h>
#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <graphics/displayinfo.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <libraries/amigaguide.h>
#include <libraries/asl.h>
#include <utility/tagitem.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/icon_protos.h>
#include <clib/amigaguide_protos.h>
#include <clib/asl_protos.h>

#define PROGNAME "AGuide"
#define VERSION  "1.0"
#define REVDATE  "16.5.94"

#define MAXNAMELEN 512

const char versiontag[] = "$VER: " PROGNAME " " VERSION " (" REVDATE ")";

struct args {
	UBYTE *file;
	UBYTE *pubscr;
	UBYTE *ownscr;
	UBYTE *port;
	void (*error)(UBYTE *);
};

struct Library *AmigaGuideBase;

BOOL fileexists(UBYTE *name) {
	BPTR dummylock;

	if (dummylock = Lock(name, ACCESS_READ)) {
		UnLock(dummylock);
		return 1;
	} else {
		return 0;
	}
}

LONG mymain(struct args *args) {
	LONG res = 0;

	if (!args->file) {
		struct FileRequester *aslreq;
		static UBYTE name[MAXNAMELEN];

		if (aslreq = AllocAslRequestTags(ASL_FileRequest,
				ASL_Hail, (ULONG)PROGNAME " - Select file to view",	TAG_DONE)
		) {
			if (AslRequestTags(aslreq, TAG_DONE)) {
				strncpy(name, aslreq->rf_Dir, MAXNAMELEN - 1);
				name[MAXNAMELEN - 1] = 0;
				if (AddPart(name, aslreq->rf_File, MAXNAMELEN - 1)) {
					args->file = name;
					if (!fileexists(args->file)) {
						args->file = 0;
					}
				}
			}
			FreeAslRequest(aslreq);
		}
	}

	if (args->file) {
		if (AmigaGuideBase = OpenLibrary("amigaguide.library", 34)) {
			UBYTE pubsig = -1;
			struct Screen *scr;
			struct NewAmigaGuide nag = {
				0, 0, 0, 0, 0, args->port, PROGNAME, 0, 0, 0, 0, 0, 0
			};
			AMIGAGUIDECONTEXT aghandle;

			if (args->ownscr) {
				ULONG modeID;
				UWORD dummypens[] = {~0};
				struct TagItem ostags[] = {
					SA_DisplayID, 0,
					SA_Type, 0,
					SA_Title, 0,
					SA_PubName, 0,
					SA_PubSig, 0,
					SA_Pens, (ULONG) dummypens,
					SA_Depth, 2,
					TAG_DONE
				};
				UBYTE *tail;

				modeID = strtol(args->ownscr, &tail, 0);
				if (*tail) {
					ULONG lastID = INVALID_ID;
					BOOL finished = 0;
					struct NameInfo nameInfo;

					do {
						if ((modeID = NextDisplayInfo(lastID)) == INVALID_ID) {
							finished = 1;
						} else {
							lastID = modeID;
							if (GetDisplayInfoData(0, (APTR)&nameInfo,
									sizeof(nameInfo), DTAG_NAME, modeID)) {
								finished = !stricmp(nameInfo.Name, args->ownscr);
							}
						}
					} while (!finished);
				}
				if (modeID == INVALID_ID) {
					struct Screen *wbscr;

					if (wbscr = LockPubScreen(0)) {
						modeID = GetVPModeID(&(wbscr->ViewPort))	;
						UnlockPubScreen(0, wbscr);
					} else {
						modeID = HIRES_KEY;
					}
				}
				ostags[0].ti_Data = modeID;
				if (args->pubscr) {
					ostags[1].ti_Data = PUBLICSCREEN;
					ostags[2].ti_Data = ostags[3].ti_Data = args->pubscr;
					pubsig = AllocSignal(-1);
					ostags[4].ti_Data =
							(pubsig != -1) ? pubsig : SIGBREAKB_CTRL_C;
				} else {
					ostags[1].ti_Data = CUSTOMSCREEN;
					ostags[2].ti_Data = (ULONG)
							PROGNAME " V" VERSION " by AEsoftwares";
					ostags[3].ti_Tag = ostags[4].ti_Tag = TAG_IGNORE;
				}
				if (scr = OpenScreenTagList(0, ostags)) {
					PubScreenStatus(scr, 0);
				} else {
					args->error("Cannot open screen");
					res = 10;
				}
			} else {
				if (args->pubscr && (scr = LockPubScreen(args->pubscr))) {
					ScreenToFront(scr);
					UnlockPubScreen(0, scr);
				}
				scr = 0;
			}
			nag.nag_Screen = scr;
			nag.nag_PubScreen = args->ownscr ? 0 : args->pubscr;
			nag.nag_Name = args->file;
			if (aghandle = OpenAmigaGuide(&nag, 0)) {
				CloseAmigaGuide(aghandle);
			} else {
				args->error("Cannot invoke AmigaGuide");
				res = 10;
			}
			if (scr) {
				while (!CloseScreen(scr)) {
					Wait((pubsig != -1) ? 1<<pubsig : SIGBREAKF_CTRL_C);
				}
			}
			if (pubsig != -1) {
				FreeSignal(pubsig);
			}
		} else {
			args->error("Cannot open amigaguide.library");
			res = 10;
		}
	} else {
		res = 10;
	}
	return res;
}

void putstr(UBYTE *msg) {

	PutStr(msg);
	PutStr("\n");
}

LONG clistart(ULONG len, UBYTE *ptr) {
	UBYTE *templ = "DATABASE,PS=PUBSCREEN/K,OS=OWNSCREEN/K,PN=PORTNAME/K";
	LONG buf[] = {0, 0, 0, 0};
	struct RDArgs *rda;
	struct args args;
	LONG res;
	static UBYTE name[MAXNAMELEN];

	args.error  = &putstr;
	if (rda = ReadArgs(templ, buf, 0)) {
		args.file   = (UBYTE *) buf[0];
		args.pubscr = (UBYTE *) buf[1];
		args.ownscr = (UBYTE *) buf[2];
		args.port   = (UBYTE *) buf[3];

		if (args.file) {
			strncpy(name, args.file, MAXNAMELEN - 7);
			name[MAXNAMELEN - 7] = 0;
			strcat(name, ".guide");
			if (fileexists(name)) {
				args.file = name;
			} else if (!fileexists(args.file)) {
				args.file = 0;
			}
		}

		res = mymain(&args);
		FreeArgs(rda);
	} else {
		args.error("Bad args");
		res = 10;
	}

	Flush(Output());	
	return res;
}

void req(UBYTE *msg) {
	struct EasyStruct easy = {
		sizeof(struct EasyStruct), 0, PROGNAME " error", msg, "OK"
	};

	EasyRequest(0, &easy, 0, 0);
}

void wbstart(struct WBStartup *msg) {
	struct args args;
	struct DiskObject *dobj;
	BPTR oldCD;

	args.error = &req;

	if (msg->sm_NumArgs == 1) {
		args.file = 0;
	} else {
		args.file = msg->sm_ArgList[msg->sm_NumArgs - 1].wa_Name;
	}

	oldCD = CurrentDir(msg->sm_ArgList[msg->sm_NumArgs - 1].wa_Lock);
	if (dobj = GetDiskObjectNew(msg->sm_ArgList[msg->sm_NumArgs - 1].wa_Name)) {
		args.pubscr = FindToolType(dobj->do_ToolTypes, "PUBSCREEN");
		args.ownscr = FindToolType(dobj->do_ToolTypes, "OWNSCREEN");
		args.port   = FindToolType(dobj->do_ToolTypes, "PORTNAME");
	} else {
		args.pubscr = 0;
		args.ownscr = 0;
		args.port   = 0;
	}
	mymain(&args);
	if (dobj) {
		FreeDiskObject(dobj);
	}
	CurrentDir(oldCD);
}

/* END OF AGuide.c */
