function  scan(instclass, varargin);
% function  scan(instclass, varargin);
%
% Produce a listing of the binary ADCP data files 
% Listing produces start/end times and ensemble numbers, etc.
% 
% The instrument class (nb, bb, os, son) NO QUOTES!! is required and 
% determines how the files are to be read. Only one kind of raw data
% can be specified per call to "scan".  Other options are 
% specified with keyword, value pairs.  Files to be scanned are 
% determined by the keyword 'suffix' or by a list specified with 
% 'filelist'.    One scan file is produced for all files read.
%
% keyword, value pairs are:
% 
%  ---------- required ----------
% 'yearbase', [4-digit yearbase]   %
%
% 'filelist', [one file or cellarray] % filelist from either
%                             %   -   dirs('name', 'fullpath',1)
%                             %   -   or (a cellarray)
%                             %NOTE must specify either filelist or globstr
% 'globstr',  [to glob on]            %    glob string
%
% ---------- optional ----------
% 'source_dir', [path to files]    % default is here (i.e. './')
%                                  %  (only used with glob_str)
% 'dest_dir', [output directory]   % default is here (i.e. './')
% 'outfile',  [string]             % default 'rawscan.scn'
% 'timetype'  [string]             % default: 'raw'
%                                  % 'raw' (uncorrected dday timestamps) 
%                                  % 'vmdas' (use nav structure (for ensembles))
%                                  % 'uhdas' (use uh raw  .time.gbin file to correct)
% 'timegbindir' [string]           % directory to find .time.gbin file
%                                  % default: '../gbin/time' 
% 'append'    [0 or 1]             % default 0 (no, write a new file); 1->append
% 'verbose', [0 or 1]              % verbose read, default is 0 (not verbose)
%
% example usage (from the directory where the raw files exist)
% scan(nb, 'yearbase', 2000, 'globstr', '*.raw')
%
% Notes: (1) it is easiest to go to the directory where the files are 
%                and point the output elsewhere 
%        (2) nbuh and sonuh file dates are uncorrected
%        

% 2000/09/25 EF
% 2001/02/15 JH adding instclass method
%

% defaults: (must initialize all defaults or fillstruct will fail)
cfg.yearbase = [];
cfg.filelist = [];
cfg.verbose = 0;
cfg.header = [];

cfg.globstr = '';
cfg.append = 0;

cfg.source_dir = './';
cfg.dest_dir = './';
cfg.outfile = 'rawscan.scn';

cfg.timetype = 'raw';
cfg.timegbindir = '../gbin/time';

if (nargin <= 1)
   help(mfilename)
   error('must specify files')
end

cfg = fillstruct(cfg,varargin,0);


