function [strout,R2] = spm_str_manip(strin,options)
% Miscellaneous string manipulation options
% FORMAT string_out = spm_str_manip(string_in,options)
% string_in    - input string, string matrix, or cell array of strings
% options      - a string of options flags, see below
%
% string_out   - output string, string matrix, or cell array of strings
% R2           - extra output for 'c' and 'C' options
%__________________________________________________________________________
% Each of the options is performed from left to right.
% The options are:
%   'r'              - remove trailing suffix
%   's'              - remove trailing suffix - only if it is either
%                      '.img', '.hdr', '.mat', '.nii' or '.gii'
%   'e'              - remove everything except the suffix
%   'h'              - remove trailing pathname component
%   'H'              - always remove trailing pathname component
%                      (returns '.' for straight filenames like 'test.img')
%                       (whereas 'h' option mimics csh & returns 'test.img' )
%   't'              - remove leading pathname component
%   ['f' num2str(n)] - remove all except first n characters
%   ['l' num2str(n)] - remove all except last n characters
%   ['k' num2str(n)] - produce a string of at most n characters long.
%                      If the input string is longer than n, then
%                      it is prefixed with '..' and the last n-2 characters
%                      are returned.
%   ['a' num2str(n)] - similar to above - except the leading directories
%                      are replaced by './'.
%                      eg. spm_str_manip('/dir1/dir2/file.img','a16') would
%                      produce '../dir2/file.img'.
%   'v'              - delete non valid filename characters
%                      Valid are '.a..zA..Z01..9_-: ' & filesep
%   'x'              - escape TeX special characters
%   'p'              - canonicalise pathname (see spm_select('CPath',...))
%   'c'              - remove leading components common to all strings
%                      returns leading component as a second output argument
%   'C'              - returns single string compressed version of a
%                      cellstr, such as '/data/pic{01,12,23}.img'.
%                      Second argument is a structure with fields:
%                        .s - start string (E.g. '/data/pic')
%                        .m - middle bits cellstr (E.g.{'01','02','03'})
%                        .e - end string (E.g. '.img')
%   'd'              - deblank - this is always done!
%__________________________________________________________________________
%
% This function is now deprecated, use spm_file when possible instead.
%__________________________________________________________________________

% John Ashburner
% Copyright (C) 1996-2022 Wellcome Centre for Human Neuroimaging


% persistent runonce
% if isempty(runonce)
%     warning('spm_str_manip is deprecated. Use spm_file instead.');
%     runonce = 1;
% end

if nargin<2, options=''; end
if nargin<1, strout=[]; R2=''; return, end

sep      = filesep;

strout   = cellstr(strin);
bSStrOut = ischar(strin);
R2       = '';

