function [fails, ginfoFails] = mk_file_list(varargin)
  % A  script to make a list of toolbox files and write an m-file to
  % declare the files
  %
  % Usage: mk_file_list(toolbox_dir);
  %
  % M Hewitson
  %
  % $Id: mk_file_list.m,v 1.18 2008/12/21 18:49:25 hewitson Exp $
  %

  if nargin == 0
    rdir = 'c:\matlab\ltpda_toolbox';
  else
    rdir = varargin{1};
  end

  if rdir(end) ~= filesep
    rdir = [rdir filesep];
  end

  % Initialise
  nn    = 1;
  fails = {};
  ginfoFails = {};

  % make a list of all class methods
  classes = utils.helper.ltpda_classes;

  % Go through each class
  for cls=classes
    cl = char(cls);

    % get the methods for this class
    mths = methods(cl);

    for m=1:numel(mths)
      mth = mths{m};
      % get file name
      fi = which(fullfile(cl, mth));
      if isempty(fi)
        warning('!!! Can''t find %s/%s', cl, mth)
      end
      % Get path,name,ext
      [path, fcnname, ext, ver] = fileparts(fi);

      % get short name
      sname = mth;
      if ~strcmpi(mth, 'contents')
        disp(sprintf('*** processing %s', mth));
        % load file
        fc = '';
        if ~isempty(fi)
          fd = fopen(fi, 'r');
          if fd == -1
            error('### Could not open %s', fi);
          end
          fc = fscanf(fd, '%s');
          fclose(fd);
        end
        
        % Look for a CVS version string
        verstr = '';
        try
          ii = strfind(fc, '$Id:');
          ts = fc(ii(1):end);
          ii = strfind(ts, '$');
          verstr = ts(1:ii(2));
        catch
          warning('!!! CVS Tag not found: Failed on %s', sname)
          fails = [fails {sname}];
        end
        
        % If we have a valid version string, continue
        ver = '';
        dt  = '';
        tt  = '';
        nm  = '';
        if ~isempty(verstr)
          
          % parse version string
          tks = regexp(verstr, 'v([.0-9]+)(\d{4}/\d{2}/\d{2})(\d{2}:\d{2}:\d{2})(\S+)', 'tokens');
          try
            ver = tks{1}{1};                    % version
            dt  = tks{1}{2};                    % date
            tt  = tks{1}{3};                    % time
            ni  = strfind(tks{1}{4}, 'Exp$');
            nm  = tks{1}{4}(1:ni-1);            % name
          catch
            ver = '';
            dt  = '';
            tt  = '';
            nm  = '';
            fails = [fails {sname}];
          end
        end
        % make hash
        if isempty(fc)
          hs = '';
        else
          hs = utils.prog.hash(fc, 'MD5');
        end
        
        % Look for the category
        cat = '';
        argsMin = '';
        argsMax = '';
        try
          cmd = sprintf('ii = %s.getInfo(''%s'', ''None'');', cl, mth);
          eval(cmd);
          cat = ii.mcategory;
          argsMin = num2str(ii.argsmin);
          argsMax = num2str(ii.argsmax);
        catch
          lasterr
          
        end
        
        % fill cell array
        vers(nn,1) = {fi};
        vers(nn,2) = {sname};
        vers(nn,3) = {ver};
        vers(nn,4) = {dt};
        vers(nn,5) = {tt};
        vers(nn,6) = {nm};
        vers(nn,7) = {path};
        vers(nn,8) = {hs};
        vers(nn,9) = {cat};
        vers(nn,10) = {cl};
        vers(nn,11) = {argsMin};
        vers(nn,12) = {argsMax};
        nn = nn + 1;
      end
    end
  end


  %--- Write out version file
  fname = fullfile(rdir, 'ltpda', 'm', 'etc','ltpda_versions.m');
  fd = fopen(fname, 'w+');
  fprintf(fd, 'versions = {...\n');
  for j=1:size(vers,1)
    fprintf(fd, '\t\t');
    for k=1:size(vers,2)
      fprintf(fd, '''%s''', vers{j,k});
      if k~=size(vers,2)
        fprintf(fd, ', ');
      end
    end
    fprintf(fd, '; ...\n');
  end
  fprintf(fd, '\t\t};\n');
  fclose(fd);

  % Compile this to p-code
  run(fname)
%   pcode(fname, '-inplace');
%   delete(fname);

  %--- Display failures
  for j=1:length(fails)
    disp(sprintf('### FAILED: %s', fails{j}));
  end

end

