/*
 *  FILE: requester.c
 *  Support routines for putting up an Auto Request or creating a Requester.
 *
 *  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   added more functionality to gimmeRequester
 */


#define I_AM_REQUESTER
#include <clib/macros.h>
#include "gimmelib/gimmefuncs.h"
#include "gimmelib/requester.h"
#include "gimmelib/macros.h"

extern struct GfxBase *GfxBase;


SHORT gimmeAutoRequest( window, s, textattr )
    struct Window   *window;
    UBYTE	    *s;
    struct TextAttr *textattr;
{
    struct IntuiText	itext, ptext, ntext;
    SHORT		xsize, ysize, width;

    if( !s ) {
	s = (UBYTE *) GAR_DUMMY_TEXT;
    }
    itext.FrontPen  = AUTOFRONTPEN;
    itext.BackPen   = AUTOBACKPEN;
    itext.DrawMode  = AUTODRAWMODE;
    itext.LeftEdge  = AUTOLEFTEDGE;
    itext.TopEdge   = AUTOTOPEDGE;
    itext.ITextFont = textattr;
    itext.IText     = s;
    itext.NextText  = AUTONEXTTEXT;

    ptext = itext;	    /* struct copy */
    ntext = itext;	    /* struct copy */
    ptext.IText = gimAutReqPostext;
    ntext.IText = gimAutReqNegtext;
    xsize = 0;
    if( textattr ) {
	ysize = textattr->ta_YSize;
    } else if( window ) {
	ysize = window->RPort->TxHeight;
	xsize = window->RPort->TxWidth;
    } else {
	ysize = GfxBase->DefaultFont->tf_YSize;
    }
    if( !xsize ) {
	xsize = GfxBase->DefaultFont->tf_XSize;
    }
    width = MAX(IntuiTextLength(&itext),
		IntuiTextLength(&ptext) + IntuiTextLength(&ntext) + 3*xsize);
    return (
	    AutoRequest( window, &itext, &ptext, &ntext, ENDGADGET, ENDGADGET,
			(ULONG) width + xsize * GAR_BORDER_WIDTH,
			(ULONG) ysize * GAR_HEIGHT )
	);
} /* gimmeAutoRequest */


#define XLEEWAY     8	    /* border space */
#define YLEEWAY     4
#define MIN_WIDTH   50	    /* minimum dimensions if calculating dimension(s) */
#define MIN_HEIGHT  20	    /* not counting y leeways */

struct Requester *gimmeRequester( mh, left, top, width, height, backfill,
				    gp, s, textattr, flags )
    void	    **mh;
    SHORT	    left, top;
    SHORT	    width, height;
    UBYTE	    backfill;
    struct Gadget   *gp;
    UBYTE	    *s;
    struct TextAttr *textattr;
    ULONG	    flags;
{
    register struct Requester	*req;
    register struct Border	*bp;
    struct Gadget   *gadg;
    SHORT   len, extra;
    void    *mymh = NULL;

    GUESS
	QUIF( !mh );
	req = chainAllocMem( &mymh, (ULONG)sizeof(struct Requester),
				MEMF_PUBLIC | MEMF_CLEAR );
	QUIF( !req );
	if( flags & POINTREL ) {
	    req->RelLeft = left;
	    req->RelTop = top;
	}
	req->LeftEdge = left;
	req->TopEdge = top;
	req->ReqGadget = gp;
	req->ReqText = gimmeIntuiText( &mymh, s != NULL ? s : (UBYTE *)"",
					textattr, 0 );
	QUIF( !req->ReqText );
	req->ReqText->TopEdge = YLEEWAY;
	req->ReqText->LeftEdge = XLEEWAY;
	req->ReqText->BackPen = backfill;
	req->Flags = flags;
	req->BackFill = backfill;
	if( width <= 0 ) {
	    width = IntuiTextLength( req->ReqText );
	    extra = 0;
	    for( gadg = gp; gadg; gadg = gadg->NextGadget ) {
		if( gadg->Flags & GRELRIGHT ) {
		    len = -gadg->LeftEdge;
		} else {
		    len = gadg->LeftEdge;
		}
		if( !(gadg->Flags & GRELWIDTH) ) {
		    len += gadg->Width;
		}
		if( len > width ) {
		    width = len;
		} else if( gadg->Activation & (RIGHTBORDER | LEFTBORDER) ) {
		    if( len > extra ) {
			extra = gadg->Width;
		    }
		}
	    } /* for */
	    width += extra + XLEEWAY;
	    if( width <= 0 ) {
		width = MIN_WIDTH;
	    }
	}
	req->Width = width;
	if( height <= 0 ) {
	    if( textattr ) {
		height = textattr->ta_YSize;
	    } else {
		height = MIN_HEIGHT;
	    }
	    extra = 0;
	    for( gadg = gp; gadg; gadg = gadg->NextGadget ) {
		if( gadg->Flags & GRELBOTTOM ) {
		    len = -gadg->TopEdge;
		} else {
		    len = gadg->TopEdge;
		}
		if( !(gadg->Flags & GRELHEIGHT) ) {
		    len += gadg->Height;
		}
		if( len > height ) {
		    height = len;
		} else if( gadg->Activation & (BOTTOMBORDER | TOPBORDER) ) {
		    if( len > extra ) {
			extra = gadg->Height;
		    }
		}
	    } /* for */
	    height += extra + YLEEWAY;
	}
	req->Height = height;
	bp = gimmeBorder( &mymh, width - 4, height - 2 );
	if( bp ) {
	    bp->LeftEdge = 2;
	    bp->TopEdge = 1;
	    bp->FrontPen = ~backfill;
	    req->ReqBorder = bp;
	    /* double thickness vertical lines */
	    bp = gimmeBorder( &mymh, width - 6, height - 2 );
	    if( bp ) {
		bp->LeftEdge = 3;
		bp->TopEdge = 1;
		bp->FrontPen = ~backfill;
		req->ReqBorder->NextBorder = bp;
	    }
	}
	linkChainMem( mh, mymh );
	return( req );
    ENDGUESS
    if( mymh ) {
	chainFreeMem( mymh );
    }
    return( NULL );
} /* gimmeRequester */
