
/* createmenu.c
 *
 * Wimp function library
 *  Joseph Heenan, 1998.
 *
 *
 *
 *
 * $Log: createmenu,v $
 * Revision 1.4  1998/07/18 15:44:26  joseph
 * Added supported for dashlines in menus
 *
 * Revision 1.3  1998/06/06 21:49:56  joseph
 * menuread and menufade added
 * createmenu changed to allow raw mode and seperator to be specified
 *
 * Revision 1.2  1998/05/10 20:13:10  jogu
 * Added names to file headers
 * Added implicit cast for frontend_taskname to wimp_report_error
 *   (it defines 'name' without 'const')
 *
 * Revision 1.1.1.1  1998/05/10 19:56:03  jogu
 * WimpCLib V1.00 (created from newshound c.wimpc rev 1.2)
 *
 *
 */

#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "swis.h"
#include "wimplib.h"

#include "wimpclib.h"


/* wimpc_createmenu( title, entries, ... )
 *
 * Takes a entries in the format of '>Info,!>Start...,Quit' with ... containing
 * window handles for >'s.
 * Flags are : !->
 * If multiple flags, must be in order shown.
 * ! = faded, > = has submenu, - = dash after
 */

WimpMenu *wimpc_createmenu( int raw, char sep, const char *title, const char *entries, ... )
{
  WimpMenu     *menu;
  WimpMenuItem *entry;
  va_list va;
  const char *ptr = entries-1, *oldptr=entries;
  int no = 0, item, len, maxlen = 1;
  int extramem=0; /* for indirected entries */
  char *indirected;
  const unsigned int itemcolour = (WimpIcon_FGColour*7) | (WimpIcon_BGColour*0);

  do
  {
    ptr = strchr( ptr+1, sep );
    len = ptr ? ptr-oldptr : strlen(oldptr);
    if ( !raw )
    {
      if ( *oldptr == '!' ) { len--; oldptr++; }
      if ( *oldptr == '-' ) { len--; oldptr++; }
      if ( *oldptr == '>' ) { len--; oldptr++; }
    }
    if ( len > 12 ) extramem += len+1;
    if ( len > maxlen ) maxlen = len;
    oldptr = ptr + 1;
    no++;
  }
  while (ptr);

  menu = malloc( sizeof(WimpMenu) + sizeof(WimpMenuItem) * (no-1) + extramem );
  if ( !menu ) return NULL;

  indirected = (char *)menu + sizeof(WimpMenu) + sizeof(WimpMenuItem) * (no-1);

  *menu->title=0;
  strncat( menu->title, title, sizeof menu->title - 1 ); /* max len 11 chars + terminator */
  menu->title_fg    = 7; /* black */
  menu->title_bg    = 2; /* greyey :-) */
  menu->work_fg     = 7;
  menu->work_bg     = 0;
  menu->item_width  = maxlen * 16;
  menu->item_height = 44;
  menu->gap	    = 0;

  item  = 0;
  ptr   = entries;
  va_start( va, entries );

  while ( item < no )
  {
    entry = &menu->items[item++];

    entry->icon_flags         = WimpIcon_Text | WimpIcon_VCentred | itemcolour;
    if ( !raw && *ptr == '!' ) { ptr++; entry->icon_flags |= WimpIcon_Shaded; }

    entry->flags              = item==no ? WimpMenuItem_Last : 0;
    if ( !raw && *ptr == '-' ) { ptr++; entry->flags |= WimpMenuItem_DottedLine; }

    entry->submenu_or_window  = (!raw && *ptr=='>') ? ptr++, (void *) va_arg(va, int) : (void *) -1;

    *entry->icon_data.t = 0;
    len = item < no ? strchr( ptr, sep ) - ptr : strlen( ptr );

    if ( len > 12 )
    {
      entry->icon_flags               |= WimpIcon_Indirected;
      entry->icon_data.it.buffer       = indirected;
      entry->icon_data.it.validation   = (char *) -1;
      entry->icon_data.it.buffer_size  = len + 1;
      *entry->icon_data.it.buffer      = 0;
      strncat( entry->icon_data.it.buffer, ptr, len );
      indirected += len + 1;
    }
    else if (len < 12)
    {
      *entry->icon_data.t = 0;
      strncat( entry->icon_data.t, ptr, len );
    }
    else
    {
      strncpy( entry->icon_data.t, ptr, len<12 ? len+1 : 12 );
    }

    ptr += len+1;
  }

  va_end( va );

  return menu;
}

