## Copyright (C) 2002-2017 Sahil Yadav
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {} {@var{s} =} erase (@var{str1}, @var{str2})
## Delete all occurances of @var{str2} within @var{str1}
##
## @var{str1} and @var{str2} can be cell array of strings or a char vector
##
## If @var{str1} is char vector, char vector is returned containing string @var{str1}
## remaining after the deletion of @var{str2} from it.
##
## If @var{str1} is cell array of strings, the returned value is the cell array of 
## string @var{str1} with substrings in cell array (or char vector) of @var{str2} deleted  
## from each of the strings of @var{str1}.
##
## Unlike MATLAB @var{str2}  cannot be an array of char vectors, if you are trying to run a
## file written for MATLAB, then just put @{@} around @var{str2} and it shoud work in octave. If @var{str1}
## is an array of char vectors then some trailing spaces might change. You should change it to a cell array.
##
## @example
## @group
## erase ('hello, world',' world')
##      @result{} 'hello,'
##
## erase (@{'octave';'octave is';'fabulous'@}, 'oct')
##      @result{} @{ave';'ave is';'fabulou'@}
##
## erase (@{'octave';'octave is';'fabulous'@}, @{'oct';'ous';'is'@})
##      @result{} @{'ave';'ave ';'fabul'@}
##
## erase ('supercalifragilisticexpialidocious', @{'cali';'exp';'ous'@})
##      @result{} 'superfragilisticialidoci'
##
## @end group
## @end example
##
## @seealso{strrep}
## @end deftypefn

## Author: Sahil Yadav <yadavsahil5198@gmail.com>


function finalstring = erase ( parentstring, childstring )
  if(nargin != 2  || !((ischar (parentstring) && isvector (parentstring)) || iscellstr (parentstring) || ischar (parentstring) ) || !((ischar (childstring) && isvector (childstring)) || iscellstr (childstring) || ischar (childstring)))
    print_usage();
  endif
  
  if ( ischar (parentstring) && ! isvector (parentstring) )
    error("STR1 must be a cell array of strings or a char vector")
  endif
  
  if ( ischar (childstring) && ! isvector (childstring) )
    error("STR2 must be a cell array of strings or a char vector")
  endif

  if (ischar (childstring))
    if (rows (childstring)>1)
      error ("Use cells for this kind of input. See the help. " )
    endif
    childstring = num2cell ( childstring,2 );
  endif
  
  parentwaschar=false;
   
  if (isempty (parentstring) || isempty (childstring) )    # Return parent string if either of the strings is NULL
    finalstring =  parentstring;
  else
    if (ischar (parentstring))
      parentstring = num2cell (parentstring,2);
      parentwaschar=true;
    else
      parentstring = cellstr (parentstring);            # Change the input array of characters to cell arrays
    endif
    
    for i = 1:rows (parentstring)
      newstring = "";
      marked = char('0'*ones(1,length(parentstring{i})));
      for j = 1:rows (childstring)
        if(numel ( (strfind ( parentstring{i}, childstring{j}) ) ) == 0 || length (parentstring{i}) < length (childstring{j}) )  # if the parentstring is empty or there's no childstring in parentstring
          continue;
        elseif( strcmp (parentstring{i},childstring{j}) == 1 ) 		# if the parentstring == childstring, return an empty string.
          parentstring{i} = "";
          continue;
        else
          index = strfind (parentstring{i},childstring{j});
          for k = 1:length(index)
            flag = 0;
            
            if (index(k) == 1 && marked(index(k))=='0')
              for l = 1:length(childstring{j})
                if (marked(l) == '1')
                  flag = 1;
                  break;
                endif
              endfor
              if (flag == 0)              
                for l = 1:length(childstring{j})
                  marked(l) = '1';
                endfor
              endif

            elseif (index(k) == length( parentstring{i})-length(childstring{j}) +1 && marked(index(k))=='0')
              for l = index(k):length(parentstring{i})
                if (marked(l) == '1')
                  flag = 1;
                  break;
                endif
              endfor
              if (flag == 0)
                for l = index(k):length(parentstring{i})
                  marked(l) = '1';
                endfor
              endif

            elseif(marked(index(k))=='0')
              for l =  index(k) : index(k)+length(childstring{j})-1
                if (marked(l) == '1')
                  flag = 1;
                  break;
                endif
              endfor
              if (flag == 0)
                for l = index(k) : index(k)+length(childstring{j})-1
                  marked(l) = '1';
                endfor
              endif

            endif
          endfor
        endif
      endfor  
      for t = 1:length(parentstring{i})
        if (marked(t) == '0')
          newstring = cstrcat(newstring,parentstring{i}(t));
        endif
      endfor
      parentstring{i} = newstring;
    endfor
    finalstring = parentstring;
    
    if (parentwaschar)
      finalstring = char ( finalstring);
    endif
       
  endif
endfunction


# from https://savannah.gnu.org/bugs/?52647#comment5
%!assert (erase ('ababa', 'aba'), 'ba');
%!assert (erase ('abababa', 'aba'), 'b');
%!assert (erase ('ababababa', 'aba'), 'bba')
%!assert (erase ('ababababa', {'aba', 'bba'}), 'bba');
%!assert (erase ('ababababa ', {'aba', 'bba'}), 'bba ');
%!assert (erase ({' ababababa '}, {'aba', 'bba'}), {' bba '});
%!assert (erase (' ababa ', {'aba', 'baba'}), ' ba ');
%!assert (erase (' Hello World t ',{'t';'llo'}),' He World  ')
%!assert (erase ({' Hello World t '},[ 'o ']),{' HellWorld t '})
%!assert (erase ( 'Hello World t ',{'ld '; 'o '}),'HellWort ')
%!assert (erase ( 'Hello World t ',['ld '; 'o ']),'HellWort ')
%!assert (erase ('aba', 'aba'), char({""}));
%!assert (erase ({'aba'}, 'aba'), ({""}));
%!assert (erase ('', 'aba'), ''); 
%!assert (erase ({'abbabbabba'},{'abba'}),{'bb'}); 
%!assert (erase ({'ababababa';'abbabbabba'},'aba'),{'bba';'abbabbabba'})
%!assert (erase ({''};{''}),{''})
%!assert (erase ({'pppppppp'},'p'),{''})
%!assert (erase ( 'Hello World t ',{'ld '; 'o '}),'HellWort ')
%!error <Use cells for this kind of input. See the help> erase ( 'Hello World t ',['ld '; 'o '])
%!xtest assert (erase ( 'Hello World t ',['ld '; 'o ']),'HellWort ')
%!assert (erase ( {'Hello World t '},{'ld '; 'o '}),{'HellWort '})

%!demo
%! str = ["the quick brown fox jumps";
%!      "over the lazy dog"]
%! matchstr = "the "
%! erase(str,matchstr)

%!demo
%! str = {"the quick brown fox jumps";
%!      "over the lazy dog"}
%! matchstr = {"the "}
%! erase(str,matchstr)

%!demo
%! str = {"the quick brown fox jumps";
%!      "over the lazy dog"}
%! matchstr = {"the ";'lazy '}
%! erase(str,matchstr)
