
/**************************************************************************
 *
 * AESFAST PD utilties
 *
 *  AESUTFM1 - Forms processing utilties.
 *    frm_dsdial - Form Dynamic String Dialog.
 *************************************************************************/

#if 0                       /* Set to 0 if not using GemFast system */
  #include <gemfast.h>
#else
  #include <gemdefs.h>
  #include <obdefs.h>
#endif

#ifndef NULL
#define NULL 0L
#endif

#ifndef TRUE
#define TRUE  1
#define FALSE 0
#endif

#define MAX_BUTTONS 5
#define MAX_STRINGS 20

/*-------------------------------------------------------------------------
 * Object tree for dynamic dialog box...
 *-----------------------------------------------------------------------*/
 
static OBJECT dialtree[] = {
  -1,  1, 21, G_BOX,    NONE,   OUTLINED, 0x00021100L, 0x0000, 0x0000, 0x0021, 0x0017,
   2, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0001, 0x0001, 0x0001,
   3, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0002, 0x0001, 0x0001,
   4, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0003, 0x0001, 0x0001,
   5, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0004, 0x0001, 0x0001,
   6, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0005, 0x0001, 0x0001,
   7, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0006, 0x0001, 0x0001,
   8, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0007, 0x0001, 0x0001,
   9, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0008, 0x0001, 0x0001,
  10, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0009, 0x0001, 0x0001,
  11, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x000A, 0x0001, 0x0001,
  12, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x000B, 0x0001, 0x0001,
  13, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x000C, 0x0001, 0x0001,
  14, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x000D, 0x0001, 0x0001,
  15, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x000E, 0x0001, 0x0001,
  16, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x000F, 0x0001, 0x0001,
  17, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0010, 0x0001, 0x0001,
  18, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0011, 0x0001, 0x0001,
  19, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0012, 0x0001, 0x0001,
  20, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0013, 0x0001, 0x0001,
  21, -1, -1, G_STRING, NONE,   NORMAL,   NULL,        0x0001, 0x0014, 0x0001, 0x0001,
   0, 22, 26, G_IBOX,   NONE,   NORMAL,   0x00001100L, 0x0001, 0x0015, 0x0001, 0x0001,
  23, -1, -1, G_BUTTON, 0x0005, NORMAL,   NULL,        0x0000, 0x0000, 0x0001, 0x0001,
  24, -1, -1, G_BUTTON, 0x0005, NORMAL,   NULL,        0x0000, 0x0000, 0x0001, 0x0001,
  25, -1, -1, G_BUTTON, 0x0005, NORMAL,   NULL,        0x0000, 0x0000, 0x0001, 0x0001,
  26, -1, -1, G_BUTTON, 0x0005, NORMAL,   NULL,        0x0000, 0x0000, 0x0001, 0x0001,
  21, -1, -1, G_BUTTON, 0x0025, NORMAL,   NULL,        0x0000, 0x0000, 0x0001, 0x0001
  };                                            

#define DIALSTL1 1      /* String Line 1                */
#define DIALPBXB 21     /* Parent Box for exit buttons  */
#define DIALBX01 22     /* First exit button            */

/**************************************************************************
 *
 * count_strings - Count strings and keep track of the longest one.
 *
 *************************************************************************/

static int
count_strings(pstrings, maxstrings, pmaxlen)
    register char   **pstrings;
    register int    maxstrings;
    int             *pmaxlen;
{
    register int    numstrings;
    register int    wrklen;
    register int    maxlen;
    
    for (numstrings = 0, maxlen = 0; 
         numstrings < maxstrings && **pstrings != 0x00; 
         numstrings++,
         pstrings++) {

            if (maxlen < (wrklen = strlen(*pstrings))) {
                maxlen = wrklen;
            }
    }
    
    *pmaxlen = maxlen;
    return numstrings;
}
       
/**************************************************************************
 *
 * frm_dsdial - Form dynamic string dialog.
 *
 *************************************************************************/

