/**********************************************************************/
/*    Public screen Opening code, for creating new public screens     */
/**********************************************************************/
#include "psx.h"

/*
struct ColorSpec ColourSpecs[] = 
	{
	{0, 11, 9, 7},
	{1, 3,  2,  2 },
	{2, 15, 14, 13},
	{3, 12, 2, 0 },
	{-1,},
	};
*/

ULONG OpenErr;

char *OpenErrors[] = 
	{
	"Unknown Error",
	"Named monitor not available",
	"Proper chips not available",
	"Not enough memory",
	"Not enough chip memory",
	"Screen name in use",
	"Unknown screen mode",
	};


/* I accept the default pens, but have to
 * pass something to get the new look.
 */
UWORD	Pens[] = 
	{
	0, 1, ~0				/* just detail and block	*/
	};

char NewPubScreenName[MAXPUBSCREENNAME];

ULONG NewScreenTags[] = 
	{
	SA_PubName, (ULONG) NewPubScreenName,
	SA_ErrorCode, (ULONG) &OpenErr,
	SA_Pens, (ULONG) Pens,
	TAG_DONE,
	};



/**********************************************************************/
/*            Get the parameters for the new public screen            */
/**********************************************************************/
int
GetScreenParameters(struct NewScreen *NS)
{
ULONG TopBorder;
int WinHeight, WinWidth;
struct Window *ReqWindow;
struct IntuiMessage *Message;
ULONG Class, Code;
int AllOkay=TRUE;
int KG;
int XDim=0, YDim=0, Depth=0;

TopBorder=Screen->WBorTop;
strcpy(NewPubScreenName, "PSX_Screen");

SGadList=NULL;
WinHeight=CreateScreenGadgets(&SGadList, VI, TopBorder, TAttr, &WinWidth);
if (WinHeight==0)
	{
	SetMessage("Unable to create gadgets.");
	return(FALSE);
	};

ReqWindow = (struct Window *)OpenWindowTags( NULL,
		WA_Left,	WIN_LEFT+10,
		WA_Top,		WIN_TOP+5,
		WA_Width,	WinWidth,
		WA_Height,	WinHeight,
		WA_IDCMP,  	GADGETUP|CLOSEWINDOW|BUTTONIDCMP|LISTVIEWIDCMP|REFRESHWINDOW,
		WA_Activate,	TRUE,
		WA_DepthGadget,	TRUE,
		WA_DragBar,	TRUE,
		WA_RMBTrap, 	TRUE,
		WA_Title,	"Select Screen Style",
		WA_SimpleRefresh, TRUE,
		WA_PubScreen,	Window->WScreen,
		TAG_END
		);

if (!ReqWindow) return(FALSE);

/** Set screen font **/

SetFont(ReqWindow->RPort, ScreenFont);

/** GadTools Init **/

AddGList(ReqWindow, SGadList, -1, -1, NULL);
RefreshGList(SGadList, ReqWindow, NULL, -1);
GT_RefreshWindow(ReqWindow, NULL);

KG=TRUE;

while (KG)
	{
	struct Gadget *Gad;
	ULONG GadID;

	Message=(struct IntuiMessage *)GT_GetIMsg(ReqWindow->UserPort);
	if (Message==FALSE)
		{
		WaitPort(ReqWindow->UserPort);
		continue;
		};

	Class=Message->Class;
	Code=Message->Code;
	Gad=Message->IAddress;
	GadID=Gad->GadgetID;

	GT_ReplyIMsg((struct IntuiMessage *)Message);

	switch (Class)
		{
		case GADGETUP:
			switch (GadID)
				{
				case SGID_NAME:
					strcpy(NewPubScreenName, ((struct StringInfo *)Gad->SpecialInfo)->Buffer);
					break;

				case SGID_CANCEL:
					KG=FALSE;
					AllOkay=FALSE;
					break;

				case SGID_XDIM:
					XDim=Code;
					break;

				case SGID_YDIM:
					YDim=Code;
					break;

				case SGID_DEPTH:
					Depth=Code;
					break;

				case SGID_OPEN:
					KG=FALSE;

				default:
					break;
				};
			break;

		case REFRESHWINDOW:
			GT_BeginRefresh(ReqWindow);
			GT_EndRefresh(ReqWindow, TRUE);
			break;
		default:
			break;
		};		
	};

NS->ViewModes=0;

if (XDim==0)
	NS->ViewModes|=HIRES;

if (YDim==1)
	NS->ViewModes|=LACE;

NS->Depth=Depth+1;

CloseWindow(ReqWindow);
return(AllOkay);
}


