function [data, config] = restruct(instclass, dd, varargin)
% [dd, config] = restruct(instclass, data, varargin)
% index is indices: step, range, or list
% reshape things to output one structure with vel, amp, cor, pg, temperature,etc
% varargin can be  'irange' (index start and end)
%                  'ilist' (indices)
%                  'step' (subsample whole thing by this)
%                  'ddayrange' (ddrange start and end)


doconfig = 0;
if (nargout == 2)
   doconfig = 1;
end


if ~isstruct(dd) | isemptys(dd) 
   data = [];
   config =[];
   return
end

cfg.irange =  [];
cfg.ilist =     [];
cfg.ddayrange = [];
cfg.step =   1;
cfg = fillstruct(cfg, varargin, 0);

if isa(instclass, 'bb')
   inst = 'BB';
elseif isa(instclass, 'nb')
   inst = 'NB';
elseif isa(instclass, 'os')
   inst = 'OS';
elseif isa(instclass, 'son')
   inst = 'SON';
else
   help restruct
   error('choices for instclass are bb, nb, and os, son')
end


index = [1:length(dd.dday)]';
%% should replace this with get_ilist.m:
if (~isemptys(cfg.irange)),index = [cfg.irange(1):cfg.step:cfg.irange(2)]; end
if (~isemptys(cfg.ilist)),       index = cfg.ilist; end
if (~isemptys(cfg.ddayrange))
   [junk, first_index] = min(abs(dd.dday - cfg.ddayrange(1)));
   [junk, last_index]  = min(abs(dd.dday - cfg.ddayrange(end)));
   index = [first_index:cfg.step:last_index]';
end


data.dday = dd.dday(index);
data.ens_num = dd.ens_num(index);

nbins = length(dd.depth);

% assume a 3-dimensional arrays are [nbins X nbeams X nprofs]

fnames = fieldnames(dd);
for fnamei = 1:length(fnames)
   fname =  fnames{fnamei};
   fval = getfield(dd, fname);
   if length(size(fval)) == 3
      [nbins, nbeams, nprofs] = size(fval);
      for beami = 1:nbeams
         newname = sprintf('%s%d', fname, beami);
         data = setfield(data, newname, squeeze(fval(:, beami, index)));
      end
   end
   data.bins = [1:nbins]';
end

if isfield(dd, 'nav')
   if length(find(~isnan(dd.nav.txy2(1,:))) > 1) 
      isnav = 1;
   else
      isnav = 0;
   end
else
   isnav = 0;
end

   

if ~isfield(dd, 'corr_dday')
   if isfield(dd, 'nav')
      if isnav==1
         dd.corr_dday = dd.nav.txy2(1,:);
      end
   end
end

%%%%% do time series
if (isfield(dd, 'corr_dday')),   data.corr_dday = dd.corr_dday(index);  end
if (isfield(dd, 'heading')),   data.heading = dd.heading(index);  end
if (isfield(dd, 'pitch')),    data.pitch   = dd.pitch(index);   end
if (isfield(dd, 'roll')),     data.roll = dd.roll(index);       end
if (isfield(dd, 'temperature')), data.temperature = dd.temperature(index); end
if (isfield(dd, 'soundspeed')),
                        data.soundspeed = dd.soundspeed(index); end

if (isfield(dd, 'pressure')),  data.pressure = dd.pressure(index); end

if strcmp(dd.config.coordsystem, 'earth')
   if isfield(dd, 'enu') 
      fprintf('field ''enu'' exists; no need to create variable manually\n')
   else
      dd.enu = dd.vel;
   end
   %% take out the field called 'vel' so it's less confusing.
   dd = rmfield(dd, 'vel');
end


if (isfield(dd, 'enu'))
   data.umeas=squeeze(dd.enu(:,1,index));
   data.vmeas=squeeze(dd.enu(:,2,index));
   data.wmeas=squeeze(dd.enu(:,3,index));
end

