/*============================================================================*/
/*  Gadgets.c: By Kevin T. Seghetti					      */
/*============================================================================*/

#include "equates.h"
#include <functions.h>
#include <exec/types.h>
#include <intuition/intuition.h>

#include <graphics/gfx.h>

/*
#include "dot.dat"
*/

extern struct IntuiText *CreateIntuiText();

/*============================================================================*/
/*  AddGadgetsToList: Link two sets of gadgets together 		      */
/*  Inputs: MasterGList-> gadget list					      */
/*	    NewGlist-> gadget list					      */
/*  Description:							      */
/*	    links NewGList to the end of MasterGList			      */
/*============================================================================*/

AddGadgetsToList(MasterGList,NewGList)
struct Gadget *MasterGList,*NewGList;
{
    while(MasterGList->NextGadget)
	MasterGList = MasterGList->NextGadget;
MasterGList->NextGadget = NewGList;
}

/*============================================================================*/
/*  CreatePropGadget: create one proportional gadget			      */
/*  Inputs: LeftEdge = x offset in pixels from left edge of window	      */
/*	    TopEdge = y offset in pixels from top of current window	      */
/*	    Width = Width of gadget in pixels.				      */
/*	    Height = Height of gadget in pixels.			      */
/*	    GRemember-> IRemember structure pointer			      */
/*	    GNum = Number of gadget(GadgetID)                                 */
/*============================================================================*/

struct Gadget *
CreatePropGadget(LeftEdge,TopEdge,Width,Height,GRemember,GNum)
SHORT LeftEdge,TopEdge,Width,Height;
struct Remember **GRemember;
USHORT GNum;
{
    struct Gadget *TempGadget;
    struct PropInfo *TempPropInfo;
    struct Image *TempImage;
    TempGadget = (struct Gadget *)AllocRemember(GRemember,(long)sizeof(struct Gadget),MEMF_CLEAR);
    TempGadget->LeftEdge = LeftEdge;
    TempGadget->TopEdge = TopEdge;
    TempGadget->Width = Width;
    TempGadget->Height = Height;
    TempGadget->GadgetType = PROPGADGET;
    TempGadget->Flags = GADGHNONE;
    TempGadget->Activation = GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE;
    TempGadget->GadgetID = GNum;

    TempPropInfo = (struct PropInfo *)AllocRemember(GRemember,(long)sizeof(struct PropInfo),MEMF_CLEAR);

    TempPropInfo->Flags = AUTOKNOB|FREEVERT;
    TempPropInfo->HorizPot = -1;
    TempPropInfo->VertPot = 30947;
    TempPropInfo->HorizBody = -1;
    TempPropInfo->VertBody = BODYVALUE; 	     /* was 0XFFFF/15 */

    TempGadget->SpecialInfo = (APTR)TempPropInfo;

    TempImage = (struct Image *)AllocRemember(GRemember,(long)sizeof(struct Image),MEMF_CLEAR);

    TempGadget->GadgetRender = (APTR)TempImage;

    TempImage->Width = 10;
    TempImage->Height = 50;

    return(TempGadget);
}

/*============================================================================*/
/*  DrawColoredBox: draws a colored box into a window			      */
/*  Not really a gadget, but used for palette gadgets			      */
/*  Inputs: rp->RastPort						      */
/*	    color = color # to fill with				      */
/*	    x = x offset from rastport					      */
/*	    y = y offset from rastport					      */
/*	    width = width of box					      */
/*									      */
/*  Bugs:								      */
/*	    height is hardwired in					      */
/*============================================================================*/

DrawColoredBox(rp,color,x,y,width)
struct RastPort *rp;
long x,y,color,width;
{
    SetAPen(rp,color);
    RectFill(rp,x,y,x+width,y+5);
}