/**********************************************************************/
/*                      Open screen base routine                      */
/**********************************************************************/
void
OpenNewPublicScreen(void)
{
struct Screen *PubScreen;
struct ExtNewScreen	NS;

setmem(&NS, sizeof(NS), 0);

if (GetScreenParameters(&NS)==FALSE)
	return;

NS.Width	=	-1;		// Set Non-Zero items
NS.Height	=	-1;
NS.BlockPen	=	1;
NS.Type		=	CUSTOMSCREEN;

PubScreen=(struct Screen *)OpenScreenTagList(&NS, (struct TagItem *)&NewScreenTags[0]);

if (PubScreen==0)
	SetMessage("Error opening screen.");
	else 
	{
	PubScreenStatus(PubScreen, 0L);
	strcpy(CurPubScreenName, NewPubScreenName);
	ClosePSXWindow();
	ReleasePublicScreen();
	FindPublicScreen();
	OpenPSXWindow();
	ScreenToFront(PubScreen);
	SetMessage("Public screen opened.");
	};

}


/**********************************************************************/
/*                   CLI-driven open public screen                    */
/**********************************************************************/
void
CLIOpenNewPublicScreen(char *Name, long HiresFlag, long LaceFlag, long *DepthPtr, long DefaultFlag)
{
struct Screen *PubScreen;
struct NewScreen	NS;

setmem(&NS, sizeof(NS), 0);

NS.Depth	=	2;
NS.Width	=	-1;		// Set Non-Zero items
NS.Height	=	-1;
NS.BlockPen	=	1;
NS.Type		=	CUSTOMSCREEN;

strcpy(NewPubScreenName, Name);

// Check args for HIRES, LORES, LACE, NOLACE, and DEPTH # arguments
if (HiresFlag) NS.ViewModes|=HIRES;
if (LaceFlag) NS.ViewModes|=LACE;
if (DepthPtr) NS.Depth=*DepthPtr;

PubScreen=(struct Screen *)OpenScreenTagList(&NS, (struct TagItem *)&NewScreenTags[0]);
if (PubScreen==0)
	{
	int ShowErr;

	if (OpenErr>6) ShowErr=0;
		else ShowErr=OpenErr;
	printf("Public screen open error: %s (%d).\n", OpenErrors[ShowErr], OpenErr);
	} else 
	{
	PubScreenStatus(PubScreen, 0L);
	if (DefaultFlag)
		SetDefaultPubScreen(NewPubScreenName);
	};

return;
}


/**********************************************************************/
/*              Close a named public screen from the CLI              */
/**********************************************************************/
void
CLIClosePublicScreen(char *Name)
{
struct Screen *ToClose;
long Result;

ToClose=LockPubScreen(Name);

if (ToClose==0) 
	{
	printf("Unable to lock screen.\n");
	return;
	};

if ((ToClose->Flags&SCREENTYPE)==WBENCHSCREEN)
	{
	printf("Cannot close the Workbench screen!\n");
	UnlockPubScreen(Name, ToClose);
	return;
	};

UnlockPubScreen(Name, ToClose);

Result=CloseScreen(ToClose);

if (Result==FALSE)
	printf("Unable to close screen.\n");
	else printf("Screen successfully closed.\n");
}
