/*
** ROUTINES.CB
**
** This file contains macros that allow a programmer to select a
** BASIC SUB or FUNCTION procedure or label from a menu and then go to it.
** Lines with labels must have the : as the last character, a space or comment
** after it on the same line will cause the macro to skip that label.
*/

#include "dialog.h"

int    _r_line;
int   mh_num_cols,
      mh_max_width,
      mh_line,
      mh_menu_buf,
      mh_flag;

string mh_name,
       mh_ext,
       mh_buf;


void routines ()
{
    int    menu_buf,
            old_buf_id,
            max_width,
            line,
            loc,
         s,
         flag = 0;

    string    menu_line,
                routine_name;

    _r_line = 0;
    save_position ();
    top_of_buffer ();
    old_buf_id = inq_buffer ();
    menu_buf = create_buffer ("Labels by MH", NULL, 1);
    message ("Scanning for routines...");

   while (search_fwd("{<{SUB }|{FUNCTION }}|{:>}"))
      {
         routine_name = trim(read());
         if (routine_name == ":")
            {
               move_abs(0,1);
               routine_name = trim(read());
               move_rel(1);
               flag=1;
            }
         else
            {
               if (upper(read(4)) == "SUB ")
                  {
                     loc = search_string ("(",routine_name) - 5;
                     routine_name = substr(routine_name,5,loc);
                     flag=1;
                  }
               else
                  {
                     loc = search_string ("(",routine_name) - 10;
                     routine_name = substr(routine_name,10,loc);
                     flag=1;
                  }
            }
         if (flag == 1)
            {
                  _r_line++;
                  message ("Scanning for routines [#%d]...", _r_line);

                  inq_position (line);

                  if (strlen (routine_name) > max_width)
                      max_width = strlen (routine_name);

                  set_buffer (menu_buf);
                  insert ("\n%s\t%d;", routine_name, line);
                  set_buffer (old_buf_id);
               flag = 0;
              }
         next_char();
      }

    _r_line = 0;
    restore_position ();
    set_buffer (menu_buf);
    inq_position (line);
    top_of_buffer ();

    if (line > 1)
        {
        int    num_lines,
                num_cols;

        delete_line ();
        tabs (80);

        inq_screen_size (num_lines, num_cols);

        if ((line += 3) > (num_lines - 5))
            line = num_lines - 5;

        if ((max_width += 2) < 15)
            max_width = 15;

        if (max_width >= num_cols - 3)
            max_width = num_cols - 3;

        max_width = (max_width + 1) / 2;
        num_cols = (num_cols + 1 ) / 2;

        set_buffer (old_buf_id);

      mh_num_cols = num_cols;
      mh_max_width = max_width;
      mh_line = line;
      mh_menu_buf = menu_buf;
      mh_flag = 1;

      inq_names(mh_name,mh_ext,mh_buf);

        _process_menu (num_cols - max_width, line, num_cols + max_width, 3, NULL, "", NULL, menu_buf, "_r_action", TRUE);

        if (_r_line)
            goto_line (_r_line);
        }
    else
        {
        set_buffer (old_buf_id);
        delete_buffer (menu_buf);
        message ("No routines found.");
      mh_flag = 0;
        }
}

/*
**        _r_action:
**
**        This routine is called by the dialog manager when a routine is
**    selected.
*/

int _r_action (int event_type, ...)
{
    string button_text;

    get_parm (0, event_type);


    switch (event_type)
        {
        case DIALOG_PICK_MENU:
        case DIALOG_F10:
            {
            get_parm (2, button_text);
            _r_line = atoi (substr (button_text, rindex (button_text, "\t") + 1));
            _dialog_esc ();
            }
        }
    returns (TRUE);
}

void rerout()
{
   string mh_n,mh_e,mh_b;

   inq_names(mh_n,mh_e,mh_b);

   if (mh_flag == 0 || mh_n != mh_name || mh_e != mh_ext || mh_b != mh_buf)
      {
         error ("No previous routines found.");
      }
   else
      {
         _process_menu (mh_num_cols - mh_max_width, mh_line, mh_num_cols + mh_max_width, 3, NULL, "", NULL, mh_menu_buf, "_r_action", TRUE);
           if (_r_line)
               goto_line (_r_line);
      }
}
