/* Copyright (c) 2000 by Kevin Forchione.  All Rights Reserved. */
/*
*  TADS ADV.T/STD.T LIBRARY EXTENSION
*  REPLACEWITH.T
*  version 1.0
*
*      ReplaceWith provides an easy way to replace string search values
*      with target values using regular expression searches.
*
*----------------------------------------------------------------------
*  REQUIREMENTS
*
*      + HTML TADS 2.3.0 or later
*
*----------------------------------------------------------------------
*  IMPORTANT LIBRARY INTERFACE AND MODIFICATION
*
*      None.
*
*----------------------------------------------------------------------
*  COPYRIGHT NOTICE
*
*      You may modify and use this file in any way you want, provided that
*              if you redistribute modified copies of this file in source form, the
*      copies must include the original copyright notice (including this
*      paragraph), and must be clearly marked as modified from the original
*      version.
*
*------------------------------------------------------------------------------
*  REVISION HISTORY
*
*      09-Feb-2000:    Creation.
*/

#define __REPLACEWITH_MODULE_

#pragma C+

#define RW_REPLACE_ONCE     1
#define RW_MATCH_WORD       2
#define RW_MATCH_CASE       4
#define RW_RET_NIL          8

/*
*  replaceWith(value, target, replacement, flags)
*
*  The function searches the value string, replacing the target string
*  with the replacement string.
*
*  Bit-flags can be passed to control the search.
*
*      RW_REPLACE_ONCE replace only one occurrence of the target in the
*           value string.
*
*          The default for replaceWith() is to replace all occurrences
*          of the target in the value string.
*
*      RW_MATCH_WORD target must match whole words. For example:
*
*          target 'get in' will search for '%<get>% *%<in%>'
*          which will match 'get    in the chair', but not
*          'get into the chair'
*
*      RW_MATCH_CASE target must match the case in value.
*
*          The default for replaceWith() is case-insensitive. A target
*          string of 'get into' will match on 'GET INTO THE CAR' as
*          well as 'Get into the car' unless RW_MATCH_CASE is used.
*
*      RW_RET_NIL function returns nil if no match for the target found
*
*          The default for replaceWith() returns the value unchanged.
*          Using RW_RET_NIL will return the value only if replacement
*          occurred; otherwise the function will return nil.
*/
replaceWith: function(value, target, replacement, ...)
{
   local ret, new_value = '';
   local valuesave, targetsave, replacementsave;
   local flags = 0;

   if (argcount > 3) flags = getarg(4);
   if ((flags & RW_MATCH_WORD)!= 0)
   {
       local tmptarget = '%<';
       tmptarget += replaceWith(target, ' ', '%> *%<');
       tmptarget += '%>';
       target = tmptarget;
   }

   do
   {
       if ((flags & RW_MATCH_CASE) == 0)
       {
           valuesave = value;
           targetsave = target;
           replacementsave = replacement;
           value = lower(value);
           target = lower(target);
           replacement = lower(replacement);
       }
       ret = reSearch(target, value);
       if ((flags & RW_MATCH_CASE) == 0)
       {
           value = valuesave;
           target = targetsave;
           replacement = replacementsave;
       }
       if (ret)
       {
           local len, tmp = '';
           len = length(value) + 1;
           if (ret[1] - 1)
               tmp += substr(value, 1, ret[1]-1);
           tmp += replacement;
           new_value += tmp;
           if (len - (ret[1]+ret[2]))
               value = substr(value, ret[1]+ret[2], len - (ret[1]+ret[2]));
           else
               value = '';
           if ((flags & RW_REPLACE_ONCE) != 0) break;
       }
       else if ((flags & RW_RET_NIL)!= 0
           && new_value == '')
               return nil;
   }
   while( ret != nil);
   new_value += value;
   return new_value;
}