/*============================================================================*/
/* DrawColoredRow: draw vertical row of colored boxes, with incremental color */
/*  Inputs:								      */
/*	rp->RastPort							      */
/*	Count = # of boxes to draw					      */
/*	LeftEdge = x offset from RastPort				      */
/*	TopEdge = y offset from RastPort				      */
/*	Width = Width of box						      */
/*	StartColor = color to start at					      */
/*  Bugs:								      */
/*	height and color offset are hard-wired				      */
/*============================================================================*/

DrawColoredRow(rp,Count,LeftEdge,TopEdge,Width,StartColor)
struct RastPort *rp;
int Count;
long StartColor;
long LeftEdge,TopEdge,Width;
{
    long i;
    for(i=0;i<Count;++i)
     {
	DrawColoredBox(rp,StartColor+i,LeftEdge,TopEdge+(i*8),Width);
     }
}

/*============================================================================*/
/*  CreateInvisibleGadget: creates a button that cannot be seen 	      */
/*  Inputs: LeftEdge = x offset in pixels from left edge of window	      */
/*	    TopEdge = y offset in pixels from top of current window	      */
/*	    Width = Width of gadget in pixels.				      */
/*	    Height = Height of gadget in pixels.			      */
/*	    GRemember-> IRemember structure pointer			      */
/*	    GNum = Number of gadget(GadgetID)                                 */
/*============================================================================*/

struct Gadget *
CreateInvisibleGadget(LeftEdge,TopEdge,Width,Height,GRemember,GNum)
SHORT LeftEdge,TopEdge,Width,Height;
USHORT GNum;
struct Remember **GRemember;
{
    struct Gadget *HitGadget;
    int i;

/*----------------------------------------------------------------------------*/
/*  since I cleared the allocated area, NextGadget, GadgetRender,	      */
/* SelectRender,MutualExclude,SpecialInfo,UserData all get set to zero	      */
/*----------------------------------------------------------------------------*/

    HitGadget = (struct Gadget *)AllocRemember(GRemember,(long)sizeof(struct Gadget),MEMF_CLEAR);
    if(!HitGadget)
	cleanup("No memory for Gadget structure",ERR_NOMEM);

    HitGadget->LeftEdge = LeftEdge;
    HitGadget->TopEdge = TopEdge;
    HitGadget->Width = Width;
    HitGadget->Height = Height;
    HitGadget->Flags = GADGHNONE;
    HitGadget->Activation = RELVERIFY;
    HitGadget->GadgetType = BOOLGADGET;
    HitGadget->GadgetRender = NULL;
    HitGadget->GadgetID = GNum;
    return(HitGadget);
}

/*============================================================================*/
/*  CreateInvisibleGadgets: creates a vertical stack of invisible gadgets     */
/*  Inputs: Count = # of gadgets to create				      */
/*	    LeftEdge = x offset in pixels from left edge of window	      */
/*	    TopEdge = y offset in pixels from top of current window	      */
/*	    Width = Width of gadget in pixels.				      */
/*	    Height = Height of gadget in pixels.			      */
/*	    GRemember-> IRemember structure pointer			      */
/*	    GNum = Number of gadget(GadgetID)                                 */
/*============================================================================*/

struct Gadget *
CreateInvisibleGadgets(Count,LeftEdge,TopEdge,Width,Height,GRemember,GNum)
SHORT LeftEdge,TopEdge,Width,Height;
USHORT GNum;
int Count;
struct Remember **GRemember;
{
    struct Gadget *LastGadget,*TempGadget,*FirstGadget;
    int i;

    FirstGadget = NULL;
    LastGadget = NULL;

    for(i=0;i<Count;++i)
     {
	TempGadget = CreateInvisibleGadget(LeftEdge,TopEdge+(i*(Height+2)),Width,Height,GRemember,GNum+i);

	if(!FirstGadget)
	    FirstGadget = TempGadget;
	else
	    LastGadget->NextGadget = TempGadget;
	LastGadget = TempGadget;
     }
    return(FirstGadget);
}

