## Copyright (C) 2025
##
## 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
## <https://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {} {@var{retval} =} contains (@var{str}, @var{pattern})
## @deftypefnx {} {@var{retval} =} contains (@var{str}, @var{pattern}, "IgnoreCase", @var{ignore_case})
## Check whether string(s) contain pattern(s).
##
## @code{contains} returns a logical array indicating which strings in
## @var{str} contain the pattern(s) in @var{pattern}.
##
## @example
## @group
## contains ("hello world", "world")
##   @result{} 1
## contains (["hello", "world"], "lo")
##   @result{} [1, 0]
## @end group
## @end example
##
## @seealso{startsWith, endsWith}
## @end deftypefn

function retval = contains (str, pattern, varargin)
  if (nargin < 2)
    print_usage ();
  endif

  ignore_case = false;
  if (nargin > 2)
    for i = 1:2:numel (varargin)
      if (strcmpi (varargin{i}, "IgnoreCase"))
        if (i+1 <= numel (varargin))
          ignore_case = logical (varargin{i+1});
        else
          error ("contains: IgnoreCase requires a value");
        endif
      else
        error ("contains: unknown option '%s'", varargin{i});
      endif
    endfor
  endif

  ## Convert to cell array of strings if needed
  if (ischar (str))
    str = {str};
  elseif (isstring (str))
    str = cellstr (str);
  elseif (! iscellstr (str))
    error ("contains: STR must be a string, char array, or cell array of strings");
  endif

  if (ischar (pattern))
    pattern = {pattern};
  elseif (isstring (pattern))
    pattern = cellstr (pattern);
  elseif (! iscellstr (pattern))
    error ("contains: PATTERN must be a string, char array, or cell array of strings");
  endif

  ## Handle scalar expansion
  if (numel (pattern) == 1)
    pattern = repmat (pattern, size (str));
  elseif (numel (str) == 1)
    str = repmat (str, size (pattern));
  elseif (! isequal (size (str), size (pattern)))
    error ("contains: STR and PATTERN must have compatible sizes");
  endif

  retval = false (size (str));
  for i = 1:numel (str)
    str_val = str{i};
    pattern_val = pattern{i};
    
    if (ignore_case)
      str_val = tolower (str_val);
      pattern_val = tolower (pattern_val);
    endif
    
    retval(i) = ! isempty (strfind (str_val, pattern_val));
  endfor
endfunction

