/*
 *  FILE: gadgstuff.c
 *  Support routines for dealing with gadgets.
 *
 *  Public Domain, but keep my name in it as the original author.
 *  31-Aug-88	Jan Sven Trabandt   first release version
 *  30-Sep-88	Jan Sven Trabandt   split from gadget.c (and improved)
 *				    renamed clearGadget to clearGadgets
 *  31-Oct-88	Jan Sven Trabandt   removed addGadgets, removeGadgets
 *				      since system AddGList, RemoveGList exists
 *				    changed order of clearGadgets parms to
 *				      match RefreshGadgets more closely
 *				    moved toggleBoolGadget from gadget.c
 */


#define I_AM_GADGSTUFF
#include "gimmelib/gimmefuncs.h"


short clearGadgets( gp, window, req, numgad )
    struct Gadget	*gp;
    struct Window	*window;
    struct Requester	*req;
    SHORT		numgad;
{
    register struct Image   *ip;
    struct RastPort	    *rp;
    APTR		    temp;
    register SHORT	    pick, onoff;    /* use as front/back as well */
    SHORT		    left, top;
    SHORT		    propborder;
    struct Image	    image;
    struct IntuiText	    itext;
    BYTE		    backpen;

#ifdef GIMME_WIMPY
    if( !window ) {
	return( -1 );
    }
#endif
    rp = window->RPort;
    if( gp && !(gp->GadgetType & REQGADGET) ) {
	req = NULL;
    }
    if( req ) {
	backpen = req->BackFill;
	if( req->ReqLayer && req->ReqLayer->rp ) {
	    rp = req->ReqLayer->rp;
	}
    } else if( (backpen = window->RPort->BgPen) == -1 ) {
	backpen = 0;
    }
    for( ; gp && numgad != 0; gp = gp->NextGadget, --numgad ) {
	left = gp->LeftEdge;
	if( gp->Flags & GRELRIGHT ) {
	    left += (req ? req->Width : window->Width) - 1;
	}
	top = gp->TopEdge;
	if( gp->Flags & GRELBOTTOM ) {
	    top += (req ? req->Height : window->Height) - 1;
	}
	propborder = 0;
	if( (gp->GadgetType & ~GADGETTYPE) == PROPGADGET ) {
	    if( !(((struct PropInfo *)gp->SpecialInfo)->Flags
					    & PROPBORDERLESS) ) {
		propborder = 1;
	    }
	}
	if( (gp->Flags & SELECTED) && (gp->Flags & GADGHIMAGE)
		&& gp->SelectRender ) {
	    (APTR) ip = gp->SelectRender;
	} else {
	    (APTR) ip = gp->GadgetRender;
	}
	if( gp->Flags & GADGIMAGE ) {
	    while( ip ) {
		if( propborder ) {
		    ip->LeftEdge += 4;
		    ip->TopEdge += 2;
		}
		pick = ip->PlanePick;
		onoff = ip->PlaneOnOff;
		ip->PlanePick = 0x0;
		ip->PlaneOnOff = backpen;
		temp = (APTR) ip->NextImage;
		ip->NextImage = NULL;
		DrawImage( rp, ip, (long) left, (long) top );
		ip->NextImage = (struct Image *) temp;
		ip->PlanePick = pick;
		ip->PlaneOnOff = onoff;
		if( propborder ) {
		    ip->LeftEdge -= 4;
		    ip->TopEdge -= 2;
		}
		ip = (struct Image *) temp;
	    } /* while */
	} else {			/* else it's a border */
	    while( (struct Border *) ip ) {
		if( propborder ) {
		    ((struct Border *)ip)->LeftEdge += 4;
		    ((struct Border *)ip)->TopEdge += 2;
		}
		pick = ((struct Border *)ip)->FrontPen;
		onoff = ((struct Border *)ip)->BackPen;
		((struct Border *)ip)->FrontPen = backpen;
		((struct Border *)ip)->BackPen = backpen;
		temp = (APTR) ((struct Border *)ip)->NextBorder;
		((struct Border *)ip)->NextBorder = NULL;
		DrawBorder( rp, (struct Border *) ip, (long) left, (long) top );
		((struct Border *)ip)->NextBorder = (struct Border *) temp;
		((struct Border *)ip)->FrontPen = pick;
		((struct Border *)ip)->BackPen = onoff;
		if( propborder ) {
		    ((struct Border *)ip)->LeftEdge -= 4;
		    ((struct Border *)ip)->TopEdge -= 2;
		}
		(struct Border *)ip = (struct Border *) temp;
	    } /* while */
	}
	(struct IntuiText *) ip = gp->GadgetText;
	while( (struct IntuiText *) ip ) {
	    pick = ((struct IntuiText *)ip)->FrontPen;
	    onoff = ((struct IntuiText *)ip)->BackPen;
	    ((struct IntuiText *)ip)->FrontPen = backpen;
	    ((struct IntuiText *)ip)->BackPen = backpen;
	    temp = (APTR) ((struct IntuiText *)ip)->NextText;
	    ((struct IntuiText *)ip)->NextText = NULL;
	    PrintIText( rp, (struct IntuiText *) ip, (long) left, (long) top );
	    ((struct IntuiText *)ip)->NextText = (struct IntuiText *) temp;
	    ((struct IntuiText *)ip)->FrontPen = pick;
	    ((struct IntuiText *)ip)->BackPen = onoff;
	    (struct IntuiText *)ip = (struct IntuiText *) temp;
	} /* while */
	    /* the actual strgadget string is rendered in the screen's font
	     * but initially using Screen->BarLayer->rp->Font
	     */
/*****
	if( (gp->GadgetType & ~GADGETTYPE) == STRGADGET ) {
	    sip = (struct StringInfo *) gp->SpecialInfo;
	    itext.BackPen = itext.FrontPen = backpen;
	    itext.DrawMode = JAM2;
	    itext.TopEdge = itext.LeftEdge = 0;
	    itext.ITextFont = window->WScreen->Font;
	    itext.IText = &sip->Buffer[sip->DispPos];
	    tempchar = itext.IText[sip->DispCount];
	    itext.IText[sip->DispCount] = '\0';
	    itext.NextText = NULL;
	    PrintIText( rp, &itext, (long) sip->CLeft, (long) sip->CTop );
	    itext.IText[sip->DispCount] = tempchar;
	}
*****/
	if( (gp->GadgetType & ~GADGETTYPE) == PROPGADGET
		|| (gp->GadgetType & ~GADGETTYPE) == STRGADGET ) {
	    image.LeftEdge = 0;
	    image.TopEdge = 0;
	    image.Width = gp->Width;
	    if( gp->Flags & GRELWIDTH ) {
		image.Width += req ? req->Width : window->Width;
	    }
	    image.Height = gp->Height;
	    if( gp->Flags & GRELHEIGHT ) {
		image.Height += req ? req->Height : window->Height;
	    }
	    image.Depth = 0;
	    image.ImageData = NULL;
	    image.PlanePick = 0;
	    image.PlaneOnOff = backpen;
	    image.NextImage = NULL;
	    DrawImage( rp, &image, (long) left, (long) top );
	}
    } /* for */
    return( 0 );
} /* clearGadgets */


