function xxx2gbin(rawfilebase, varargin)
% xxx2gbin(rawfilebase, varargin)
%                                
% read .tim.bin files to get best logger times 
%  *** should have already created it with gps2gbin ***
% find the matching (logger) time ranges for xxx files, 
% interpolate to get xxx fields  at logger times,  
% write a flat binary file with (ncols-1)xN entries
% output name is 'outfpath/rawfilebase.xxx.gbin' for "gridded bin"
% 
% eg. xxx2gbin('nbp2001_094_36014', 'binfpath', 'gyro')
% varargin name, value pairs are:
% 
% tim_gbinpath [path to *.tim.gbin]   (input)    % *** required ***
% xxx_binpath [path to *.xxx.bin]     (input)    % *** required ***
%           xxx is 'hdg', 'gps', 'adu', 'spd'
% outfpath [path to output file]                 % *** required ***
% in_fext     [file extension in xxx_binpath]    % *** required  ***
%           xxx is 'hdg', 'gps', 'adu', 'spd'
% out_fext    [file extension in xxx_gbinpath]   % *** required  ***
%           xxx is 'hdg', 'pos', 'adu', 'spd'
% gap_seconds [NaN positions with    %default 10
%             gaps longer than this]
% scootch_sec [require time shifts to         % .5
%              be under this
% redo     [0 or 1] redo gbin file            % 0 


%JH 2001/04/05

cfg.xxx_binpath = '';
cfg.tim_gbinpath = 'gbinfiles/pcode';
cfg.outfpath = '';
cfg.gap_seconds = 10;
cfg.scootch_sec = .5;
cfg.in_fext     = '';
cfg.out_fext     = '';
cfg.redo = 0;

cfg = fillstruct(cfg, varargin, 0);

if (isempty(cfg.in_fext))
      error('in_fext not set')
end

if (isempty(cfg.out_fext))
      error('out_fext not set')
end

if (isempty(cfg.xxx_binpath))
      error('path to *.xxx.bin not set')
end

if (isempty(cfg.outfpath))
      error('path to outfile *.xxx.gbin not set')
end


outfile =     fullfile(cfg.outfpath, ...
                       sprintf('%s.%s.gbin', rawfilebase, cfg.out_fext));

if (exist(outfile, 'file') & (~cfg.redo))
   fprintf('not writing %s\n', outfile)
   return
end


timdata = read_bin(fullfile(cfg.tim_gbinpath, [rawfilebase, '.tim.gbin']));
logger_dday = timdata(1,:)';
%get the logger time info from the tim files
badi = find(isnan(logger_dday));
goodi = find(~isnan(logger_dday));
logger_dday = logger_dday(goodi);
logger_timerange = [logger_dday(1) logger_dday(end)];

bindata = bin_extract(cfg.xxx_binpath, cfg.in_fext,  logger_timerange );
if (isempty(bindata))
   cfg
   error('no bin data read')
end

nani = find_gaps(logger_dday, bindata(1,:), cfg.gap_seconds);
dt = filt242(diff(bindata(1,:)));
bin_lmean = mean(bindata(1,:));   %want mean of times to match
bin_filt_ldday = bindata(1,1) + cumsum([0 dt]);
%this might only be necessary for small files: make the means match
bin_fldday = bin_filt_ldday - mean(bin_filt_ldday) + bin_lmean;
%make sure shifts over 1/2 don't occur
bin_fldday = unscootch(bin_fldday, bindata(1,:), cfg.scootch_sec);

% use the reaquisition flag to make bad entries into NaNs (reaqfl = 1)
if (strcmp(cfg.in_fext, 'adu'))
   badi = find(bindata(8,:) == 1);
   bindata(8,:) = [];  %lose the reaquisition column
   % [logger_dday, attdday, heading, pitch, roll, mrms, brms]
   bindata([2:7],badi) = NaN;
   % rearrange it
   % [logger_dday,  heading, pitch, roll, attdday, mrms, brms]
   %     1             3       4      6         2   6    7
   bindata = bindata([1 3 4 5 2 6 7],:);
end


%remove bad points in speed of sound
if (strcmp(cfg.in_fext, 'spd'))
   badi = flag_sspd(bindata);
   if (~isempty(badi))
      bin_fldday(badi)=[];
      bindata(:,badi)=[];
   end
end


%%%%%%
if (strcmp(cfg.in_fext, 'gps'))
   bindata = bindata([1 3 4],:); % logger_time [gga time] lon, lat
end
%%%%%%%%

% table the data onto the logger ddays
try
   gdata = NaN*ones(length(timdata(1,:)), length(bindata(:,1))-1);
   gdata(goodi,:) = table1([bin_fldday' bindata(2:end,:)'], logger_dday);
   gdata = gdata';
catch
   cfg.in_fext
   cfg.out_fext
   rawfilebase
   disp('not monotonic')
   keyboard
end

   
gdata(:,nani) = NaN;

if (length(gdata(1,:)) ~= length(timdata(1,:)))
   error('incorrect number of indices')
   keyboard
end


if (strcmp(cfg.out_fext, 'hdg'))
   write_bin(outfile, gdata, 'hdg', {'gyro_heading'});
elseif (strcmp(cfg.out_fext, 'pos'))
   write_bin(outfile, gdata, 'pos', {'lon', 'lat'});
elseif (strcmp(cfg.out_fext, 'spd'))
   write_bin(outfile, gdata, 'spd', {'meas_soundspeed'});
elseif (strcmp(cfg.out_fext, 'adu'))
   write_bin(outfile, gdata, 'adu', ...
        { 'adu_heading', 'pitch', 'roll', 'att_dday', 'mrms', 'brms'});
else
   error('not writing for some reason: output file extenion mismatch?')
end


function nani = find_gaps(logger_dday, serdata_dday, gap_seconds)
%find time ranges from logged serial data (serdata_dday) greater than gap_sec 
%return indices into logger_dday where NaNs should be placed due to gaps

 serdata_dday = serdata_dday(:);  %need a column vector

gapi = find(diff(serdata_dday)*86400 >= gap_seconds);
nani = [];
if (~isempty(gapi))
   gaptimes =  [serdata_dday(gapi) serdata_dday(gapi + 1)]; %serial data times
   for gapnum = 1:length(gapi) %find indices in logger_ddday
      newnani = find( (logger_dday >= gaptimes(gapnum(1),1) ) &...
                 (logger_dday <= gaptimes(gapnum(end),2)));
      nani = [nani; newnani];
   end
end

%%%%%


%%%%%%

function unscootched = unscootch(scootched, orig_dday, scootch_sec);
%
unscootched = scootched;

diffsec = 86400*(scootched - orig_dday);
scootchi = find( (abs(diffsec) > scootch_sec) & (diffsec > scootch_sec));
if (~isempty(scootchi))
   unscootched(scootchi) = orig_dday(scootchi) + scootch_sec/86400;
end
scootchi = find( (abs(diffsec) > scootch_sec) & (diffsec < - scootch_sec));
if (~isempty(scootchi))
   unscootched(scootchi) = orig_dday(scootchi) - scootch_sec/86400;
end



