/* strbuild.c */

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

#include "toolbox.h"

#include "error.h"

#include "dBoxTools.h"
#include "strbuild.h"
#include "find.h"
#include "list.h"
#include "mapping.h"
#include "read.h"
#include "debug.h"

static _kernel_oserror *append
( char **out, int *space, Action *a, int event, WimpPollBlock *wpb,
  int *pending, PendingHandler p, void *ap )
{ _kernel_oserror *er = NULL;
  int l;

  if( a && a->object == -2 )
    read_event( event, wpb, a->component, *out, *space, pending, p, ap );
  else  
  { read_gadget( a->object, a->component, *out, *space );
    pending = FALSE;
  }
  if( debug )
  { fprintf( debug,
      "  Appending %x:%x.  String is [%s]\n", a->object, a->component, *out );
  }
  a->value = *out;
  if( !pending )
  { er = mapping_lookup( a, *out, *space );
    if( debug ) fprintf( debug, "  Mapped to [%s]\n", *out );
  }  
  l = strlen( *out );
  *space -= l;
  *out += l;
  return er;
}

_kernel_oserror *strbuild_build
( char *in, char *out, int space,
  Action *action, int event, WimpPollBlock *wpb,
  int *pending, PendingHandler ph, void *handle )
{ int inc;
  char *p, *start;
  char rangeType;
  Action act;
  _kernel_oserror *er = NULL;
  ObjectId object;

  start = in;
  *out = 0;
  act = *action;
  act.object = -1;
  while( *in && space > 0 )
  { p = strchr( in, '#' );
    if( p )
    { inc = p - in;
      space -= inc;
      if( space > 0 )
      { strcat( out, in );
        in = p + 1;
        out += inc;

        /* now do the component substitution bit */
        er = listItem( in, '#', &object, &act.component, &rangeType );
        if( object != -1 ) act.object = object;
        if( er ) break;
        while( act.object != -1 && act.component != -1 )
        {
          er = append( &out, &space, &act, event, wpb, pending, ph, handle );
          if( er ) break;
          if( rangeType == '=' && space > 1 )
          { *out++ = ' ';
            space--;
          }
          er = listItem( NULL, '#', &object, &act.component, &rangeType );
          if( er ) break;
          if( object != -1 ) act.object = object;
        }
        *out = 0;
        in = strchr( in, '#' ) + 1;
      }
    }
    else
    { inc = strlen( in );
      space -= inc;
      if( space > 0 ) strcpy( out, in );
      in += inc;
    }
  }
  if( space < 0 )
  { strcpy( error_block.errmess, "strbuild_build(): String too long" );
    error_block.errnum = ERROR_BUFFER_OVERFLOW;
    er = &error_block;
  }
  return er;
}

/* end of strbuild.c */
