#include "PostPre.h"
#include "PostWin.h"
#include "Global.h"

char	hailfilef[]		= "Select font to load";
char	hailfilen[]		= "Select file to load";
char	hailfiles[]		= "Select file to run";
char	useopts[3][15] = {"ENV:POST","ENV:POST.iff","ENV:POST.print"};
char	saveopts[3][20]= {"ENVARC:POST","ENVARC:POST.iff","ENVARC:POST.print"};
char	command[256], newpubscreenname[MAXPUBSCREENNAME+1];

int	next_page_number, opt_number;

struct	Requester sleep_req;
struct	List	NewPubScrList;
struct	PubScrContext newpubscrcontext = {NULL, FALSE, FALSE, FALSE};


void	sleep_OutputWnd(void)
{
	if(OutputWnd == NULL) return;
	ModifyIDCMP(OutputWnd, IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE |
		IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_MENUPICK | IDCMP_CLOSEWINDOW |
		IDCMP_MOUSEMOVE | IDCMP_SIZEVERIFY | IDCMP_ACTIVEWINDOW |
		IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW | IDCMP_IDCMPUPDATE |
		IDCMP_RAWKEY | IDCMP_VANILLAKEY);
	InitRequester(&sleep_req);
	Request(&sleep_req, OutputWnd);
	if(os_3) SetWindowPointer(OutputWnd, WA_BusyPointer, TRUE, WA_PointerDelay, TRUE, TAG_DONE);
}

void	awake_OutputWnd(void)
{
	if(OutputWnd == NULL) return;
	ModifyIDCMP(OutputWnd, IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE |
		IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_MENUPICK | IDCMP_CLOSEWINDOW |
		IDCMP_MOUSEMOVE | IDCMP_SIZEVERIFY | IDCMP_ACTIVEWINDOW |
		IDCMP_INACTIVEWINDOW | IDCMP_MENUVERIFY | IDCMP_CHANGEWINDOW |
		IDCMP_IDCMPUPDATE | IDCMP_RAWKEY | IDCMP_VANILLAKEY);
	EndRequest(&sleep_req, OutputWnd);
	if(os_3) SetWindowPointer(OutputWnd, WA_Pointer, NULL, TAG_DONE);
}

int MenuNew( void )
{
	/* routine when (sub)item "New" is selected. */

	int	retc;

	opt_number = MENU_NEW;
	if(OpenOptionsWindow()) 
	{
		okmsg("can't open options window!");
		CloseOptionsWindow();
		return(0);
	}
	sleep_OutputWnd();
	SetWindowTitles(OptionsWnd, "Options for the new Post Window", "Options for the new Post Window");
	copy_options(&TempOptions, &NewOptions);
	setoptionsgadgets(MENU_NEW);
	for(;;)
	{
		WaitPort(OptionsWnd->UserPort);
		retc = HandleOptionsIDCMP();
		if(retc == Options_CANCEL || retc == Options_OK) break;
	}
	CloseOptionsWindow();
	awake_OutputWnd();
	if(retc == Options_OK)
	{
		copy_options(&NewOptions, &TempOptions);
		sprintf(command, "run > NIL: POST:Post PUBSCREEN %s OPTFILE ENV:POST",
					Options.Screen.custscreen ? postpubscrname : pubscreenname);
		SystemTagList(command, TAG_END);
	}
	return(0);
}

int MenuClear( void )
{
	/* routine when (sub)item "Clear" is selected. */


	saveterminate();
	sendmenu(PSACTCLEAR, 0, 0, 0, NULL, NULL);
	Wait(1L << create_signal);
	if(createerror)
	{
		errorende();
		exit(10);
	}
	runstartupfiles();
	return(0);
}

int MenuOpen( void )
{
	/* routine when (sub)item "Open File..." is selected. */

	filereq = filerequester;
	if (AslRequestTags(filereq,
		ASLFR_TitleText,	(ULONG) hailfilen,
		ASLFR_Window,		(ULONG) OutputWnd,
		TAG_DONE) == NULL) return(0);
	getfullfilename(Options.lastfile, filereq->rf_Dir, filereq->rf_File);
	sendfile(PSACTFILE);
	return(0);
}