timetypes = {'raw', 'vmdas', 'uhdas'};
if (~ismember(cfg.timetype, timetypes))
   help(mfilename)
   fprintf('''timetype'' must one of the following\n')
   timetypes
   return
end


if (isemptys(cfg.filelist) & (isemptys(cfg.globstr)))
   help(mfilename)
   error('must specify glob string or file list')
end

if (isemptys(cfg.yearbase) | (length(num2str(cfg.yearbase))~=4))
   help(mfilename)
   error('must specify 4-digit yearbase')
end

if (isemptys(cfg.outfile))
   help(mfilename)
   error('may not specify an empty outfile name')
end

% --- assemble the list of files  ---

% fill filelist1
if (isemptys(cfg.globstr))
   filelist1 = [];
else
   filelist1 = dirs(fullfile(cfg.source_dir, cfg.globstr));
end

%fill filelist2


if isemptys(cfg.filelist)
   if (cfg.verbose)
      fprintf('getting filenames from ''globstr''\n')
   end
   filelist2 = cfg.filelist;   
else
   if (isstr(cfg.filelist)) %one file
      filelist2.name  = cfg.filelist;
   else                    
      if (iscell(cfg.filelist))  %more than one file (i.e. cellarray)
         for ii=1:length(cfg.filelist)
            filelist2(ii).name = cfg.filelist{ii};
         end
      else                       %structure (from dirs)
         if ~isstruct(cfg.filelist)
            fprintf('WARNING: filelist not valid')
            return
         end
         filelist2 = cfg.filelist;
      end
   end
end

filelist = [filelist1; filelist2];
if size(filelist, 1) == 0,
   error(sprintf('could not find files in directory %s\n',cfg.source_dir))
else
   %sort it
   fnames = fieldnames(filelist);
   fcell = struct2cell(filelist);   %(4 X nfiles)
   [sorted_names, sorti] = sort(fcell(1,:));
   sorted_fcell = fcell(:,sorti);
   filelist = cell2struct(sorted_fcell', fnames(:)',2);
end

% --- read and scan the files ---

f = [];
ii = 1;

for ifile = 1:length(filelist)
   if strmatch(cfg.source_dir, './')
      cfg.source_dir = [];
   end
   
   if ~isemptys(cfg.source_dir)
      file = fullfile(cfg.source_dir, filelist(ifile).name);
   else
      file =  filelist(ifile).name;
   end
   
   
   if (cfg.verbose)
      disp(file)
   end
   
   %navigation may not exist:
   if strmatch(cfg.timetype, 'vmdas')
      try
         d = read(instclass, file, 'ends', 4, 'yearbase', cfg.yearbase, ...
                  'vars','nav','verbose', cfg.verbose);
      catch
         d = read(instclass, file, 'ends', 2, 'yearbase', cfg.yearbase, ...
                  'vars','nav','verbose', cfg.verbose);
      end
   else
      try
         d = read(instclass, file, 'ends', 4, 'yearbase', cfg.yearbase, ...
                  'verbose', cfg.verbose);
      catch
         d = read(instclass, file, 'ends', 2, 'yearbase', cfg.yearbase, ...
                  'verbose', cfg.verbose);
      end
   end


   
   f(ii).name = filelist(ifile).name;
   
   
   
   if (isemptys(d))
      nump = 0;
      f(ii).dd = [NaN NaN];
      f(ii).ens = [NaN NaN];
      f(ii).yearbase = NaN;
      f(ii).error = 'empty';
   else
      nump = length(d.dday);
      % figure out proc timestamp
      if strmatch(cfg.timetype, 'vmdas')
         if (isfield(d, 'nav') & (~isnan(sum(d.nav.sec_pc_minus_utc))))
            if nump == 1
               sec_pc_minus_utc = d.nav.sec_pc_minus_utc*[1 1];
               dt = 0;
               f(ii).dd = [1 1] * (d.dday(1) - sec_pc_minus_utc(1)/86400);
            else         
               sec_pc_minus_utc = [d.nav.sec_pc_minus_utc([2 end])];
               dt = d.dday(end) - d.dday(end-1);
               f(ii).dd = [d.dday(2) d.dday(end)+dt] - sec_pc_minus_utc/86400;
            end
            timetype{ii} = 'vmdas';
         else
            fprintf('WARNING: valid navigation structure does not exist.')
            fprintf(' Using raw times\n\n')
            if nump == 1
               f(ii).dd = d.dday(1)*[1 1] ;
            else
               f(ii).dd = d.dday([1 end]);
            end
            timetype{ii} = 'raw';
         end
      elseif strmatch(cfg.timetype, 'uhdas')
         
         [ppjunk, rawfilebase, extjunk] = fileparts(file);
         timbin_filename = fullfile(cfg.timegbindir, ...
                                    sprintf('%s.tim.gbin', rawfilebase));
         tim_bindata = read_bin(timbin_filename);
         if (isemptys(tim_bindata))
            if nump == 1
               f(ii).dd = d.dday(1) * [1 1];
            else
               f(ii).dd = d.dday([1 end]);
            end            
            timetype{ii} = 'raw';
         else
            if (nump == 1)
               f(ii).dd = tim_bindata(2,1) * [1 1];
            else
               f(ii).dd = tim_bindata(2,[1 end]);  %best time
            end            
            timetype{ii} = 'uhdas';
         end
      else
         if nump == 1
            f(ii).dd = d.dday(1) * [1 1];
         else
            f(ii).dd = d.dday([1 end]);
         end  
         timetype{ii} = 'raw';
      end
      f(ii).ens = d.ens_num([1 end]);
      f(ii).yearbase = d.config.yearbase;
      f(ii).error = d.error;
      ii = ii + 1;
   end
end


if (cfg.append)
   fid = fopen(cfg.outfile, 'a');
else
   fid = fopen(cfg.outfile, 'w');
end

if fid == -1, 
   error(['Can''t open ', cfg.outfile]); 
else
   fprintf('writing scan info to %s\n',cfg.outfile)
end


% some header, commented
fprintf(fid,'%%           file              start time           end time           ');
fprintf(fid,'startdd          enddd      ens(start,end,num) ensgap ');
fprintf(fid,'ensdt       t_gap    totalDT timetype\n');


for ii = 1:length(f)
   
   if (diff(f(ii).ens) == 0)
      sprintf('filename %s has only one ensemble\n', f(ii).name)
      nump = 1;
   end   

   if nump == 1   
      n = 1;
      dt = 0;
      DT = dt * n;
      if ii == 1,
         ens_gap = 0;
         t_gap = 0;
      else
         ens_gap = f(ii).ens(1) - f(ii-1).ens(2);
         t_gap = 86400 * (f(ii).dd(1) - f(ii-1).dd(2));
      end
   else
      n = 1 + diff(f(ii).ens);
      dt = 86400 * diff(f(ii).dd)/(n - 1);
      DT = dt * n;
      if ii == 1,
         ens_gap = 0;
         t_gap = 0;
      else
         ens_gap = f(ii).ens(1) - f(ii-1).ens(2);
         t_gap = 86400 * (f(ii).dd(1) - f(ii-1).dd(2));
      end
   end

   
   fprintf(fid, '%s  %s  %s', f(ii).name, ...
                  to_date(f(ii).yearbase, f(ii).dd(1), 'string'), ...
                  to_date(f(ii).yearbase, f(ii).dd(2), 'string'));

   fprintf(fid, '  %12.6f  %12.6f', f(ii).dd);
   fprintf(fid, '  %6d %6d', f(ii).ens);
   fprintf(fid, '  %5d %5d', n, ens_gap);
   fprintf(fid, '  %4.1f %10.0f %10.0f  %5s\n', dt, t_gap, DT, timetype{ii});
   

   
end

fclose(fid);