if (isfield(dd, 'xyze'))
   data.emeas=squeeze(dd.xyze(:,4,index));
end


if isnav == 1
   data.nav = dd.nav;
   [data.mps, xx, yy, data.cog] = ...
       ll2mps(dd.nav.txy2(1,index), ...
              dd.nav.txy2(2,index), dd.nav.txy2(3,index));
   data.lon = unwrap_lon(dd.nav.txy2(2,:));
   data.lat = dd.nav.txy2(3,:);
   data.uship = diff(xx)./(86400*diff(dd.nav.txy2(1,index))); 
   data.vship = diff(yy)./(86400*diff(dd.nav.txy2(1,index))); 

   data.uship = [data.uship(1) data.uship];
   data.vship = [data.vship(1) data.vship];
   
   if isfield(data, 'umeas')
      data.uabs = data.umeas + repmat(data.uship, nbins, 1);
      data.vabs = data.vmeas + repmat(data.vship, nbins, 1);
   end
else
   data.nav = NaN;
   data.mps = NaN;
   data.cog = NaN;
   data.lon = NaN;
   data.lat = NaN;
   data.uship = NaN;
   data.uship = NaN;
   data.vship = NaN;
   data.vship = NaN;
end


if isfield(data, 'uabs') & isfield(data, 'vabs') & isfield(data, 'heading') 
   data.fabs = uv2fp(data.uabs, data.vabs, data.heading);
end


data.config =  dd.config;
if (isfield(dd,'bt'))
   data.bt.vel   = dd.bt.vel(:,index);
   data.bt.range  = dd.bt.range(:,index);
   if isfield(dd.bt, 'status'), data.bt.status = dd.bt.status(index);  end
   if isfield(dd.bt, 'cor'),    data.bt.cor    = dd.bt.cor(:,index);   end
   if isfield(dd.bt, 'sdb'),    data.bt.sdb    = dd.bt.sdb(:,index);   end
   if isfield(dd.bt, 'amp'),    data.bt.amp    = dd.bt.amp(:,index);   end
   if isfield(dd.bt, 'rssi'),   data.bt.rssi   = dd.bt.rssi(:,index);  end
   if isfield(dd.bt, 'pg'),     data.bt.pg     = dd.bt.pg(:,index);    end   
   if isfield(dd.bt, 'enu'),    data.bt.enu    = dd.bt.enu(:,index);   end   
end


if (isfield(dd, 'depth'))
   data.depth = dd.depth;
end

%do this on the final product
if (isfield(data, 'umeas'))
   rads = repmat((90-data.heading)*pi/180,length(data.umeas(:,1)),1);
   %foreport of measured vel
   fp = (data.umeas(:,index) + i*data.vmeas(:,index)).*exp(-i*rads);
   data.fmeas = real(fp);
   data.pmeas = imag(fp);
end


% now do aux_struct (if it exists)
if isfield(dd, 'aux_struct')
   get_instfields;
   for ofieldi = 1:length(instfields)
      if (isfield(dd.aux_struct, instfields{ofieldi}))
         ostruct = getfield(dd.aux_struct, instfields{ofieldi});
         data = setfield(data, instfields{ofieldi}, ostruct);
      end
   end
end