int MenuRun( void )
{
	/* routine when (sub)item "Run File ..." is selected. */

	filereq = filerequester;
	if (AslRequestTags(filereq,
		ASLFR_TitleText,	(ULONG) hailfiles,
		ASLFR_Window,		(ULONG) OutputWnd,
		TAG_DONE) == NULL) return(0);
	getfullfilename(Options.lastfile, filereq->rf_Dir, filereq->rf_File);
	sendfile(PSACTRUN);
	return(0);
}

int MenuFont( void )
{
	/* routine when (sub)item "Load Font ..." is selected. */

	filereq = fontrequester;
	if (AslRequestTags(filereq,
		ASLFR_InitialPattern,	(ULONG) "~(#?.afm|#?.info)",
		ASLFR_InitialDrawer,		(ULONG) "PSFONTS:",
		ASLFR_InitialFile, 		(ULONG) "",
		ASLFR_InitialHeight, 	300,
		ASLFR_TitleText,			(ULONG) hailfilef,
		ASLFR_DoSaveMode,			FALSE,
		ASLFR_Window,				(ULONG) OutputWnd,
		TAG_DONE) == NULL) return(0);
	getfullfilename(Options.lastfile, filereq->rf_Dir, filereq->rf_File);
	sendfile(PSACTFONT);
	return(0);
}

int MenuIff( void )
{
	/* routine when (sub)item "Save As Iff ..." is selected. */

	int	retc;

	if(running == FALSE)
	{
		filereq = filerequester;
		if (AslRequestTags(filereq,
			ASLFR_TitleText,	(ULONG) "Select file to save ...",
			ASLFR_Window,		(ULONG) OutputWnd,
			TAG_DONE) == NULL) return(0);
		strcpy(Options.lastdir, filereq->rf_Dir);
		getfullfilename(Options.lastfile, filereq->rf_Dir, filereq->rf_File);
		number_of_pages = splitpage(Options.lastfile);
	}
	opt_number = MENU_IFF;
	if(OpenOptionsWindow()) 
	{
		okmsg("can't open options window!");
		CloseOptionsWindow();
		return(0);
	}
	sleep_OutputWnd();
	SetWindowTitles(OptionsWnd, "Options for the IFF-File", "Options for the IFF-File");
	copy_options(&TempOptions, &IffOptions);
	if(number_of_pages == 0)
	{
		TempOptions.PostOpts.bandrendering = FALSE;
		TempOptions.PostOpts.allpages = TRUE;
		TempOptions.PostOpts.from = 0;
		TempOptions.PostOpts.to = 0;
	}
	else
	{
		TempOptions.PostOpts.from = 1;
		TempOptions.PostOpts.to = number_of_pages;
	}
	setoptionsgadgets(MENU_IFF);
	GT_SetGadgetAttrs(OptionsGadgets[GD_OptGetIff], OptionsWnd, NULL,
		GA_Disabled, FALSE, TAG_DONE);
	GT_SetGadgetAttrs(OptionsGadgets[GD_OptIff], OptionsWnd, NULL,
		GA_Disabled, FALSE, TAG_DONE);
	for(;;)
	{
		WaitPort(OptionsWnd->UserPort);
		retc = HandleOptionsIDCMP();
		if(retc == Options_CANCEL || retc == Options_OK) break;
	}
	CloseOptionsWindow();
	awake_OutputWnd();
	if(retc == Options_OK)
	{
		copy_options(&IffOptions, &TempOptions);
		sprintf(command, "run >nil: POST:Post IFF %s OPTFILE ENV:POST.iff FILE %s PUBSCREEN %s CONWIN VERBOSE",
					(char *) &(TempOptions.PostOpts.iffname), Options.lastfile, Options.Screen.custscreen ? postpubscrname : pubscreenname);
		SystemTagList(command, TAG_END);
	}
	return(0);
}