/*============================================================================*/
/*  CreateTextGadget: creates a button containing a single line of text       */
/*  with a border drawn around it					      */
/*  Inputs: text-> to null terminated text string			      */
/*	    LeftEdge = x offset in pixels from left edge of window	      */
/*	    TopEdge = y offset in pixels from top of current window	      */
/*	    GRemember-> IRemember structure pointer			      */
/*	    GNum = Number of gadget(GadgetID)                                 */
/*  Description:							      */
/*	Will determine width from text, height is hard-wired		      */
/*============================================================================*/

struct Gadget *
CreateTextGadget(text,LeftEdge,TopEdge,GRemember,GNum)
SHORT LeftEdge,TopEdge;
USHORT GNum;
char *text;
struct Remember **GRemember;
{
    struct Gadget *HitGadget;
    struct Border *HitBorder;
    SHORT Width;
    SHORT *HitXY;
    int i;

    Width = 2+strlen(text)*8;

    HitXY = (SHORT *)AllocRemember(GRemember,(long)(sizeof(SHORT)*10),NULL);
    if(!HitXY)
	cleanup("no memory for gadget Border XY table",ERR_NOMEM);

    *(HitXY) = -1;
    *(HitXY+1) = -1;

    *(HitXY+2) = -1;
    *(HitXY+3) = 9;

    *(HitXY+5) = 9;

    *(HitXY+7) = -1;

    *(HitXY+8) = -1;
    *(HitXY+9) = -1;

    HitBorder = (struct Border *)AllocRemember(GRemember,(long)sizeof(struct Border),MEMF_CLEAR);
    if(!HitBorder)
	cleanup("no memory for gadget Border structure",ERR_NOMEM);
    HitBorder->FrontPen =1;
    HitBorder->Count = 5;
    HitBorder->XY = HitXY;
    *(HitXY+4) = Width;
    *(HitXY+6) = Width;

/*----------------------------------------------------------------------------*/
/*  since I cleared the allocated area, NextGadget, GadgetRender, SelectRender*/
/*  MutualExclude,SpecialInfo,GadgetID,UserData,LeftEdge and TopEdge all get  */
/*  set to zero 							      */
/*----------------------------------------------------------------------------*/

    HitGadget = (struct Gadget *)AllocRemember(GRemember,(long)sizeof(struct Gadget),MEMF_CLEAR);
    if(!HitGadget)
	cleanup("No memory for Gadget structure",ERR_NOMEM);

    HitGadget->LeftEdge = LeftEdge;
    HitGadget->TopEdge = TopEdge;
    HitGadget->Width = Width;
    HitGadget->Height = 9;
    HitGadget->Flags = GADGHCOMP;
    HitGadget->Activation = RELVERIFY;
    HitGadget->GadgetType = BOOLGADGET;
    HitGadget->GadgetText = CreateIntuiText(text,GRemember);
    HitGadget->GadgetText->DrawMode = JAM1;
    HitGadget->GadgetText->TopEdge = 1;
    HitGadget->GadgetText->LeftEdge = 1;
    HitGadget->GadgetRender = (APTR)HitBorder;
    HitGadget->GadgetID = GNum;

    return(HitGadget);
}

/*============================================================================*/
/*  CreateTextGadgets: creates a list of buttons containing a single line of  */
/*  text with a border drawn around it					      */
/*  Inputs: text-> to array of null terminated text strings		      */
/*	    LeftEdge = x offset in pixels from left edge of window	      */
/*	    TopEdge = y offset in pixels from top of current window	      */
/*	    GRemember-> IRemember structure pointer			      */
/*	    GNum = Number of gadget(GadgetID)                                 */
/*  Description:							      */
/*	Will determine width from text, height is hard-wired		      */
/*============================================================================*/

struct Gadget *
CreateTextGadgets(text,LeftEdge,TopEdge,GRemember,GBase)
SHORT LeftEdge,TopEdge;
USHORT GBase;
char *text[];
struct Remember **GRemember;
{
    struct Gadget *FirstGadget,*TempGadget,*LastGadget;
    int i;

