/*
 *  FILE: intuistuff.c
 *  Support routines for creating some useful intuition-type structures.
 *
 *  Public Domain, but keep my name in it as the original author.
 *  31-Aug-88	Jan Sven Trabandt   first release version
 *  31-Oct-88	Jan Sven Trabandt   made gimmeBorder more flexible/efficient
 */


#define I_AM_INTUISTUFF
#include "gimmelib/gimmefuncs.h"
#include "gimmelib/intuistuff.h"
#include "gimmelib/macros.h"


/* WSL-type construct */
#define GUESS		do {
#define QUIF( cond )    if( cond ) break;
#define ENDGUESS	} while( 0 );


struct Border *gimmeBorder( mh, xsize, ysize )
    void    **mh;
    SHORT   xsize, ysize;
{
    register struct Border  *bp;
    register SHORT	    *r;
    ULONG		    size;
    void		    *mymh = NULL;
    void		    **mhdr = &mymh;

    GUESS
	size = sizeof(struct Border);
	if( !mh ) {
	    r = AllocMem( (ULONG)sizeof(SHORT) * 2 * 5, MEMF_PUBLIC );
	    QUIF( !r );
	    mhdr = NULL;
	} else {
	    if( xsize > 0 && ysize > 0 ) {
		/* need room for 5 pairs of shorts as well */
		size = sizeof(struct Border) + sizeof(SHORT) * 2 * 5;
		r = NULL;
	    }
	}
	bp = chainAllocMem( mhdr, (ULONG) size, MEMF_CLEAR | MEMF_PUBLIC );
	QUIF( !bp );
	bp->FrontPen = 1;
	bp->DrawMode = JAM1;
	if( xsize > 0 && ysize > 0 ) {
	    if( !r ) {
		r = (SHORT *) (bp + 1);
	    }
	    bp->XY = r;
	    r[2] = r[4] = xsize - 1;
	    r[5] = r[7] = ysize - 1;
	    bp->Count = 5;
	}
	linkChainMem( mh, mymh );
	return( bp );
    ENDGUESS
    if( mhdr ) {
	chainFreeMem( mymh );
    } else {
	if( r ) {
	    FreeMem( r, (ULONG) sizeof(SHORT) * 2 * 5 );
	}
    }
    return( NULL );
} /* gimmeBorder */


struct Image *gimmeImage( mh, depth, width, height )
    void    **mh;
    SHORT   depth, width, height;
{
    register struct Image   *ip;
    ULONG   size;		    /* image datasize (bytes) for allocation */
    void    *mymh = NULL;
    void    **mhdr = &mymh;
    UBYTE   planepick;

    GUESS
	if( !mh ) {
	    mhdr = NULL;
	}
	ip = chainAllocMem( mhdr, (ULONG)sizeof(struct Image),
				MEMF_CLEAR | MEMF_PUBLIC );
	QUIF( !ip );
	ip->Width = width;
	ip->Height = height;
	ip->Depth = depth;
	if( depth > 0 && width > 0 && height > 0 ) {
	    size = GIM_IMAGESIZE(depth, width, height);
	    ip->ImageData = chainAllocMem( mhdr, size, MEMF_CLEAR|MEMF_CHIP );
	    QUIF( !ip->ImageData );
	    planepick = 1;
	    while( --depth > 0 ) {
		planepick = (planepick << 1) + 1;
	    } /* while */
	    ip->PlanePick = planepick;
	}
	linkChainMem( mh, mymh );
	return( ip );
    ENDGUESS
    if( mhdr ) {
	chainFreeMem( mymh );
    } else {
	if( ip ) {
	    FreeMem( ip, (ULONG)sizeof(struct Image) );
	}
    }
    return( NULL );
} /* gimmeImage */


struct IntuiText *gimmeIntuiText( mh, s, textattr, width )
    void    **mh;
    UBYTE   *s;
    struct TextAttr *textattr;
    SHORT   width;
{
    register struct IntuiText	*itp;

    GUESS
	itp = chainAllocMem( mh, (ULONG)sizeof(struct IntuiText),
				MEMF_CLEAR | MEMF_PUBLIC );
	QUIF( !itp );
	itp->FrontPen = 1;
	itp->DrawMode = JAM2;
	itp->ITextFont = textattr;
	itp->IText = s;
	if( width > 0 ) {           /* if width given, centre text */
	    itp->LeftEdge = (width - IntuiTextLength(itp)) >> 1;
	}
	return( itp );
    ENDGUESS
    return( NULL );
} /* gimmeIntuiText */