int MenuPrint( void )
{
	/* routine when (sub)item "Print ..." is selected. */

	int	retc;

	if(running == FALSE)
	{
		filereq = filerequester;
		if (AslRequestTags(filereq,
			ASLFR_TitleText,	(ULONG) "Select file to print ...",
			ASLFR_Window,		(ULONG) OutputWnd,
			TAG_DONE) == NULL) return(0);
		strcpy(Options.lastdir, filereq->rf_Dir);
		getfullfilename(Options.lastfile, filereq->rf_Dir, filereq->rf_File);
		number_of_pages = splitpage(Options.lastfile);
	}
	opt_number = MENU_PRINT;
	if(OpenOptionsWindow()) 
	{
		okmsg("can't open options window!");
		CloseOptionsWindow();
		return(0);
	}
	sleep_OutputWnd();
	SetWindowTitles(OptionsWnd, "Print Options", "Print Options");
	copy_options(&TempOptions, &PrintOptions);
	if(number_of_pages == 0)
	{
		TempOptions.PostOpts.bandrendering = FALSE;
		TempOptions.PostOpts.allpages = TRUE;
		TempOptions.PostOpts.from = 0;
		TempOptions.PostOpts.to = 0;
	}
	else
	{
		TempOptions.PostOpts.from = 1;
		TempOptions.PostOpts.to = number_of_pages;
	}
	setoptionsgadgets(MENU_PRINT);
	GT_SetGadgetAttrs(OptionsGadgets[GD_OptPrDen], OptionsWnd, NULL,
		GA_Disabled, FALSE, TAG_DONE);
	GT_SetGadgetAttrs(OptionsGadgets[GD_OptCenter], OptionsWnd, NULL,
		GA_Disabled, FALSE, TAG_DONE);
	GT_SetGadgetAttrs(OptionsGadgets[GD_OptFF], OptionsWnd, NULL,
		GA_Disabled, FALSE, TAG_DONE);

	for(;;)
	{
		WaitPort(OptionsWnd->UserPort);
		retc = HandleOptionsIDCMP();
		if(retc == Options_CANCEL || retc == Options_OK) break;
	}
	CloseOptionsWindow();
	awake_OutputWnd();
	if(retc == Options_OK)
	{
		copy_options(&PrintOptions, &TempOptions);
		sprintf(command, "run > NIL: POST:Post PRINTER OPTFILE ENV:POST.print FILE %s PUBSCREEN %s CONWIN VERBOSE",
					Options.lastfile, Options.Screen.custscreen ? postpubscrname : pubscreenname);
		SystemTagList(command, TAG_END);
	}
	return(0);
}

int MenuAbout( void )
{
	/* routine when (sub)item "About ..." is selected. */

	struct EasyStruct myES =
	{
		sizeof(struct EasyStruct),
		0,
		"About Post:",
		"%s\n\n"
		"post.library:       %ld.%ld\n"
		"Public screen name: %s\n"
		"%s\n"
		"Based on Post V1.7     © 1989, 1992 Adrian Aylward,\n"
		"              V1.86enh © 1993 Robert Poole,\n"
		"              V2.00    © 1997 Christian Eibl\n",
		"Ok",
	};
	char	*an, string[25];

	if(an = ARexxName(RexxStuff))
	{
		sprintf(string, "ARexx port name:    %s\n", an);
	}
	else
	{
		string[0] = 0;
	}
	EasyRequest(OutputWnd, &myES, NULL, (ULONG) &version[6],
					PSbase->lib_Version, PSbase->lib_Revision,
					(ULONG) (Options.Screen.custscreen ? postpubscrname : pubscreenname),
					(ULONG) string);
	return(0);
}

int MenuQuit( void )
{
	/* routine when (sub)item "Quit" is selected. */

	SavePostOptions("ENV:Post", &Options);
	errorende();
	exit(0);
	return(0);
}