if (doconfig)

   %initialize some default titles and limits 

   config.title.vel1            = sprintf('%s BEAM 1 VELOCITY (m/s)', inst);
   config.title.vel2            = sprintf('%s BEAM 2 VELOCITY (m/s)', inst);
   config.title.vel3            = sprintf('%s BEAM 3 VELOCITY (m/s)', inst);
   config.title.vel4            = sprintf('%s BEAM 4 VELOCITY (m/s)', inst);

   config.title.cor1            = sprintf('%s BEAM 1 CORRELATION', inst);
   config.title.cor2            = sprintf('%s BEAM 2 CORRELATION', inst);
   config.title.cor3            = sprintf('%s BEAM 3 CORRELATION', inst);
   config.title.cor4            = sprintf('%s BEAM 4 CORRELATION', inst);

   config.title.sw1            = sprintf('%s BEAM 1 SPECTRAL WIDTH', inst);
   config.title.sw2            = sprintf('%s BEAM 2 SPECTRAL WIDTH', inst);
   config.title.sw3            = sprintf('%s BEAM 3 SPECTRAL WIDTH', inst);
   config.title.sw4            = sprintf('%s BEAM 4 SPECTRAL WIDTH', inst);

   config.title.amp1            = sprintf('%s BEAM 1 AMPLITUDE', inst);
   config.title.amp2            = sprintf('%s BEAM 2 AMPLITUDE', inst);
   config.title.amp3            = sprintf('%s BEAM 3 AMPLITUDE', inst);
   config.title.amp4            = sprintf('%s BEAM 4 AMPLITUDE', inst);

   config.title.sdb1            = sprintf('%s BEAM 1 SOUND (dB)', inst);
   config.title.sdb2            = sprintf('%s BEAM 2 SOUND (dB)', inst);
   config.title.sdb3            = sprintf('%s BEAM 3 SOUND (dB)', inst);
   config.title.sdb4            = sprintf('%s BEAM 4 SOUND (dB)', inst);

   config.title.rssi1            = sprintf('%s BEAM 1 RSSI', inst);
   config.title.rssi2            = sprintf('%s BEAM 2 RSSI', inst);
   config.title.rssi3            = sprintf('%s BEAM 3 RSSI', inst);
   config.title.rssi4            = sprintf('%s BEAM 4 RSSI', inst);

   config.title.umeas            = sprintf('%s MEAS U (m/s)', inst);
   config.title.vmeas            = sprintf('%s MEAS V (m/s)', inst);
   config.title.wmeas            = sprintf('%s MEAS W (m/s)', inst);
   config.title.emeas            = sprintf('%s ERROR VEL (m/s)', inst);


   config.minclipval.vel1 = -6;    config.maxclipval.vel1 =  6;
   config.minclipval.vel2 = -6;    config.maxclipval.vel2 =  6;
   config.minclipval.vel3 = -6;    config.maxclipval.vel3 =  6;
   config.minclipval.vel4 = -6;    config.maxclipval.vel4 =  6;


   config.minclipval.amp1 = 10;    config.maxclipval.amp1 =  200;
   config.minclipval.amp2 = 10;    config.maxclipval.amp2 =  200;
   config.minclipval.amp3 = 10;    config.maxclipval.amp3 =  200;
   config.minclipval.amp4 = 10;    config.maxclipval.amp4 =  200;


   config.minclipval.rssi1 = 10;    config.maxclipval.rssi1 =  200;
   config.minclipval.rssi2 = 10;    config.maxclipval.rssi2 =  200;
   config.minclipval.rssi3 = 10;    config.maxclipval.rssi3 =  200;
   config.minclipval.rssi4 = 10;    config.maxclipval.rssi4 =  200;


   config.minclipval.cor1 = 20;    config.maxclipval.cor1 =  260;
   config.minclipval.cor2 = 20;    config.maxclipval.cor2 =  260;
   config.minclipval.cor3 = 20;    config.maxclipval.cor3 =  260;
   config.minclipval.cor4 = 20;    config.maxclipval.cor4 =  260;

   config.minclipval.sw1 = 20;    config.maxclipval.sw1 =  260;
   config.minclipval.sw2 = 20;    config.maxclipval.sw2 =  260;
   config.minclipval.sw3 = 20;    config.maxclipval.sw3 =  260;
   config.minclipval.sw4 = 20;    config.maxclipval.sw4 =  260;

   config.minclipval.umeas = -6;    config.maxclipval.umeas =  6;
   config.minclipval.vmeas = -6;    config.maxclipval.vmeas =  6;
   config.minclipval.wmeas = -6;    config.maxclipval.wmeas =  6;
   config.minclipval.emeas = -6;    config.maxclipval.emeas =  6;


   config.comment = '';
end
