function [data,failed] = process_rt17 (data)
% process_rt17: processes RT17 data
failed=1;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% initialize variables
data.GPS.week=[];
data.GPS.dAT=[];
data.GPS.time_zone=[];
data.GPS.position=[];
data.GPS.observables=[];

clock_start=toc;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% process RT17 file

% get file names
if ((strcmp(data.GPS.type,'RT17')==1)|(strcmp(data.GPS.type,'PreRT17')==1))
   j01=findstr(data.GPS.rt17_file,'.');
   dat_file=strcat(data.GPS.rt17_file(1:(j01(end)-1)),'.dat');
   fix_file=strcat(data.GPS.rt17_file(1:(j01(end)-1)),'NoDup17.dat');
   d11_file=strcat(data.GPS.rt17_file(1:(j01(end)-1)),'.d11');
   d17_file=strcat(data.GPS.rt17_file(1:(j01(end)-1)),'.d17');
   d21_file=strcat(data.GPS.rt17_file(1:(j01(end)-1)),'.d21');
   
   if (strcmp(data.GPS.type,'RT17')==1)
      % RT172dat %Name%.r17 %Name%.dat
      dos(sprintf('RT172dat "%s" "%s"',data.GPS.rt17_file,dat_file));
      
      % nodup17 %Name%.dat
      dos(sprintf('nodup17 "%s"',dat_file));
      
      % rename DAT file
      delete(dat_file);
      dos(sprintf('move "%s" "%s"',fix_file,dat_file));
   end;
elseif (strcmp(data.GPS.type,'DAT')==1)
   j01=findstr(data.GPS.DAT_file,'.');
   dat_file=data.GPS.DAT_file;
   d11_file=strcat(data.GPS.DAT_file(1:(j01(end)-1)),'.d11');
   d17_file=strcat(data.GPS.DAT_file(1:(j01(end)-1)),'.d17');
   d21_file=strcat(data.GPS.DAT_file(1:(j01(end)-1)),'.d21');
end;

if (strcmp(data.GPS.type,'PreRT17')==0)
   % viewdat -d11 -p* -x -o%Name%.d11 %Name%.dat
   dos(sprintf('viewdat -d11 -p* -m -o"%s" "%s"',d11_file,dat_file));
   
   % viewdat -d17 -p* -x -o%Name%.d17 %Name%.dat
   dos(sprintf('viewdat -d17 -p* -m -o"%s" "%s"',d17_file,dat_file));
   
   % viewdat -d21 -p* -o%Name%.d21 %Name%.dat
   dos(sprintf('viewdat -d21 -p* -o"%s" "%s"',d21_file,dat_file));
   
   fprintf('\n\n');
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read D21 (eph) file

fdata=dir(d21_file);
if (fdata.bytes>0)
   % open input file
   infile=fopen(d21_file);	                  % open data file
   if (infile==-1)                           % check for file
      fprintf('could not open %s file!\n',d21_file);
      return;
   else
      fprintf('loading Type 21 file: %s\n',d21_file);
   end;
   
   % open wait bar
   whan=waitbar(0,'Analyzing Ephemeris Data, Please wait...',...
      'Name','Analyzing',...
      'CloseRequestFcn','closereq',...
      'WindowStyle','Modal',...
      'Pointer','watch');
   drawnow;
   
   % loop to read file
   i=0;
   SV_count=0;
   percent_complete=0;
   last_percentage=0;
   eof=0;
   fdata=dir(d21_file);
   readline=fgetl(infile);
   while (eof==0)
      i=i+1;
      
      % update waitbar
      percent_complete=round(100*ftell(infile)/fdata.bytes)/100;
      if (percent_complete~=last_percentage)
         last_percentage=percent_complete;
         waitbar(percent_complete,whan);
         drawnow;
      end;
      
      % extract data
      if ((size(readline,2)>25)&(strcmp(readline(1:25),'TYPE 21: Ephemeris for sv')==1))
         SV_count=SV_count+1;
         SV_no=str2double(readline(26:end));
         fprintf('  Ephemeris for sv: %.0f\n',SV_no);
         % get week number
         i=i+1;
         readline=fgetl(infile);
         j01=strfind(readline,'WN:');
         j02=strfind(readline,'TOW:');
         data.GPS.week=str2double(readline((j01+3):(j02-1)));
         fprintf('    Week Number: %.0f\n',data.GPS.week);
      else
         %fprintf('  Discarded Type 21 Line: %s\n',readline);
      end;
      
      % read next line
      eof=feof(infile);
      if (eof==0)
         readline=fgetl(infile);
         if ((isempty(readline)==1)&(feof(infile)==0))
            readline=fgetl(infile);
         end;
      end;
   end;
   
   % close all files & figures
   fclose(infile);
   set(whan,'Pointer','arrow');
   delete(whan);
   fprintf('  Type 21 file lines read: %.0f\n',i);
   fprintf('  Ephemerides loaded: %.0f\n\n',SV_count);
else
   fprintf('Empty Ephemeris File.\n');
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read D11 (position) file