int MenuPause( void )
{
	/* routine when (sub)item "Pause Every Page" is selected. */

	pause = !pause;
	return(0);
}

int MenuNext( void )
{
	/* routine when (sub)item "Next Page" is selected. */

	nextpage();
	return(0);
}

int MenuPrevious( void )
{
	/* routine when (sub)item "Previous Page" is selected. */

	previouspage();
	return(0);
}

int MenuGoto( void )
{
	/* routine when (sub)item "Goto Page ..." is selected. */

	int	retc;

	if(running && paused && number_of_pages)
	{
		if(OpenGotoPageWindow()) 
		{
			okmsg("can't open selection window!");
			CloseGotoPageWindow();
			return(0);
		}
		sleep_OutputWnd();
		next_page_number = page_number + 1;
		if(next_page_number == number_of_pages + 1) next_page_number = 1;
		GT_SetGadgetAttrs(GotoPageGadgets[GD_GotoPage], GotoPageWnd, NULL,
			GTIN_Number, next_page_number, TAG_DONE);
		ActivateGadget(GotoPageGadgets[GD_GotoPage], GotoPageWnd, NULL);
		for(;;)
		{
			WaitPort(GotoPageWnd->UserPort);
			retc = HandleGotoPageIDCMP();
			if(retc == GotoPage_CANCEL || retc == GotoPage_OK) break;
		}
		CloseGotoPageWindow();
		awake_OutputWnd();
		if(retc == GotoPage_OK)
		{
			if(page_number != next_page_number)
			{
				Signal((struct Task *) rendertask, 1L << pause_signal);
				page_number = next_page_number;
				sendmenu(PSACTPAUSE, number_of_pages, page_number, 0, NULL, NULL);
			}
		}
	}
	return(0);
}

int MenuInterrupt( void )
{
	/* routine when (sub)item "Interrupt" is selected. */

	if(running && !paused) PSsignalint(arec, 1);
	return(0);
}

int MenuKill( void )
{
	/* routine when (sub)item "Kill" is selected. */

	if(running && !paused) PSsignalint(arec, 2);
	return(0);
}

int MenuInteractive( void )
{
	/* routine when (sub)item "Interactive" is selected. */

	saveterminate();
	sendmenu(PSACTINTER, 0, 0, 0, "%stdin", NULL);
	return(0);
}

int MenuPubScreen( void )
{
	/* routine when (sub)item "Public Screen" is selected. */

	struct	List *pubscrlist;
	struct	Node *node, *nextnode;
	struct	PubScrNode *PubScrNode;
	int		retc, i, selected=0;

	NewList(&NewPubScrList);
	pubscrlist = LockPubScreenList();
	for(node = pubscrlist->lh_Head, i=0; node->ln_Succ; node = node->ln_Succ,i++)
	{
		if(!strcmp(node->ln_Name, postpubscrname)) continue;
		if(!strcmp(node->ln_Name, pubscreenname))
		{
			selected = i;
			strcpy(newpubscreenname, node->ln_Name);
		}
		PubScrNode = (struct PubScrNode *) malloc(sizeof(struct PubScrNode));
		PubScrNode->node.ln_Name = PubScrNode->name;
		strcpy(PubScrNode->name, node->ln_Name);
		AddTail(&NewPubScrList, (struct Node *) PubScrNode);
	}
	UnlockPubScreenList();
	if(NewPubScrList.lh_TailPred == (struct Node *) &NewPubScrList)
	{
		okmsg("no public screens available!");
		return(0);
	}

	if(OpenChoosePSWindow()) 
	{
		okmsg("can't open selection window!");
		CloseChoosePSWindow();
		for(node = NewPubScrList.lh_Head; node->ln_Succ;)
		{
			nextnode=node->ln_Succ;
			free(node);
			node=nextnode;
		}
		return(0);
	}
	sleep_OutputWnd();
	GT_SetGadgetAttrs(ChoosePSGadgets[GD_PubScreenLV], ChoosePSWnd, NULL,
		GTLV_Labels, (ULONG) &NewPubScrList, GTLV_Selected, selected, GTLV_Top, selected, TAG_DONE);
	for(;;)
	{
		WaitPort(ChoosePSWnd->UserPort);
		retc = HandleChoosePSIDCMP();
		if(retc == ChoosePS_CANCEL || retc == ChoosePS_OK) break;
	}
	CloseChoosePSWindow();
	awake_OutputWnd();
	for(node = NewPubScrList.lh_Head; node->ln_Succ;)
	{
			nextnode=node->ln_Succ;
			free(node);
			node=nextnode;
	}
	if(retc == ChoosePS_OK && strcmp(newpubscreenname, postpubscrname))
	{
		if(do_pubscreen()) return(0);
	}
	return(0);
}