short toggleBoolGadget( window, gp, req )
    struct Window	    *window;
    register struct Gadget  *gp;
    struct Requester	    *req;
{
    APTR	    temp;
    USHORT	    pos;
    SHORT	    pick, onoff;

#ifdef GIMME_WIMPY
    if( !window || !gp ) {
	return( -1 );
    }
#endif
    if( (gp->GadgetType & ~GADGETTYPE) != BOOLGADGET ) {
	return( 0 );
    }
    if( (pos = RemoveGadget(window, gp)) == (USHORT) -1 ) {
	return( -1 );
    }
    gp->NextGadget = NULL;
    if( gp->Flags & GADGIMAGE ) {
	clearGadgets( gp, window, req, 1 );
	temp = gp->GadgetRender;
	gp->GadgetRender = gp->SelectRender;
	gp->SelectRender = temp;
	gp->Width = ((struct Image *)gp->GadgetRender)->Width;
	gp->Height = ((struct Image *)gp->GadgetRender)->Height;
    } else {
	temp = (APTR) gp->GadgetText;
	gp->GadgetText = (struct IntuiText *) gp->SelectRender;
	gp->SelectRender = temp;
    }
    gp->Flags &= ~SELECTED;
    AddGList( window, gp, (long) pos, 1L, req );
    RefreshGList( gp, window, req, 1L );
    return( 0 );
} /* toggleBoolGadget */


struct Gadget *findGadget( gp, id )
    register struct Gadget  *gp;
    USHORT  id;
{
    for( ; gp; gp = gp->NextGadget ) {
	if( gp->GadgetID == id ) {
	    break;
	}
    } /* for */
    return( gp );
} /* findGadget */


struct Gadget *findMyFirstGadget( gp, id )
    register struct Gadget  *gp;
    USHORT  id;
{
    for( ; gp; gp = gp->NextGadget ) {
	if( gp->GadgetID > id ) {
	    break;
	}
    } /* for */
    return( gp );
} /* findMyFirstGadget */