    i = 0;
    FirstGadget = NULL;
    LastGadget = NULL;

    while(text[i])
     {
	TempGadget = CreateTextGadget(text[i],LeftEdge,TopEdge+(i*12),GRemember,GBase+i);
	if(!FirstGadget)
	    FirstGadget = TempGadget;
	else
	    LastGadget->NextGadget = TempGadget;
	LastGadget = TempGadget;
	++i;
     }
    return(FirstGadget);
}

/*============================================================================*/
/*  CreateIntGadget: creates one integer gadget 			      */
/*  Inputs: StartVal = number to seed gadget with, in ascii(stupid Intuition) */
/*	    LeftEdge = x offset in pixels from left edge of window	      */
/*	    TopEdge = y offset in pixels from top of current window	      */
/*	    GRemember-> IRemember structure pointer			      */
/*	    GNum = Number of gadget(GadgetID)                                 */
/*============================================================================*/

struct Gadget *
CreateIntGadget(StartVal,LeftEdge,TopEdge,GRemember,GNum)
char *StartVal;
SHORT LeftEdge,TopEdge;
USHORT GNum;
struct Remember **GRemember;
{
    struct Gadget *IntGadget;
    struct Border *IntBorder;
    struct StringInfo *IntInfo;

    SHORT Width;
    SHORT *IntXY;
    int i;

/*    Width = 2+strlen(StartVal)*8; */      /* this is more general purpose */
    Width = 2+(4*8);

    IntXY = (SHORT *)AllocRemember(GRemember,(long)(sizeof(SHORT)*10),NULL);
    if(!IntXY)
	cleanup("no memory for gadget Border XY table",ERR_NOMEM);

    *(IntXY) = -1;
    *(IntXY+1) = -1;

    *(IntXY+2) = -1;
    *(IntXY+3) = 9;

    *(IntXY+5) = 9;

    *(IntXY+7) = -1;

    *(IntXY+8) = -1;
    *(IntXY+9) = -1;

    IntBorder = (struct Border *)AllocRemember(GRemember,(long)sizeof(struct Border),MEMF_CLEAR);
    if(!IntBorder)
	cleanup("no memory for gadget Border structure",ERR_NOMEM);
    IntBorder->FrontPen =1;
    IntBorder->Count = 5;
    IntBorder->XY = IntXY;
    *(IntXY+4) = Width;
    *(IntXY+6) = Width;

/*----------------------------------------------------------------------------*/
/*  since I cleared the allocated area, NextGadget, GadgetRender, SelectRender*/
/*  MutualExclude,SpecialInfo,GadgetID,UserData,LeftEdge and TopEdge all get  */
/*  set to zero 							      */
/*----------------------------------------------------------------------------*/

    IntGadget = (struct Gadget *)AllocRemember(GRemember,(long)sizeof(struct Gadget),MEMF_CLEAR);
    if(!IntGadget)
	cleanup("No memory for Gadget structure",ERR_NOMEM);

    IntGadget->LeftEdge = LeftEdge;
    IntGadget->TopEdge = TopEdge;
    IntGadget->Width = Width;
    IntGadget->Height = 9;
    IntGadget->Flags = GADGHCOMP|LONGINT;
    IntGadget->Activation = RELVERIFY|LONGINT;
    IntGadget->GadgetType = STRGADGET;

    IntGadget->GadgetRender = (APTR)IntBorder;
    IntGadget->GadgetID = GNum;

    IntInfo = (struct StringInfo *)AllocRemember(GRemember,(long)sizeof(struct StringInfo),MEMF_CLEAR);

    IntInfo->Buffer = (UBYTE *)AllocRemember(GRemember,20L,MEMF_CLEAR);
    strcpy(IntInfo->Buffer,StartVal);
    IntInfo->MaxChars = 4;

    IntGadget->SpecialInfo = (APTR)IntInfo;

    return(IntGadget);
}

