function [hFLB, found] = fileListBox(parent, pathstr, mask, type, varargin)

% h = fileListBox(parent, pathstr, mask, type, ...)
% Creates a listbox uicontrol with the contents of 
% the directory specified by pathstr and mask displayed.
% The results of the var = dir(...) commmand are
% stored in the uicontrol's UserData.
%
% parent = handle to parent figure {gcf}
%          or handle to existing fileListBox,
%          in which case, fileListBox updates
%          the box's contents.
% pathstr = pathstr {.}
% mask = file mask {*}
% type = 'dirs' | 'files' | 'nodirmask' | {'both'}
%
% You can specifiy pairs for the set command after 
% the 'type' parameter.
%
% [h, found] = fileListBox(...) returns the
% list of files stored in the UserData into found.

if nargin < 1; parent = gcf; end;
if nargin < 2; pathstr = cd; end;
if nargin < 3; mask = '*'; end;
if nargin < 4; type = 'files'; end;

dirmarkhead = '';
dirmarktail = filesep;

if strcmp(pathstr(length(pathstr)), filesep)
   pathmask = [pathstr mask];
else
   pathmask = [pathstr filesep mask];
end;

if (strcmp(type, 'dirs') | strcmp(type, 'files'))
   % only lists dirs OR files, not both.
   dirlist = dir(pathmask);
   dirlist2 = dirlist(1);
   flbString = {};
   j = 0;
   for i=1:length(dirlist)
      switch type
      case 'dirs'
         if dirlist(i).isdir & not(strcmp(dirlist(i).name, '.'))
            flbString = { flbString{:},  [ dirmarkhead dirlist(i).name dirmarktail ] };
            j=j+1; dirlist2(j) = dirlist(i);
         end;
      case 'files'
         if not(dirlist(i).isdir)
            flbString = { flbString{:}, dirlist(i).name };
            j=j+1; dirlist2(j) = dirlist(i);
         end;
      end;
   end;
else
   % first construct DIR list, Then add files
   if strcmp(type, 'nodirmask')
      dirlist = dir(pathstr);
   else 
      dirlist = dir(pathmask);
   end
   dirlist2 = {};
   flbString1 = {};
   j = 0;
   % only add dirs
   for i=1:length(dirlist)
      if dirlist(i).isdir & not(strcmp(dirlist(i).name, '.'))
         flbString1 = {flbString1{:}, [ dirmarkhead dirlist(i).name dirmarktail ]};
         j=j+1; dirlist2(j) = dirlist(i);
      end;
   end;
   dirlist = dir(pathmask);
   flbString2 = {};
   % now only add files
   for i=1:length(dirlist)
      if not(dirlist(i).isdir)
         flbString2 = {flbString2{:}, dirlist(i).name };
         j=j+1; dirlist2(j) = dirlist(i);
      end;
   end;
   flbString = { flbString1{:}, flbString2{:} };
end;


% default pos fills window
unitsold = get(parent, 'units');
set(parent, 'units', 'pixels');
position = get(parent, 'position'); position(1:2) = [0 0];
set(parent, 'units', unitsold);
% default callback is null
callback = '';

if nargin > 4 & not(mod(length(varargin),2));
   foundposition = 0;
   foundcallback = 0;
   for lp=1:2:size(varargin,2);
      switch lower(varargin{lp})
      case 'position'
         foundposition = 1;
      case 'callback'
         foundcallback = 1;
      end;
   end;
   if not(foundposition); varargin = { varargin{:}, 'Units', 'pixels', 'Position', position }; end;
   if not(foundcallback); varargin = { varargin{:}, 'Callback', callback }; end;
else
   varargin = {'Units', 'pixels', 'Position', position, 'Callback', callback};
end;

switch get(parent, 'Type')
case 'uicontrol'
   %just update string.
   hFLB = parent;
   set(hFLB, 'String', flbString, 'UserData', dirlist2, 'Value', 1);
otherwise
   hFLB = uicontrol(parent, 'Style','listbox','String',flbString,'units','Pixels','UserData',dirlist2,varargin{:},'Value',1);
end

if nargout > 1; found = dirlist2; end;