int MenuCustomScreen( void )
{
	/* routine when (sub)item "Custom Screen" is selected. */

	if(!Menu_ScreenMode())
	{
		do_screen();
	}
	return(0);
}

int MenuOptions( void )
{
	/* routine when (sub)item "Options ..." is selected. */

	int	retc;
	BOOL	exitnext = FALSE;
	struct	Options	Options_bak;

	opt_number = MENU_NEW;
	copy_options(&TempOptions, &Options);
	copy_options(&Options_bak, &Options);
nochmal:
	if(OpenOptionsWindow()) 
	{
		okmsg("can't open options window!");
		CloseOptionsWindow();
		return(0);
	}
	sleep_OutputWnd();
	SetWindowTitles(OptionsWnd, "Options for this Post Window", "Options for this Post Window");
	setoptionsgadgets(MENU_NEW);
	for(;;)
	{
		WaitPort(OptionsWnd->UserPort);
		retc = HandleOptionsIDCMP();
		if(retc == Options_CANCEL || retc == Options_OK) break;
	}
	CloseOptionsWindow();
	awake_OutputWnd();
	if(retc == Options_OK)
	{
		if(exitnext = do_opts())
		{
			copy_options(&TempOptions, &Options_bak);
			SavePostOptions("ENV:Post", &Options_bak);
			goto nochmal;
		}
	}
	else if(exitnext)
	{
		errorende();
		exit(20);
	}
	return(0);
}



int PubScreenLVClicked( void )
{
	/* routine when gadget "" is clicked. */

	struct  Node    *node;
	int     i;

	node = NewPubScrList.lh_Head;
	for(i=0; i < ChoosePSMsg.Code; i++) 
	{
		node = node->ln_Succ;
	}
	strcpy(newpubscreenname, node->ln_Name);
	return(0);
}

int CPSCancelClicked( void )
{
	/* routine when gadget "_Cancel" is clicked. */

	return(ChoosePS_CANCEL);
}

int CPSOkClicked( void )
{
	/* routine when gadget "_Ok" is clicked. */

	return(ChoosePS_OK);
}

int GotoPageClicked( void )
{
	/* routine when gadget "Page Number:" is clicked. */

	next_page_number = GetNumber(GotoPageGadgets[GD_GotoPage]);
	if(next_page_number < 1)
	{
		next_page_number = 1;
		GT_SetGadgetAttrs(GotoPageGadgets[GD_GotoPage], GotoPageWnd, NULL,
			GTIN_Number, next_page_number, TAG_DONE);
		ActivateGadget(GotoPageGadgets[GD_GotoPage], GotoPageWnd, NULL);
		return(0);
	}
	else if(next_page_number > number_of_pages)
	{
		next_page_number = number_of_pages;
		GT_SetGadgetAttrs(GotoPageGadgets[GD_GotoPage], GotoPageWnd, NULL,
			GTIN_Number, next_page_number, TAG_DONE);
		ActivateGadget(GotoPageGadgets[GD_GotoPage], GotoPageWnd, NULL);
		return(0);
	}
	else return(GotoPage_OK);
}

int GotoPageCloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */

	return(GotoPage_CANCEL);
}

int ChoosePSCloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */

	return(ChoosePS_CANCEL);
}

int ChoosePSVanillaKey( void )
{
	/* routine for "IDCMP_VANILLAKEY". */

	switch (ChoosePSMsg.Code)
	{
		case	'c':
		case	'C':
			return(ChoosePS_CANCEL);

		case	'o':
		case	'O':
			return(ChoosePS_OK);
	}
	return(0);
}

BOOL	do_opts(void)
{
	struct DimensionInfo di;
	BOOL	do_screen = FALSE;
	int	depth_bak;

	depth_bak = Options.PostOpts.depth;
	if(Options.PostOpts.depth != TempOptions.PostOpts.depth || 
		Options.Screen.custscreen != TempOptions.Screen.custscreen)
	{
		do_screen = TRUE;
		if(Options.Screen.custscreen)
		{
			if(GetDisplayInfoData(FindDisplayInfo(Options.Screen.ScrDisplayID), (APTR) &di,
				sizeof(struct DimensionInfo), DTAG_DIMS, Options.Screen.ScrDisplayID))
			{
				if(di.MaxDepth < TempOptions.PostOpts.depth+1)
				{
					okmsg("the current displaymode does not support enough colors!");
					return(OPT_COLORS);
				}
			}
		}
	}
	copy_options(&Options, &TempOptions);
	saveterminate();
	sendmenu(PSACTCREATE, 0, 0, 0, NULL, NULL);
	Wait(1L << create_signal);
	if(createerror)
	{
		Options.PostOpts.depth = depth_bak;
		return(OPT_CREATE);
	}
	closewindow();
	if(do_screen)
	{
		if(!Options.Screen.custscreen)
		{
			openpubscreen(&pubscrcontext, pubscreenname);
			if(pubscrcontext.pens_ok == FALSE)
			{
				okmsg("Can't obtain needed Pens!");
				GetVisual();
				UnlockPubScreen(NULL, pubscrcontext.pubscreen);
				pubscrcontext.ps_lock = FALSE;
				Options.PostOpts.depth = depth_bak;
				return(OPT_PENS);
			}
		}
		if (custscreen)		
		{
			while(!CloseScreen(custscreen)) okmsg("you have to close the visitor windows!");
			custscreen = NULL;
		}
		if (Options.Screen.custscreen) openscreen();
	}
	openwindow();
	do_blit();
	runstartupfiles();
	return(FALSE);
}

void	do_screen(void)
{
	closewindow();
	if (custscreen)
	{
		while(!CloseScreen(custscreen)) okmsg("you have to close the visitor windows!");
		custscreen = NULL;
	}
	Options.Screen.custscreen = TRUE;
	openscreen();
	openwindow();
	do_blit();
}

BOOL	do_pubscreen(void)
{
	struct	Screen	*screen_bak;

	if(!Options.Screen.custscreen && !strcmp(newpubscreenname, pubscreenname))
	{
		return(PUB_SAME);
	}
	screen_bak = screen;
	if(openpubscreen(&newpubscrcontext, newpubscreenname) == FALSE)
	{
		return(PUB_SCREEN);
	}
	else if(newpubscrcontext.pens_ok == FALSE)
	{
		okmsg("Can't obtain needed Pens!");
		UnlockPubScreen(NULL, newpubscrcontext.pubscreen);
		screen = screen_bak;
		return(OPT_PENS);
	}
	closewindow();
	if (custscreen)
	{
		while(!CloseScreen(custscreen)) okmsg("you have to close the visitor windows!");
		custscreen = NULL;
	}
	Options.Screen.custscreen = FALSE;
	strcpy(pubscreenname, newpubscreenname);
	strcpy(Options.Screen.pubscrname, newpubscreenname);
	pubscrcontext = newpubscrcontext;
	screen = newpubscrcontext.pubscreen;
	ScreenToFront(screen);
	openwindow();
	do_blit();
	return(FALSE);
}