while ~isempty(options)
    o = 2;

    %-Read in optional numeric argument c
    %======================================================================
    opt = options(2:length(options));
    c = 0;
    if ~isempty(opt), b = opt(1); else b = '-'; end
    while (b >= '0') && (b <= '9')
        c = c * 10 + opt(1)-'0';
        opt = opt(2:length(opt));
        if isempty(opt)
            b = '-';
        else
            b = opt(1);
        end
        o = o + 1;
    end


    %-Process option - string by string processing options
    %======================================================================
    for i=1:numel(strout)
        str = deblank(strout{i});

        switch options(1)       
        case 'r'
        %-Remove a trailing suffix of the form `.xxx', leaving the basename
        %------------------------------------------------------------------
            d1 = max([find(str == sep) 0]);
            d2 = max([find(str == '.') 0]);
            if d2 > d1, str = str(1:(d2-1)); end

        case 'e'
        %-Remove all but the suffix
        %------------------------------------------------------------------
            d1 = max([find(str == sep) 0]);
            d2 = max([find(str == '.') 0]);
            if d2 > d1
                str = str((d2+1):length(str));
            else
                str = '';
            end

        case 'h'
        %-Remove a trailing pathname component, leaving the head
        %------------------------------------------------------------------
            d1 = max([find(str == sep) 0]);
            if d1 > 0
                str = str(1:(d1-1));
            end

        case 'H'
        %-Remove a trailing pathname component, leaving the head
        %------------------------------------------------------------------
            d1 = max([find(str == sep) 0]);
            if d1 > 0
                str = str(1:(d1-1));
            else
                str = '.';
            end

        case 't'
        %-Remove all leading  pathname  components, leaving the tail
        %------------------------------------------------------------------
            d1 = max([find(str == sep) 0]);
            if d1 > 0
                str = str((d1+1):length(str));
            end

        case 'f'
        %-First few characters
        %------------------------------------------------------------------
            str = str(1:min([length(str) c]));

        case 'l'
        %-Last few characters
        %------------------------------------------------------------------
            l = length(str);
            str = str(l-min([length(str) c])+1:l);

        case 'k'
        %-Last few characters, prefixed with '..'
        %------------------------------------------------------------------
            l = length(str);
            if l > c
                str = ['..' str(l-c+2:l)];
            end

        case 'a'
        %-Last few characters
        %------------------------------------------------------------------
            m1   = find(str == sep);
            l    = length(str);
            if c < l
                m2   = find(l-m1+1+2 <= c);
                if ~isempty(m2)
                    str = ['.' str(m1(min(m2)):l)];
                else
                    str = ['.' str(max(m1):l)];
                end
            end

        case 's'
        %-Strip off '.img', '.hdr', '.nii' or '.mat' suffixes
        %------------------------------------------------------------------
            l = length(str);
            if l > 4
                if ismember(str((l-3):l),...
                        {'.img','.hdr','.nii','.gii','.mat'})
                    str = spm_str_manip(str, 'r');
                end
            end

        case 'v'
        %-Delete non valid filename characters
        %------------------------------------------------------------------
            tmp = ( str>='a' & str<='z' ) | ...
                  ( str>='A' & str<='Z' ) | ...
                  ( str>='0' & str<='9' ) | ...
                    str==','              | ...
                    str=='-' | str=='_'   | ...
                    str=='.' | str==' '   | ...
                    str=='(' | str==')'   | ...
                    str==sep | str==':'   ;
            str = str(tmp);

        case 'x'
        %-Escape TeX special characters
        %------------------------------------------------------------------
            str = strrep(str,'\','\\');
            str = strrep(str,'^','\^'); str   = strrep(str,'_','\_');
            str = strrep(str,'{','\{'); str   = strrep(str,'}','\}');
        
        case 'p'
        %-Canonicalise pathname
        %------------------------------------------------------------------
            str = spm_select('CPath',str);

        case {'c','C','d'}
        %-Allow these options (implemented below)
        %------------------------------------------------------------------
            
        otherwise
        %------------------------------------------------------------------    
            warning(['ignoring unrecognised option: ',options(1)])

        end

        strout{i} = str;
    end
        
    %-Process option - all strings options
    %======================================================================
    if options(1)=='c'
    %-Remove common path components
    %----------------------------------------------------------------------
        if length(strout)>1
            tmp    = size(strout);
            strout = char(strout(:));
            msk    = diff(strout+0)~=0;
            d1     = find(sum(msk,1), 1 );
            d1     = max([find(strout(1,1:d1) == sep) 0]);
            R2     = strout(1,1:d1);
            strout = reshape(cellstr(strout(:,d1+1:end)),tmp);
        end
    
    elseif options(1)=='C'
    %-Common path components
    %----------------------------------------------------------------------
        if length(strout)>1
            tmp  = size(strout);
            str  = char(strout);
            msk  = diff(str+0)~=0;
            d1   = find(sum(msk,1), 1 );
            if isempty(d1)
                R2.s = str(1,:);
                R2.e = '';
                R2.m = cell(tmp);
                [R2.m{:}] = deal('');
            else
                R2.s = str(1,1:d1-1);
                str  = cellstr(str(:,d1:end));
                for i=1:length(str), str{i}=fliplr(str{i}); end
                str  = char(str);
                msk  = diff(str+0)~=0;
                d1   = max([1,find(sum(msk,1), 1 )]);
                R2.e = fliplr(str(1,1:d1-1));
                str  = cellstr(str(:,d1:end));
                for i=1:length(str), str{i}=fliplr(str{i}); end
                R2.m = reshape(str,tmp);
            end
            strout = {[ sprintf('%s{%s',R2.s,R2.m{1}),...
                    sprintf(',%s',R2.m{2:end}),...
                    sprintf('}%s',R2.e)]};
        end
        bSStrOut = 1;

    elseif options(1)=='d'
    % Deblanking is always done by cellstr above
    %----------------------------------------------------------------------
        % strout = deblank(strout);
    end

    options = options(o:length(options));   

end

if bSStrOut, strout=char(strout); end
