/*
 *  FILE: screen.c
 *  Support for Intuition screen stuff.
 *
 *  Public Domain, but keep our names in it as the original authors.
 *  31-Aug-88	Jan Sven Trabandt   first release version
 *  30-Sep-88	Jan Sven Trabandt   gimmeNewScreen checks width more closely
 */


#define I_AM_SCREEN
#include "gimmelib/gimmefuncs.h"
#include "gimmelib/window.h"
#include "gimmelib/globals.h"

extern struct GfxBase *GfxBase;


struct NewScreen *gimmeNewScreen( modes, type, depth, title, textattr )
    ULONG	    modes, type;
    SHORT	    depth;
    UBYTE	    *title;
    struct TextAttr *textattr;
{
    register struct NewScreen	*ns;

#ifdef GIMME_WIMPY
    if( depth < 1 || depth > 8 ) {
	return( NULL );
    }
#endif
    ns = (struct NewScreen *) AllocMem( (ULONG)sizeof(struct NewScreen),
					    MEMF_PUBLIC | MEMF_CLEAR );
    if( ns ) {
	ns->Width = GfxBase->NormalDisplayColumns;
	if( modes & HIRES ) {
	    if( ns->Width <= 350 ) {
		ns->Width <<= 1;
	    }
	} else {
	    if( ns->Width > 350 ) {
		ns->Width >>= 1;
	    }
	}
	ns->Height = STDSCREENHEIGHT;
	ns->Depth = depth;
	ns->BlockPen = 1;
	ns->ViewModes = modes;
	ns->Type = type;
	ns->Font = textattr;
	ns->DefaultTitle = title;
    }
    return( ns );
} /* gimmeNewScreen */


short getRidOfNewScreen( ns )
    struct NewScreen	*ns;
{
#ifdef GIMME_WIMPY
    if( !ns ) {
	return( -1 );
    }
#endif
    FreeMem( ns, (ULONG)sizeof(struct NewScreen) );
    return( 0 );
} /* getRidOfNewScreen */


struct Screen *gimmeScreen( ns, winptr, depth, IDCMPflags, winflags )
    struct NewScreen	*ns;
    struct Window	**winptr;
    SHORT		depth;
    ULONG		IDCMPflags, winflags;
{
    struct Screen	*screen;
    struct NewWindow	*nw;
    struct NewScreen	*myns;

    if( !(myns = ns) ) {
	ns = gimmeNewScreen( HIRES, CUSTOMSCREEN, depth, NULL, &gimMyFont );
    }
    if( ns ) {
	screen = OpenScreen( ns );
	if( screen && winptr ) {
	    nw = gimmeNewWindow( NULL, screen, 0, 1, IDCMPflags, winflags );
	    if( !nw ) {
		*winptr = NULL;
	    } else {
		*winptr = gimmeWindow( nw, 0, 0, 0 );
		getRidOfNewWindow( nw );
		if( !*winptr ) {
		    getRidOfScreen( screen, NULL );
		    screen = NULL;
		} else {
		    ShowTitle( screen, FALSE );     /* hide screen title */
		}
	    }
	}
    }
    if( !myns && ns ) {
	getRidOfNewScreen( ns );
    }
    return( screen );
} /* gimmeScreen */


struct Screen *gimmeScreenLazy( ns, winptr, depth )
    struct NewScreen	*ns;
    struct Window	**winptr;
    SHORT		depth;
{
    return( gimmeScreen(ns, winptr, depth, IDCMP_DEFAULT, FLAGS_DEFAULT) );
} /* gimmeScreenLazy */


short getRidOfScreen( screen, window )
    struct Screen   *screen;
    struct Window   *window;
{
    if( window ) {
	getRidOfWindow( window );
    }
    if( screen ) {
	CloseScreen( screen );
    }
    return( 0 );
} /* getRidOfScreen */


short lowerScreen( screen, toheight )
    struct Screen   *screen;
    SHORT	    toheight;
{
    register SHORT  i;

#ifdef GIMME_WIMPY
    if( !screen ) {
	return( -1 );
    }
#endif
    for( i = screen->TopEdge | 1; i < toheight; i += 2 ) {
	MoveScreen( screen, 0L, 2L );
    } /* for */
    return( 0 );
} /* lowerScreen */


short raiseScreen( screen, toheight )
    struct Screen   *screen;
    SHORT	    toheight;
{
    register SHORT  i;

#ifdef GIMME_WIMPY
    if( !screen ) {
	return( -1 );
    }
#endif
    for( i = screen->TopEdge & (~1); i >= toheight; i -= 2 ) {
	MoveScreen( screen, 0L, -2L );
    } /* for */
    return( 0 );
} /* raiseScreen */
