/*=======================================================================
  mp.c - Process the mouse on the screen.   and handle all mouse actions
========================================================================*/
 
/*  The usual header files to be inserted later  */
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/display.h>
#include <exec/memory.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <devices/narrator.h>
#include <devices/audio.h>
#include <libraries/translator.h>
#include "gad.h" 
 
/* --------------- change list -------------
 
6/10/86 - jd  Changed PropInfo flag setting to avoid crashing if none
          allocated.   Added new global "pflag" that holds the flags.
 
6/12/86 - jd  Changed proc_button() to change the border pairs when the
          gadget is re-sized.

11/15/86- RRL added a call to ClearAllTexts (in ITextEd.c) to remove old
          intuitexts when a gadget is moved to a new position
          
11/17/86- RRL moved the pflag setting to addgad.c
---------------------------------------------*/
 
/* extern vars */
 
extern int new_sel;
extern int pflag;
extern int curgad;
extern int nextgad;
extern int nextlink;
extern struct RastPort *rp;
extern struct Window *w;
extern struct NewWindow nw;
extern struct Gadget testgad;
 
extern struct Gadget *gads[];
extern struct IntuiText *Texts[];
extern struct PropInfo *props[];
extern struct StringInfo *strings[];
extern UBYTE *gadnames[];
extern UBYTE names [MAX_NUM_GADGETS]  [NAM_SIZ];
 
/* Extern functions */
 
extern UBYTE *getrname();
 
/* global vars */
 
int frst = 5;
int new_sel;
int rt_button;
int oldgad = FALSE;
int siz_flag;
SHORT Left, Top, Width, Height;
int erase;
int link = FALSE;    /* Do NOT link until told to */
 