%   %--- Process each file
%   for j=1:nfs
%
%     % This file
%     fi = tbfs{j};
%
%     % Get path,name,ext
%     [path, fcnname, ext, ver] = fileparts(fi);
%
%     % Make exceptions
%     if  ~strcmp(fcnname, 'Contents') && ...
%         ~strcmp(fcnname, 'MakeContents')
%
%       % get short name
%       sname = strrep(fi, rdir, '');
%       if sname(1) == '/'
%         sname = sname(2:end);
%       end
%       disp(sprintf('*** processing %s', sname));
%
%       % load file
%       fd = fopen(fi, 'r');
%       fc = fscanf(fd, '%s');
%       fclose(fd);
%
%       % Look for a CVS version string
%       try
%         ii = strfind(fc, '$Id:');
%         ts = fc(ii(1):end);
%         ii = strfind(ts, '$');
%         verstr = ts(1:ii(2));
%       catch
%         warning('!!! CVS Tag not found: Failed on %s', sname)
%         fails = [fails {sname}];
%       end
%
%
%
%       % If we have a valid version string, continue
%       if ~isempty(verstr)
%
%         % parse version string
%         tks = regexp(verstr, 'v([.0-9]+)(\d{4}/\d{2}/\d{2})(\d{2}:\d{2}:\d{2})(\S+)', 'tokens');
%         try
%           ver = tks{1}{1};                    % version
%           dt  = tks{1}{2};                    % date
%           tt  = tks{1}{3};                    % time
%           ni  = strfind(tks{1}{4}, 'Exp$');
%           nm  = tks{1}{4}(1:ni-1);            % name
%         catch
%           ver = '';
%           dt  = '';
%           tt  = '';
%           nm  = '';
%           fails = [fails {sname}];
%         end
%
%         % make hash
%         hs = utils.prog.hash(fc, 'MD5');
%
%         % get class/category
%         idx = strfind(sname, fcnname);
%         pth = sname(1:idx(end)-1);
%
%         % get class
%         if ~isempty(strfind(pth, 'classes'))
%           [s,r] = strtok(pth, '@');
%           cl = r(2:end-1);
%         else
%           cl = 'None';
%         end
%
%         % Look for the category
%         cat = '';
%         acc = '';
%         if ismember(cl, classes)
%           if ~strcmp(cl, 'None')
%             try
%               cmd = sprintf('ii = %s.getInfo(''%s'', ''None'');', cl, fcnname);
%               eval(cmd);
%               cat = ii.mcategory;
%             end
%           end
%           if isempty(cat)
%             ginfoFails = [ginfoFails {sname}];
%           end
%         end
%
%         % fill cell array
%         vers(nn,1) = {fi};
%         vers(nn,2) = {fcnname};
%         vers(nn,3) = {ver};
%         vers(nn,4) = {dt};
%         vers(nn,5) = {tt};
%         vers(nn,6) = {nm};
%         vers(nn,7) = {pth};
%         vers(nn,8) = {hs};
%         vers(nn,9) = {cat};
%         vers(nn,10) = {cl};
%         nn = nn + 1;
%       else
%         fails = [fails {sname}];
%       end
%     end
%   end
%   % Only output those which are not empty
%   vers = vers(1:nn-1,:);
%
%   %--- Write out version file
%   fname = [rdir '/ltpda/m/etc/ltpda_versions.m'];
%   fd = fopen(fname, 'w+');
%   fprintf(fd, 'versions = {...\n');
%   for j=1:length(vers)
%     fprintf(fd, '\t\t');
%     for k=1:size(vers,2)
%       fprintf(fd, '''%s''', vers{j,k});
%       if k~=size(vers,2)
%         fprintf(fd, ', ');
%       end
%     end
%     fprintf(fd, '; ...\n');
%   end
%   fprintf(fd, '\t\t};\n');
%   fclose(fd);
%
%   % Compile this to p-code
%   run(fname)
% %   pcode(fname, '-inplace');
% %   delete(fname);
%
%   %--- Display failures
%   for j=1:length(fails)
%     disp(sprintf('### FAILED: %s', fails{j}));
%   end


function files = mtfilescan(root_dir, ext)

  % FILESCAN recursively scans the given directory for files that end in
  % 'ext' and returns a list of the full paths.
  %
  % function files = mtfilescan(root_dir, ext)
  %

  files = getfiles(root_dir, ext, []);
end

%--------------------------------------------------------------------------
function ofiles = getfiles(root_dir, iext, ofiles)
  % Recursive function for getting file lists
  %

  disp(sprintf('   + looking in %s', root_dir));
  files = dir(root_dir);

  for j=1:length(files)
    f = files(j);
    if f.isdir
      if strcmp(f.name,'.')==0 && strcmp(f.name,'..')==0
        %mdisp('found dir %s', f.name);
        ofiles = getfiles([root_dir '/' f.name], iext, ofiles);
      end
    else
      [pathstr,name,ext,v] = fileparts(f.name);
      if any(strcmp(ext, iext))
        ofiles = [ofiles; cellstr([root_dir '/' f.name])];
      end
    end
  end
end

function mths = getMethods(cl)

  mths = [];
  % Class info
  try
    % get meta info for this class
    ci = eval(sprintf('?%s', cl));
    % Get methods
    ms = methods(cl); %ci.Methods;

    % Check if this is an abstract class
    try
      o = feval(cl);
      abstract = false;
    catch
      abstract = true;
    end

    if ~abstract
      % Go through methods
      for kk=1:numel(ms)
        m = eval(sprintf('?%s', ms{kk}));
        % If this is not an inherited
%         if strcmp(m.DefiningClass.Name, cl)
          disp(sprintf('   -- checking %s/%s', cl, m.Name));
          if strcmp(m.Access, 'public') && ~m.Static && ~strcmp(m.Name, 'Contents')
            mths = [mths; {m}];
          end
%         else
%           warning('!!! Skipping inherited method %s/%s', cl, m.Name);
%         end
      end
    end
  catch
    warning('!!! Couldn''t get meta info for class %s', cl);
  end
end

% END
