/*---------------------------------------------------*
  $Id: button.c,v 1.1 93/01/18 00:17:25 tf Exp $
  Intuition support functions for buttons and borders
  written 1992 by Tobias Ferber, All Rights Reserved
 *---------------------------------------------------*/

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>

#define FRONTPEN    1
#define BACKPEN     0
#define SHINEPEN    2
#define SHADOWPEN   1

#define SYSMEMTYPE  (MEMF_PUBLIC|MEMF_CLEAR)
#define BORDERSIZE  (sizeof(struct Border))
#define XYSIZE      (2*5*sizeof(WORD))
#define GADGETSIZE  (sizeof(struct Gadget))
#define ITEXTSIZE   (sizeof(struct IntuiText))

static struct TextAttr Topaz80= {
  (STRPTR) "topaz.font",  /* ta_Name  */
  8,                      /* ta_YSize */
  FS_NORMAL,              /* ta_Style */
  FPF_ROMFONT,            /* ta_Flags */
};

void FreeBorder(struct Border *b)
{ if(b != (struct Border *)NULL)
  { if(b->NextBorder)
      FreeMem(b->NextBorder,BORDERSIZE);
    if(b->XY)
      FreeMem(b->XY, XYSIZE);
    FreeMem(b,BORDERSIZE);
  }
}

struct Border *CreateBorder(x,y,w,h)
WORD x,y,w,h;
{
  struct Border *tl, *br;  /* TopLeft, BottomRight */
  WORD *xy;

  if(tl= (struct Border *)AllocMem(BORDERSIZE,SYSMEMTYPE))
  {
    if(br= (struct Border *)AllocMem(BORDERSIZE,SYSMEMTYPE))
    {
      if(xy= (WORD *)AllocMem(2*XYSIZE,SYSMEMTYPE))
      {
        --w;
        --h;

        /* shining edges */
        xy[0]= w-1;   xy[1]= 0;       /*  ++++++++++++  */
        xy[2]= 0;     xy[3]= 0;       /*  ++            */
        xy[4]= 0;     xy[5]= h;       /*  ++            */
        xy[6]= 1;     xy[7]= h-1;     /*  ++            */
        xy[8]= 1;     xy[9]= 1;       /*  +             */

        /* shadow edges */
        xy[10]= 1;    xy[11]= h;      /*              + */
        xy[12]= w;    xy[13]= h;      /*             ++ */
        xy[14]= w;    xy[15]= 0;      /*             ++ */
        xy[16]= w-1;  xy[17]= 1;      /*             ++ */
        xy[18]= w-1;  xy[19]= h-1;    /*   ++++++++++++ */

        /* top, left (shining) border */
        tl->LeftEdge   = x;
        tl->TopEdge    = y;
        tl->FrontPen   = SHINEPEN;
        tl->BackPen    = 0;
        tl->DrawMode   = JAM1;
        tl->Count      = 5;
        tl->XY         = &xy[0];
        tl->NextBorder = br;

        /* bottom, right (shadow) border */
        br->LeftEdge   = x;
        br->TopEdge    = y;
        br->FrontPen   = SHADOWPEN;
        br->BackPen    = 0;
        br->DrawMode   = JAM1;
        br->Count      = 5;
        br->XY         = &xy[10];
        br->NextBorder = (struct Border *)NULL;
        return(tl);
      }
      FreeMem(br,BORDERSIZE);
    }
    FreeMem(tl,BORDERSIZE);
  }
  return((struct Border *)NULL);
}


void FreeButton(struct Gadget *g)
{ if(g != (struct Gadget *)NULL)
  { if(g->GadgetText)
      FreeMem(g->GadgetText, ITEXTSIZE);
    if(g->GadgetRender)
      FreeBorder(g->GadgetRender);
    FreeMem(g,GADGETSIZE);
  }
}


struct Gadget *CreateButton(x,y,w,h, text, id)
WORD x,y,w,h;
STRPTR text;
ULONG id;
{
  struct Gadget *g;
  struct IntuiText *it;
  struct TextFont *tf;

  if(g= (struct Gadget *)AllocMem(GADGETSIZE,SYSMEMTYPE))
  {
    if(it= (struct IntuiText *)AllocMem(ITEXTSIZE,SYSMEMTYPE))
    {
      it->FrontPen     = FRONTPEN;
      it->BackPen      = BACKPEN;
      it->DrawMode     = JAM1;
      it->ITextFont    = &Topaz80;
      it->IText        = text;
      it->NextText     = (struct IntuiText *)NULL;

      if(tf= (struct TextFont *)OpenFont(&Topaz80))
      { it->LeftEdge   = (w-strlen(text)*tf->tf_XSize)/2;
        it->TopEdge    = (h-tf->tf_Baseline)/2;
        CloseFont(tf);
      }
      else /* use known topaz80 dimensions */
      { it->LeftEdge   = (w-strlen(text)*8)/2;
        it->TopEdge    = (h-6)/2;
      }

      g->NextGadget    = (struct Gadget *)NULL;
      g->LeftEdge      = x;
      g->TopEdge       = y;
      g->Width         = w;
      g->Height        = h;
      g->Flags         = GADGHCOMP;
      g->Activation    = GADGIMMEDIATE|RELVERIFY;
      g->GadgetType    = BOOLGADGET;
      g->GadgetRender  = (APTR)CreateBorder(0,0,w,h);
      g->SelectRender  = (APTR)NULL;
      g->GadgetText    = it;
      g->MutualExclude = (LONG)0L;
      g->SpecialInfo   = (APTR)NULL;
      g->GadgetID      = id;
      g->UserData      = (APTR)NULL;
      return(g);
    }
    FreeMem(g,GADGETSIZE);
  }
  return((struct Gadget *)NULL);
}


void ToggleButton(struct Window *w, struct Gadget *g)
{ short pos= RemoveGadget(w,g);
  RefreshGList(g,w,0L,1L);
  g->Flags ^= SELECTED;
  if(pos>=0) AddGadget(w,g,pos);
  RefreshGList(g,w,0L,1L);
}