int
frm_dsdial(pstrings, pbuttons, graphicsflag)
    char             *pstrings[];
    char             *pbuttons[];
    int              graphicsflag;
{
    int              dmy;
    int              xbwidth;
    int              slen;
    register int     sizechar;
    register int     counter;
    register int     numobs;
    register int     pixlen;
    register OBJECT  *ptree;
    register char    **pwrk;
    static   int     initdone = 0;
    static   int     wchar;
    static   int     hchar;
    
/*-------------------------------------------------------------------------
 * Init the xywh values in the object tree, get the system character sizes
 * for later usage, adjust the top line to be 1/2 char up from the rest. 
 *-----------------------------------------------------------------------*/

    if (!initdone) {
        initdone = 1;
#ifdef AESFAST_A
        rsc_treefix(dialtree);
#else
        ptree = dialtree;
        for (counter = 0; (ptree[counter].ob_flags & LASTOB) == FALSE; counter++) {
            rsrc_obfix(ptree, counter);
        }
#endif
        graf_handle(&wchar, &hchar, &dmy, &dmy);
        dialtree[DIALSTL1].ob_y -= (hchar >> 1);       
    }

/*-------------------------------------------------------------------------
 * Count the button strings, find the longest one, distribute the buttons
 * evenly within their parent box, make the rightmost the default button.
 * (We place a gutter of 2 character widths on each side of each button.) 
 *-----------------------------------------------------------------------*/

    {
        register int obx;

        numobs = count_strings(pbuttons, MAX_BUTTONS, &slen);

        sizechar = wchar;
        pixlen   = (slen + 2) * sizechar;
        sizechar <<= 1;
        xbwidth  = (numobs * pixlen) + ((numobs + 1) * sizechar);
        
        for (counter   = 0, 
               obx     = sizechar,
               pwrk    = pbuttons, 
               ptree   = &dialtree[DIALBX01]
               ;
             counter < MAX_BUTTONS
               ; 
             counter++, 
               obx += pixlen + sizechar,
               ptree++ 
               ) {

            ptree->ob_flags &= ~DEFAULT;

            if (counter < numobs) {
                ptree->ob_flags &= ~HIDETREE;
                ptree->ob_x     = obx;
                ptree->ob_spec  = (long)*pwrk++;
                ptree->ob_width = pixlen;
            } else {
                ptree->ob_flags |= HIDETREE;
            }
        }
    
    dialtree[DIALPBXB+numobs].ob_flags |= DEFAULT;
    
    }
     
/*-------------------------------------------------------------------------
 * Count the dialog strings, find the largest, calc the size of the 
 * dialog box and the placement of the buttons at the bottom.  If space
 * permits, we leave a 1-line gutter between the last dialog string and
 * the buttons, but if all 20 dialog strings are used, then the buttons
 * are jammed right up against the bottom string.
 *-----------------------------------------------------------------------*/

    { 
        register int btnadjust;
        
        numobs    = count_strings(pstrings, MAX_STRINGS, &slen);

        btnadjust = (numobs < MAX_STRINGS); /* button padding, if space allows */
    
        pixlen    = (slen + 2) * wchar;
        pixlen    = (pixlen > xbwidth) ? pixlen : xbwidth;

        sizechar  = hchar;
        
        ptree            = dialtree;
        ptree->ob_width  = pixlen;
        ptree->ob_height = (numobs + 3 + btnadjust) * sizechar;

        ptree            = &dialtree[DIALPBXB];
        ptree->ob_x      = (pixlen - xbwidth) >> 1;
        ptree->ob_y      = ((numobs + 1 + btnadjust) * sizechar) + (sizechar >> 2);
        ptree->ob_width  = xbwidth;
    }
    
/*-------------------------------------------------------------------------
 * Set the ob_width and ob_spec for all the active strings in the dialog
 * box, set all the inactive strings to HIDETREE.
 *-----------------------------------------------------------------------*/

    for (counter = 0,
           pwrk  = pstrings,
           ptree = &dialtree[DIALSTL1]
           ; 
         counter < MAX_STRINGS; 
         counter++, 
           ptree++
           ) {

        if (counter < numobs) {
            ptree->ob_flags &= ~HIDETREE;
            ptree->ob_spec   = (long)*pwrk++;
            ptree->ob_width  = pixlen;
        } else {
            ptree->ob_flags |= HIDETREE;
        }
    }

/*-------------------------------------------------------------------------
 * Do dialog, return button number adjusted to range of 0-4.
 *-----------------------------------------------------------------------*/

    {
        register int selection;
        GRECT        dialrect;
        
        ptree = dialtree;
    
        form_center(ptree, 
                    &dialrect.g_x, &dialrect.g_y, 
                    &dialrect.g_w, &dialrect.g_h);

        form_dial(FMD_START, 0L, 0L, dialrect);
        if (graphicsflag) {
            form_dial(FMD_GROW, 0L, 0L, dialrect);
        }
        objc_draw(ptree, 9L, dialrect);
        selection = form_do(ptree, 0);
        if (graphicsflag) {
            form_dial(FMD_SHRINK, 0L, 0L, dialrect);
        }
        form_dial(FMD_FINISH, 0L, 0L, dialrect);
        ptree[selection].ob_state &= ~SELECTED;
    
        return (selection - DIALBX01);

    }
}

            