fdata=dir(d11_file);
if (fdata.bytes>0)
   % open wait bar
   whan=waitbar(0.10,'Analyzing Position Data, Please wait...',...
      'Name','Analyzing',...
      'CloseRequestFcn','closereq',...
      'WindowStyle','Modal',...
      'Pointer','watch');
   drawnow;
   
   % load the tab delimited position file
   [data.GPS.position,fail]=load_tab(d11_file);
   if (fail==1)
      return;
   end;
   
   % position computations
   waitbar(0.50,whan);
   
   % decode position flag
   for (i=1:size(data.GPS.position,1))
      data.GPS.position(i,7)=decode_status(data.GPS.position(i,7));
   end;
   
   waitbar(0.75,whan);
   
   % find time greater than one week
   j01=[];
   j01=find(data.GPS.position(:,1)>604800);
   if (isempty(j01)==0)
      data.GPS.position(j01,1)=data.GPS.position(j01,1)-604800;
   end;
   
   % remove duplicate records
   clear j01;
   [j01,j02,j03]=unique(data.GPS.position(:,1));
   if (size(j02,1)~=size(j03,1))
      data.GPS.position=data.GPS.position(j02,:);
   end;
   
   % geodetic parameters for conversions
   a=6378137;                                            % semi-major axis
   f_inv=298.257223563;                                  % inverse flattening
   eSQ=2/f_inv-(1/f_inv)^2;                              % first eccentricity
   w=sqrt(1-eSQ*(sin(mean(data.GPS.position(:,2))))^2);  % "w" constant for latitude
   M=a*(1-eSQ)/w^3;                                      % radius of curvature in the meridian
   N=a/w;                                                % radius of curvature in the prime vertical
   rho=sqrt(M*N);                                        % mean radius of curvature
   LONGo=min(data.GPS.position(:,3))*pi/180;
   LATo=min(data.GPS.position(:,2))*pi/180;
   ho=min(data.GPS.position(:,4));
   
   % move velocity columns & do conversions to meters
   data.GPS.position(:,11)=N*data.GPS.position(:,9)*cos(LATo);
   data.GPS.position(:,12)=M*data.GPS.position(:,8);
   data.GPS.position(:,13)=data.GPS.position(:,10);
   
   % convert to delta [e,n,u]
   data.GPS.position(:,8)=N*(data.GPS.position(:,3)*pi/180-LONGo)*cos(LATo);
   data.GPS.position(:,9)=M*(data.GPS.position(:,2)*pi/180-LATo);
   data.GPS.position(:,10)=data.GPS.position(:,4)-ho;
   
   % compute velocity
   data.GPS.position(:,14)=[nan];
   data.GPS.position(2:end,14)=[(sqrt((data.GPS.position(2:end,8)-data.GPS.position(1:(end-1),8)).^2+...
         (data.GPS.position(2:end,9)-data.GPS.position(1:(end-1),9)).^2+...
         (data.GPS.position(2:end,10)-data.GPS.position(1:(end-1),10)).^2))./(data.GPS.position(2:end,1)-data.GPS.position(1:(end-1),1))];
   
   % compute accel
   data.GPS.position(:,15)=[nan];
   data.GPS.position(3:end,15)=(data.GPS.position(3:end,14)-data.GPS.position(2:(end-1),14))./(data.GPS.position(3:end,1)-data.GPS.position(2:(end-1),1));
   
   % close waitbar
   set(whan,'Pointer','arrow');
   delete(whan);
   fprintf('  Position records loaded: %.0f\n\n',size(data.GPS.position,1));
else
   fprintf('Empty Position File.\n');
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read D17 file

