%find_images
%
%	Generate an m-file with paths to all images below a
%	specified directory.
%
% -Usage-
%	find_images(imagedir, filename, extras)
%
% -Inputs-
%	imagedir	image directory, must be below current directory
%	filename	output filename
%	extras		cell array with names of extra fields
%
% -Outputs-
%	None
%
% Last Modified: 10/17/2009
function find_images(varargin)

	% Recognized extensions
	extensions = {'.jpg', '.jpeg', '.gif', '.tif', '.tiff', ...
		'.png', '.hdr','.exr', '.ppm', '.bmp', '.pfm'};

	data = processArgs(varargin);

	files = getFilesFromDir('', data, extensions);
	writeMFile(files, data);

end

%
% Process input args
%
function data = processArgs(args)

	nargs = numel(args);

	if nargs < 1
		error('Image folder not specified.');
	end

	drname = args{1};

	% Check that folder exists
	if ~exist(drname, 'dir')
		error(sprintf('Image folder %s does not exist.',drname));
	end

	% Set default mfile name to folder name
	if nargs < 2 | isempty(args{2})
		mfile = sprintf('%s.m',drname);
	else
		mfile = args{2};
	end

	% Make sure mfile ends in .m
	[dr,nm,ex] = fileparts(mfile);
	if ~strcmp(ex,'.m')
		mfile = fullfile(dr,[nm '.m']);
	end

	data.drname = drname;
	data.mfile  = mfile;

	% Get current dir
	thisdir = pwd;

	% Check that specified image dir is in local directory
	[tempdr,tempnm,tempex] = fileparts(drname);
	if isempty(tempdr)
		tempdr = tempnm;
	end

	localfiles = dir;
	[names{1:numel(localfiles)}] = deal(localfiles.name);
	if ~any(strcmp(names,tempdr))
		error('Image folder is not below working directory.');
	end
	data.base   = thisdir;
	data.subdir = drname;
	data.useenv = false;
	data.extras = {};

	% If the RESEARCH env variable is set and drname
	% is below that path, remove the RESEARCH component
	% of the path
	rpath = getenv('RESEARCH');

	if ~isempty(strmatch(rpath,thisdir)) & ~isempty(rpath)
		sp = filesep;
		if rpath(end) ~= sp
			rpath = [rpath sp];
		end
		subdir = fullfile(thisdir(length(rpath)+1:end), drname, '');
		
		data.base = rpath;
		data.subdir = subdir;
		data.useenv = true;
	end

	% Check for extra fields
	if nargs > 2
		data.extras = args{3};
		if ~iscell(data.extras)
			warning('Extra fields must be specified as a cell array of names');
			data.extras = {};
		end
	end
end


%
% Recursively search for image files
%
function names = getFilesFromDir(dr, data, ext)

	names = {};
	ix = 1;
	thisdir = fullfile(data.base,data.subdir,dr,'');
	files = dir(thisdir);
	for i = 1 : numel(files)
		% Skip current, parent directories and hidden files
		if files(i).name(1) == '.'
			continue;
		end

		% Scan subfolders for images
		if files(i).isdir
			temp = getFilesFromDir(fullfile(dr,files(i).name,''), data, ext);
			for j = 1 : numel(temp)
				names(ix).path = temp(j).path;
				ix = ix + 1;
			end
		end

		% Check if this file is an image
		[ignore,nm,ex] = fileparts(files(i).name);
		if ~isempty(strmatch(lower(ex),ext,'exact'));
			names(ix).path = fullfile(dr,files(i).name);
			ix = ix + 1;
		end

	end

end

%
% Write the struct array
%
function writeMFile(files, data)

	fd = fopen(data.mfile, 'w');

	% Get name without extension
	[ignore,fname,ex] = fileparts(data.mfile);

	fprintf(fd,'function out = %s()\n\n',fname);

	if data.useenv
		fprintf(fd,'rdir = getenv(''RESEARCH'');\n');
	else
		fprintf(fd,'rdir = ''%s'';\n',data.base);
	end
	fprintf(fd,'path = fullfile(rdir,%s,'''');\n\n',split(data.subdir));

	nextra = numel(data.extras);
	nfiles = numel(files);
	fprintf(fd,'data = cell(%d,%d);\n',nfiles,1+nextra);

	for i = 1 : numel(files)
		pt = split(files(i).path);
		fprintf(fd,'data(%d,:) = {fullfile(path,%s)',i,pt);
		for j = 1 : nextra
			fprintf(fd,', ''''');
		end
		fprintf(fd,'};\n');
	end
	
	fprintf(fd,'\nout = cell2struct(data, {''path''');
	for j = 1 : nextra
		fprintf(fd,', ''%s''',data.extras{j});
	end
	fprintf(fd,'}, 2);\n');

	fclose(fd);

	fprintf('%d images saved in %s.\n',nfiles,data.mfile);

end


%
%
%
function outstr = split(dr)
	parts = regexp(dr,filesep,'split');
	outstr = sprintf('''%s'',',parts{:});
	% Remove final comma
	outstr = outstr(1:end-1);
end

