function [your_path] = foldersearch(start_folder, contains, check_filenames)
%FOLDERSEARCH looks for a folder with a specific string in current drive
% check_filenames - also checks the filenames inside folders for matches
%   TODO - better description

% TODO - better comments in code

if nargin < 3
    check_filenames = false;
else
    validateattributes(check_filenames, {'numeric', 'logical'}, {'scalar'})
end

validateattributes(start_folder, {'char', 'string'}, {'vector'})
assert(isfolder(start_folder))
validateattributes(contains, {'char', 'string'}, {'nonempty', 'vector'})

memorized_pos = {};
your_path = recursive_foldersearch(start_folder, contains, memorized_pos, check_filenames);
end


function [your_path, memorized_pos] = recursive_foldersearch(start_folder, contains, memorized_pos, check_filenames)

your_path = '';

list = dir(start_folder);
memorized_pos{end+1} = start_folder; % add current folder to memorized checked folders

folder_content_names = {list.name};
is_dir = [list.isdir];

if check_filenames % check if any files contain the search word
    files_in_folder = folder_content_names(~is_dir);
    if any(~cellfun(@isempty, regexp(files_in_folder, contains))) % if any of them is not empty - i.e. there was a match
        your_path = start_folder; % return the current folder
        return
    end
end

% check folders
folders_in_folder = folder_content_names(is_dir);

for exclude = {'.', '..'} % skip current and parent folders
    folders_in_folder = folders_in_folder(~strcmp(folders_in_folder, exclude));
end

matching_folder = find(~cellfun(@isempty, regexp(folders_in_folder, contains)), 1); % find 1st instance if any
full_folders = fullfile(start_folder, folders_in_folder);

if ~isempty(matching_folder)
    your_path = full_folders{matching_folder}; % return found folder
else

    parent = fileparts(start_folder); % get parent folder
    if ~any(strcmpi(parent, memorized_pos))
        full_folders{end+1} = parent; % add parent directory to folders, if not checked already
    end

    for k = 1:length(full_folders)
        if any(strcmpi(full_folders{k}, memorized_pos)) % skip already checked folders
            continue
        end
        [your_path, memorized_pos] = recursive_foldersearch(full_folders{k}, contains, memorized_pos, check_filenames);
        if ~isempty(your_path)
            break
        end
    end
end

end