fdata=dir(d17_file);
if (fdata.bytes>0)
   data.GPS.observables.time=[];
   data.GPS.observables.SV{32}=[];
   
   % open wait bar
   whan=waitbar(0.10,'Analyzing Observable Data, Please wait...',...
      'Name','Analyzing',...
      'CloseRequestFcn','closereq',...
      'WindowStyle','Modal',...
      'Pointer','watch');
   drawnow;
   
   % load the tab delimited position file
   [table,fail]=load_tab(d17_file);
   if (fail==1)
      return;
   end;
   
   waitbar(0.50,whan);
   
   % get a vector of unique times (data.GPS.observables.time(:,1))
   [times,rows]=unique(table(:,1));
   data.GPS.observables.time=times;
   
   % add the biass to the time vector (data.GPS.observables.time(:,2))
   data.GPS.observables.time(:,2)=table(rows,2);
   
   % sort SV records (data.GPS.observables.SV{PRN})
   for (i=1:size(data.GPS.observables.SV,2))
      j01=find(table(:,3)==i);
      if (isempty(j01)==0)
         [j02,j03,j04]=intersect(table(j01,1),data.GPS.observables.time(:,1));
         data.GPS.observables.SV{i}(j03,:)=[table(j01,5) table(j01,4) table(j01,6) table(j01,7) table(j01,8) table(j01,9) table(j01,10) table(j01,11) table(j01,12) table(j01,13) table(j01,14) table(j01,15) table(j01,16)];
         clear j02 j03 j04;
      end;
      clear j01;
   end;
   
   % renumber the SV tracking & slip codes
   % -m option for MatLab output
   % Position display includes velocities when -m specified
   % Missing fields in measurement records now contain NAN
   for (i=1:size(data.GPS.observables.SV,2))
      if (isempty(data.GPS.observables.SV{i})==0)
         % L1 slip values (col 10): 0 no slip, 1 slip, -1 invalid range => col 7: 5 no slip, 4 slip, 3 invalid range
         j01=find(data.GPS.observables.SV{i}(:,7)==0);
         if (isempty(j01)==0)
            data.GPS.observables.SV{i}(j01,7)=5*ones(length(j01),1);
         end;
         j02=find(data.GPS.observables.SV{i}(:,7)==1);
         if (isempty(j02)==0)
            data.GPS.observables.SV{i}(j02,7)=4*ones(length(j02),1);
         end;
         j03=find(data.GPS.observables.SV{i}(:,7)==-1);
         if (isempty(j03)==0)
            data.GPS.observables.SV{i}(j03,7)=3*ones(length(j03),1);
         end;
         
         % L1 code values (col 11): 0 C/A code, 1 P code => col 8:
         
         % L2 slip values (col 15): 0 no slip, 1 slip => col 12: 2 no slip, 1 slip
         j04=find(data.GPS.observables.SV{i}(:,12)==0);
         if (isempty(j04)==0)
            data.GPS.observables.SV{i}(j04,12)=2*ones(length(j04),1);
         end;
         
         % L2 code values (col 16): 0 no code, 1 cross-correlation or encrypted, 2 P code, 3 C/A or C/S code => col 13:
      end;
      clear j01 j02 j03 j04;
   end;
   
   waitbar(0.75,whan);
   
   % check that there are times for all observable records
   for (i=1:size(data.GPS.observables.SV,2))
      if (isempty(data.GPS.observables.SV{i})==0)
         if (size(data.GPS.observables.SV{i},1)<size(data.GPS.observables.time,1))
            data.GPS.observables.SV{i}(size(data.GPS.observables.time,1),1:13)=[nan nan nan nan nan nan nan nan nan nan nan nan nan];
         elseif (size(data.GPS.observables.SV{i},1)>size(data.GPS.observables.time,1))
            fprintf('SV %.0f contains more records than the Time Table\n',i);
            return;
         end;
      end;
   end;
   
   % find time greater than one week
   j01=[];
   j01=find(data.GPS.observables.time(:,1)>604800);
   if (isempty(j01)==0)
      data.GPS.observables.time(j01,1)=data.GPS.observables.time(j01,1)-604800;
   end;
   
   % close waitbar
   set(whan,'Pointer','arrow');
   delete(whan);
   fprintf('  Type 17 epochs processed: %.0f\n\n',size(data.GPS.observables.time,1));
else
   fprintf('Empty Observables File.\n');
end;

fprintf(strcat('RT17 Processing Completed, Runtime: %.1f seconds (%.1f minutes)\n'),(toc-clock_start),(toc-clock_start)/60);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% user inputs

% check that week number has been set
if (isempty(data.GPS.week)==1)
   dlg_prompt={'Enter GPS Week for this data set:','Enter the Time Zone:','Enter the current dAT for this data set:','Data frequency (sec):'};
   dlg_title='User Time Input Dialog';
   bin=inputdlg(dlg_prompt,dlg_title,1,{num2str(data.config.week),num2str(data.config.time_zone),num2str(data.config.dAT),num2str(data.config.rate)});
   if (isempty(bin)==0)
      data.GPS.week=str2double(char(bin(1)));
      data.GPS.time_zone=str2double(char(bin(2)));
      data.GPS.dAT=str2double(char(bin(3)));
      data.GPS.rate=str2double(char(bin(4)));
   else
      fprintf('input canceled!\n');
      return;
   end;
else
   dlg_prompt={'Enter the Time Zone:','Enter the current dAT for this data set:','Data frequency (sec):'};
   dlg_title='User Time Input Dialog';
   bin=inputdlg(dlg_prompt,dlg_title,1,{num2str(data.config.time_zone),num2str(data.config.dAT),num2str(data.config.rate)});
   if (isempty(bin)==0)
      data.GPS.time_zone=str2double(char(bin(1)));
      data.GPS.dAT=str2double(char(bin(2)));
      data.GPS.rate=str2double(char(bin(3)));
   else
      fprintf('input canceled!\n');
      return;
   end;
end;
fprintf('  GPS Week Number: %.0f\n',data.GPS.week);
fprintf('  Time Zone: %.0f\n',data.GPS.time_zone);
fprintf('  dAT: %.0f\n',data.GPS.dAT);
fprintf('  data frequency (sec): %.1f\n\n',data.GPS.rate);

% update saved variables
data.config.week=data.GPS.week;
data.config.time_zone=data.GPS.time_zone;
data.config.dAT=data.GPS.dAT;
data.config.rate=data.GPS.rate;

% add one millisecond to the data rate
data.GPS.rate=data.GPS.rate+0.001;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% delete processing files

if (strcmp(data.GPS.type,'PreRT17')==0)
   delete(d11_file);
   delete(d17_file);
   delete(d21_file);
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
failed=0;
return;