/*=======================================================================
   Process the mouse movements,   this function gets called a lot,  so
  lets not dilly dally around folks,  just keep that line a movin
========================================================================*/
proc_mouse(addr, x, y)
APTR addr;                /* From IAddress field of IntuiMessage */
SHORT x, y;
{
    static SHORT OLeft, OTop, OWidth, OHeight;
    static SHORT Ox, Oy;  /* old mouse positions */
    long  flags;
 
    /* Because we may be re-drawing the boxes,  we have to restore the
       old box,  IE,  Last box drawn,  wherever that is */
    if (new_sel) {
       OLeft = Left;
       OWidth = Width;
       OTop = Top;
       OHeight = Height;
       Ox = x ;
       Oy = y ;
       new_sel = FALSE;
       /* Erase will be set TRUE, thus draw_box will be called */
    }
    x -= Ox ;
    y -= Oy ;
    Ox += x ;
    Oy += y ;
    if (rt_button) {                     /* $$$ */
 
       if (erase) {
          draw_box(rp, OLeft-1, OTop-1, OWidth, OHeight);
       }
       if (!siz_flag) Left += x;
       else Width += x ;
 
       if (!siz_flag) Top += y;
       else Height += y ;
 
       draw_box(rp, Left-1, Top-1, Width, Height);
       OLeft = Left;   OTop = Top;
       OWidth = Width; OHeight = Height;
       erase = TRUE;
    }
    else {
      /* If in the menu area,  then clear RMBTRAP */
      if (Oy < 11)
        w->Flags &= ~RMBTRAP;
      else
        w->Flags |= RMBTRAP;
    }
}
/*========================================================================
  Process the mouse when a button is pressed,  accepts the mouse location
  at the time the button was pressed, passed through from the Intuimessge
========================================================================*/
proc_button(code, x, y)
USHORT code;
SHORT x,y;
{
    int which;       /* Index into the gadget located by "findmouse" */
    static long Lf, Tp, Wd, Ht;
    struct PropInfo *pi;
    struct Border *bd;
    SHORT *pairs;
    long flags;
    UBYTE *str;
 
    if (code == MENUDOWN) {
        rt_button = TRUE;
        if ((which = findmouse(x,y)) == -1) {
          erase = FALSE;             /* Drawing new gadget */
          new_sel = FALSE;
          oldgad = FALSE;
          Left = x;  Top = y;        /* Creating a "New" gadget */
          Width = 0; Height = 0;     /* Starts at this coords */
          siz_flag = TRUE;           /* default mode */
 
          /* Clear out testgad structure */
          testgad.SpecialInfo = NULL;
          testgad.GadgetRender = NULL;
          testgad.SelectRender = NULL;
          testgad.GadgetText = NULL;
       }
       else {
          erase = TRUE;              /* We intend to re-draw current gad */
          if (in_corner(which, x, y)) {
              siz_flag = TRUE;
         }
         else  {
              siz_flag = FALSE;
         }
         /*  Select new CURRENT gadget */
          curgad = which;
          Left = gads[which]->LeftEdge;
          Top  = gads[which]->TopEdge;
          Width = gads[which]->Width;
          Height = gads[which]->Height;
 
          /* Mark spot where old rect is so we can clean it up */
          Lf = (long)(Left-1);
          Tp = (long)(Top-1);
          Wd = (long)Width;
          Ht = (long)Height;
 
          /* Snatch old gadget structure into temp structure  */
          testgad          = *gads[curgad];
 
          /* Set a few flags */
          oldgad = TRUE;
          new_sel = TRUE;     /* Used by proc_mouse to reload the OLD */
                              /*  Rectangle values to properly erase */
       }
       ModifyIDCMP(w, nw.IDCMPFlags);
    }
    if (code == MENUUP) {           /*  */
       rt_button = FALSE;
       link = TRUE;                 /* OK  you have permission */
       siz_flag = TRUE;             /* default mode */
       testgad.TopEdge = Top;
       testgad.LeftEdge = Left;
       testgad.Height = Height;
       testgad.Width = Width;
       frst = 5;                 /* remove later */
 
       /* We should prabably have an option here to change the border
          around the gadget if it gets re-sized.  We must check the
          option flag, if TRUE,  then change the "appropriate pairs"
          value in the gadget.
       */
       ModifyIDCMP(w, nw.IDCMPFlags);
       if (!oldgad && Width > 8 && Height > 4) {
            addgad();                 /* $$$ Allocate the gadget */
       }
      flags = (long)testgad.UserData;
 
       if ((testgad.GadgetType != PROPGADGET) &&
          ((flags & GAD_IMAGE_TYPE) != GAD_IMAGE_TYPE)) {
          bd = (struct Border *)testgad.GadgetRender;
          pairs = bd->XY;
          pairs[2] = pairs[4] = Width;
          pairs[5] = pairs[7] = Height;
       }
       if (gads[curgad] != NULL) {
          *gads[curgad] = testgad;       /* Update Gadget data */
 
           /* Force user to enter gadget name */
           if (gadnames[curgad] == NULL) {
             str = getrname("Enter Gadget name");
             strcpy(names[curgad], str);
             gadnames[curgad] = names[curgad];
           }
       }
       /* $$$ Erase the border - perhaps            */
/*         draw_box(rp, Left-1, Top-1, Width, Height);
          erase = FALSE;
*/
       /* ### Refresh the gadgets */
       if (nextlink == nextgad && nextlink != NULL) {
          draw_box(rp, Left-1, Top-1, Width, Height);
          SetAPen(rp, 0L);
          SetDrMd(rp, JAM1);
          /* remove old intuitexts */
          ClearAllTexts(gads[curgad],Lf+1L,Tp+1L);
          RectFill(rp, Lf-1L, Tp-1L, Lf+Wd+2L, Tp+Ht+2L);
          RefreshGadgets(gads[0], w, NULL);
       }
    }
}
/* ----------------------------------------------------------------------
  Find the location of the mouse and determine if it falls on any gadget,
  return an index into the gadget structure where the mouse is pointing
  to.  It involves searching each of the "Gadget" structures looking for
  a "LeftEdge/TopEdge" that falls "under" the mouse.
-----------------------------------------------------------------------*/
int findmouse(x, y)
SHORT x, y;           /* Coordinates of the mouse */
{
     int   ind = 0;  /* Index into Gadget pointer array */
     if (nextgad == NULL) return(-1);
 
     for (ind = 0;  ind < nextgad; ind++) {
        if (x >= gads[ind]->LeftEdge &&
           x <= (gads[ind]->LeftEdge + gads[ind]->Width) &&
           y >= gads[ind]->TopEdge &&
           y <= (gads[ind]->TopEdge + gads[ind]->Height))
          return(ind);
     }
     return(-1);
}
/*------------------------------------------------------------------------
  Determine if the mouse was pressed in the corner of the box, indicating
  that the user wants to change the gadget's size.
------------------------------------------------------------------------*/
int in_corner(which, x, y)
int which;                    /* Index to specific gadget */
SHORT x, y;                   /* Mouse location */
{
    SHORT left, top, deltx, delty;
 
    top  = y - gads[which]->Height;
    left = x - gads[which]->Width;
    deltx = gads[which]->LeftEdge - left;
    delty = gads[which]->TopEdge - top;
 
    if (deltx < 8 && deltx > -8 && delty < 6 && delty > -6)
       return(TRUE);
    else
       return(FALSE);
}
                                                                            