/*
		Find CON: window pointer and set its font
		by A. Finkel, R. Burns, and M. McInerny
		)1986 by Commodore-Amiga and M. McInerny.
*/

#include	"exec/types.h"
#include	"exec/nodes.h"
#include	"exec/ports.h"
#include	"exec/io.h"
#include	"exec/memory.h"
#include	"devices/console.h"
#include	"devices/conunit.h"
#include	"libraries/dos.h"
#include	"libraries/dosextens.h"
#include	"intuition/intuitionbase.h"
#include	"workbench/startup.h"
#include	"workbench/workbench.h"
#include	"graphics/rastport.h"
#include	"graphics/text.h"
#include	"libraries/diskfont.h"

extern struct Library *OpenLibrary();
extern struct TextFont *OpenDiskFont();

struct IntuitionBase *IntuitionBase = 0;
long GfxBase = 0;
long DiskfontBase = 0;
struct TextFont *font;

struct MsgPort iorp = {
	{0, 0, NT_MSGPORT, 0, 0}, 0,
	-1,				/* initialize signal to -1 */
	0,				/* start with empty list */
	{(struct Node *)&iorp.mp_MsgList.lh_Tail, 0, 
	 (struct Node *)&iorp.mp_MsgList.lh_Head, 0, 0}
};
struct IOStdReq ior = {
	{{0, 0, 0, 0, 0}, &iorp, 0},
	0				/* device is zero */
};

void OpenLibs()
{
	GfxBase = (long)OpenLibrary("graphics.library", 0);
	if (GfxBase == NULL) {
		printf("Graphics library open failed.\n");
		cleanup(20);
	}

	if ((IntuitionBase = (struct IntuitionBase *)
				OpenLibrary("intuition.library", 0)) == 0) {
		cleanup(21);
	}

	DiskfontBase = (long)OpenLibrary("diskfont.library", 0);
	if (DiskfontBase == NULL) {
		printf("Diskfont library open failed.\n");
		cleanup(25);
	}

}

struct Window *GetWindow()
{
	struct MsgPort *con;
	struct StandardPacket *packet = 0;
	struct InfoData *id = 0;
	struct Window *windw = 0;

	/* open the console device, returns address of device handler */
	if ((OpenDevice("console.device", -1, &ior, 0)) != 0) {
		cleanup(30);
	}

	/* set up the message port in the I/O request */
	if ((iorp.mp_SigBit = AllocSignal(-1)) < 0) {
		cleanup(35);
	}

	/* which task am I? */
	iorp.mp_SigTask = (struct Task *) FindTask((char *) NULL);

	/* Try to find the console associated with calling process */
	if (iorp.mp_SigTask->tc_Node.ln_Type == NT_PROCESS) {
	   con = (struct MsgPort *)
		  ((struct Process *) iorp.mp_SigTask)->pr_ConsoleTask;
	   if (con != 0) {
 	     if (packet = (struct StandardPacket *)
			   AllocMem(sizeof(*packet), MEMF_CLEAR)) {
	       if (id = (struct InfoData *)AllocMem(sizeof(*id), MEMF_CLEAR)) {
		 /* This is the console handlers packet port. */
		 packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
		 packet->sp_Pkt.dp_Link = (struct Message *)&(packet->sp_Pkt);
		 packet->sp_Pkt.dp_Port = &iorp;
		 packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
		 packet->sp_Pkt.dp_Arg1 = ((ULONG) id) >> 2; /* #@!% BPTR! */
		 PutMsg(con, packet);
		 WaitPort(&iorp);
		 windw = (struct Window *) (id->id_VolumeNode);
		 FreeMem(id, sizeof(*id));
	       }
	       FreeMem(packet, sizeof(*packet));
	     }
	  }
	}
	ior.io_Unit = (struct Unit *) -1;
	return(windw);
}

cleanup(code)
int code;
{
	if (ior.io_Device != 0) {
		if (iorp.mp_SigBit != -1) {
			FreeSignal(iorp.mp_SigBit);
		}
		CloseDevice(&ior);
	}
	if (font) CloseFont(font);
	if (DiskfontBase) CloseLibrary(DiskfontBase);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
	if (GfxBase) CloseLibrary(GfxBase);

	exit(code);
}

main(argc, argv)
int argc;
char *argv[];
{
	struct TextAttr *ta = 0;
	struct TextAttr *old_ta;
	struct TextFont *oldfont;
	struct Window *win;
	struct RastPort *rp;
	int fontsize = 8;
	char *fontname;
	int	i,
		screen_flag = 0,
		rast_flag = 0;

	if (*argv[1] == '?')
	{	
		printf(
"Usage:  %s [fontname=topaz [fontsize=8]] [-s=set screen] [-r=set rastport]\n",
			argv[0]);
		printf("v1.1 )1986 by M. McInerny and Commodore-Amiga.\n");
		cleanup(10);
	}

#define FBUFSIZE 40 
	fontname = (char *)AllocMem(FBUFSIZE, MEMF_CLEAR);
	if (argc>1) {
		fontname = (char *)strncpy(fontname, argv[1], FBUFSIZE);
		fontname = (char *)strncat(fontname, ".font", FBUFSIZE);
	} else {
		fontname = (char *)strncpy(fontname, "topaz.font", FBUFSIZE);
		screen_flag = 1;	/* restore the screen to normal */
		rast_flag = 1;
	}

	if ((argc>2) && (*argv[2] != '-')) fontsize = atoi(argv[2]);

	for (i = 1; i < argc; ++i)
		if (*argv[i] == '-')
			switch (*(argv[i]+1)) {
				case 's': screen_flag = 1; break;
				case 'r': rast_flag = 1; break;
			}
	OpenLibs();

	ta = (struct TextAttr *)AllocMem(sizeof(*ta), MEMF_CLEAR);
	ta->ta_Name =  fontname;
	ta->ta_YSize = fontsize;
	ta->ta_Style = 0;
	ta->ta_Flags = FPF_DISKFONT;

	font = OpenDiskFont(ta);
	if (font == 0)
	{
		printf("OpenDiskFont failed--font not found?\n");
 		cleanup(27);
	}

	win = GetWindow();
	if (!win) cleanup(40);

	if (screen_flag == 1) {
		old_ta = win->WScreen->Font;
		win->WScreen->Font = ta;
		FreeMem(old_ta, sizeof(old_ta));
	} else FreeMem(ta, sizeof(ta));

	if (rast_flag == 1) {
		rp = &(win->WScreen->RastPort);
		oldfont =  rp->Font;
		if (SetFont(rp, font) != 0)
			CloseFont(oldfont);
	}

	rp = win->RPort;
	oldfont = rp->Font;
	/* If the SetFont() works, on cleanup, CloseFont(oldfont) */
	if (SetFont(rp, font) != 0) {
		font = oldfont;
		printf("\033c");
	}
	cleanup(0);
}


