/* ps.c -- public screen "meat" routines :ts=4	*/

/*
Copyright (c) 1989 Commodore-Amiga, Inc.

Executables based on this information may be used in software
for Commodore Amiga computers. All other rights reserved.
This information is provided "as is"; no warranties are made.
All use is at your own risk, and no liability or responsibility
is assumed.
*/

#include "sysall.h"
#include "pubsc.h"

#define D(x)	;

/* globals for messages to user	*/
extern UBYTE			currname[];
extern UBYTE			defname[];

extern struct Screen			*lockedscreen;
extern struct Window			*window;

struct Screen	*LockPubScreen();

/*
 * process command messages
 */
doCommand( id )
int		id;		/* already has high byte masked off	*/
{
	struct Screen	*currscreen;
	ULONG			openPubScreen();
	ULONG			oserror;

	switch ( id )
	{
	case	c_close:
		currscreen = window->WScreen;
		if ( ( currscreen->Flags & SCREENTYPE ) == WBENCHSCREEN )
		{
			psstatus( "Can't close Workbench screen.");
		}
		else
		{
		    downWindow();	/* get off current screen	*/
			if ( ! CloseScreen( currscreen ) )
			{
				lockPubScreen();
				upWindow();		/* come back	*/
				psstatus( "Can't close screen." );
			}
			else
			{
				currname[0] = '\0';
				lockPubScreen();
				upWindow();
			}
		}
		break;

	case	c_default:
		SetDefaultPubScreen( currname );
		strcpy( defname, currname );
		updateMessages();
		psstatus( "New default pubscreen set." );
		break;

	case	c_open:
	    if ( oserror = openPubScreen() )
		{	
			D( printf("oPS failed, error %lx\n", oserror ) );
			if ( oserror == OSERR_PUBNOTUNIQUE )
				psstatus( "Public screen already open." );
			else
				psstatus( "Public screen failed to open." );
		}
		else	/* successful open	*/
		{
			/* open on the new screen	*/
			downWindow();
			/* we open our screen locked	*/
			upWindow();
		}
		break;
	case	c_jump:
		lockNextScreen( window->WScreen );
		downWindow();
		upWindow();
		break;

	default:
	    psstatus( "Unknown doCommand" );
	}
}

/*
 * try to get ones hands on the next public screen
 * Only call this if window is open.
 */
lockNextScreen( screen )
struct Screen	*screen;
{
	D( printf("lNextScreen, screen %lx\n", screen ) );

	/* set up new currname	*/
	if ( ! NextPubScreen( screen, currname ) )
	{
		D( printf("NextPubScreen failed.\n") );
		currname[0] = '\0';
	}
	D( printf("new currname: %s\n", currname ) );

	lockPubScreen();
}

/*
 * locks currname, else WB
 */
lockPubScreen()
{
	UBYTE	*psname;

	D( if ( lockedscreen ) printf("!!!locking second! ! !\n") );

	psname = currname[0]? currname: NULL;
	D( printf( "lPS: lock with pointer %lx\n", psname ) );

	lockedscreen = LockPubScreen( currname[0]? currname: NULL );
	D( printf("lPS: LockPubScreen returned %lx\n", lockedscreen ));
}

unlockScreen()
{
	if ( lockedscreen ) UnlockPubScreen( currname );
	lockedscreen = NULL;
}


#define PSNAME	"Phred"

struct ColorSpec colorspecs[] = {
	{0, 0xf, 0xf, 0xf},
	{1, 0,  0,  0 },
	{2, 0xb, 0xb, 0xb},
	{3, 0x2, 0x7, 0xC},
	{-1,},
};

ULONG				oserror;

struct TagItem	nsext[] = {
	{ NSTAG_PUBNAME, (ULONG) PSNAME },
	{ NSTAG_ERROR, (ULONG) &oserror },
	{ NSTAG_INITCOLORS, (ULONG) colorspecs },
	{ TAG_DONE,}
};


/*
 * returns error from OpenScreen
 * uses hardcoded name
 * ZZZ: if FALLBACK: should reset currname.
 */
ULONG
openPubScreen()
{
	struct ExtNewScreen	ns;
	struct Screen		*pubscreen;

    ns.ViewModes =	HIRES;
    ns.LeftEdge	=	0;
    ns.TopEdge	=	0;
    ns.Width	=	STDSCREENWIDTH;
    ns.Height	=	STDSCREENHEIGHT;
    ns.Depth	=	2;
    ns.DefaultTitle	= NULL;				/* use pubname	*/

	ns.DetailPen =	0;
	ns.BlockPen	=	1;
	ns.Gadgets	=	NULL;
	ns.CustomBitMap	=	NULL;
	ns.Font		=	NULL;
	ns.Type		=	CUSTOMSCREEN;

	ns.Type			|= NS_EXTENDED;		/* means that ns.Extension is valid	*/
	ns.Extension	=	nsext;		/* it points to an array of tagitems	*/

	if ( pubscreen = OpenScreen( &ns ) )
	{
		/* set up new currname, assuming we want to open
		 * out window on this new screen
		 */
		strcpy( currname, PSNAME );
		PubScreenStatus( pubscreen, 0L );	/* make it public */
		D( if (lockedscreen) printf("!!!!!! locking a second!!\n") );
		lockPubScreen();
		return ( 0 );
	}
	else return ( oserror );
}
