function satlan_write(FileIn, FileOut, Aux)
% SATLAN_WRITE - Format *.out files into NASA style format
%
% Use as: SATLAN_WRITE(FileIn)
%      or SATLAN_WRITE(FileIn, FileOut)
%      or SATLAN_WRITE([], FileOut)          % Prompts for input file
%      or SATLAN_WRITE(FileIn, FileOut, Aux)
%      or SATLAN_WRITE([], FileOut, Aux)     % Prompts for input file
%
% Note: because it gets times from argos messages, all times are in GMT

%
% Inputs: FileIn  = Name of File to reformat 
%         FileOut = Name of File to write (default = [FileIn '.ftp'])
%         Aux     = Structure of Auxilliary data returned by satlan3 (optional)
%                    if included it requires the following fields:
%                     FileName
%                     CalibrationFile
%                     Date
%                     Lat
%                     Lon

% Brian Schlining
% 25 Mar 1999

%==============
% Get FileName
%==============
if ~nargin | isempty(FileIn)
   [infile inpath] = uigetfile('*.out','Select ASCII Eqpac Data File',0,0);
   if infile == 0 
      return
   end
   FileIn = [inpath infile];
end

if nargin < 2 | isempty(FileOut)
   [PathOut FileName FileExt] = fileparts(FileIn);
   FileOut = [PathOut filesep FileName '.ftp'];
end

D   = readout(FileIn);
[Year Month Day Hour Minute Second] = datevec(D.TIME_TAG);  % Convert back to year Month Day
Second = round(Second);

ymd = Year*10000+Month*100+Day;
r   = length(D.TIME_TAG);

if nargin < 3
   [temp.path temp.file temp.ext] = fileparts(FileIn);
   Aux.FileName = [temp.file temp.ext];
   Aux.CalibrationFile = 'unknown';
   Aux.Date = [];
   Aux.Lat  = [];
   Aux.Lon = [];
   IntLat = ones(size(D.TIME_TAG))*-999;
   IntLon = IntLat;
else
   bad    = find(Aux.Lon > 180);
   Aux.Lon(bad) = -1*(360 - Aux.Lon(bad));
   IntLat = interp1q(Aux.Date,Aux.Lat,D.TIME_TAG);
   IntLon = interp1q(Aux.Date,Aux.Lon,D.TIME_TAG);
   if all(isnan(IntLat)) 
      Lat = [];
   else
      Lat = nanmedian(IntLat);
   end
   if all(isnan(IntLon))
      Lon = [];
   else
      Lon = nanmedian(IntLon);
   end
end

%==============================
% Get the valid position range
%==============================
if ~isempty(Lat)
   i = find(abs(Aux.Lat - Lat) < 0.05);       % Find Lons inside specifed range
   minLat = min(Aux.Lat(i));
   maxLat = max(Aux.Lat(i));
   i = find(abs(Aux.Lon - Lon) < 0.05);       % Find Lons inside specifed range
   minLon = min(Aux.Lon(i));
   maxLon = max(Aux.Lon(i));
else
   minLat = -999;
   maxLat = -999;
   minLon = -999;
   maxLon = -999;
end

%===============
% Begin Writing
%===============
fid = fopen(FileOut,'wt');         % Open the file for writing

%==================
% Write the header
%==================
fprintf(fid,'/begin_header\n');
fprintf(fid,'/affiliations=Monterey_Bay_Aquarium_Research_Institute\n');
fprintf(fid,'/experiment=TAO_Moorings\n');
fprintf(fid,'/cruise=TAO_98\n');
fprintf(fid,'/investigators=Francisco_Chavez,Pete_Strutton,Brian_Schlining\n');
fprintf(fid,'/contact=chfr@mbari.org,stpe@mbari.org,brian@mbari.org\n');
fprintf(fid,'/parameters=Lu,Ed,Lw,Nlw,Wt,CHL\n');
fprintf(fid,'/data_type=mooring\n');
fprintf(fid,'/original_file_name=%s\n',Aux.FileName);
fprintf(fid,'/delimiter=space\n');
fprintf(fid,'/missing=-999\n');
if ~isempty(Aux.Lat) | ~isempty(Aux.Lon)     % If Aux data is present
   fprintf(fid,'/north_latitude=%-5.3f[DEG]\n',maxLat);
   fprintf(fid,'/south_latitude=%-5.3f[DEG]\n',minLat);
   fprintf(fid,'/east_longitude=%-5.3f[DEG]\n',maxLon);
   fprintf(fid,'/west_longitude=%-5.3f[DEG]\n',minLon);
else                                         % If Aux data is not present
   fprintf(fid,'/north_latitude=%-5.3f[DEG]\n',-999);
   fprintf(fid,'/south_latitude=%-5.3f[DEG]\n',-999);
   fprintf(fid,'/east_longitude=%-5.3f[DEG]\n',-999);
   fprintf(fid,'/west_longitude=%-5.3f[DEG]\n',-999);
end
fprintf(fid,'/start_date=%8i\n',min(ymd));
fprintf(fid,'/end_date=%8i\n',max(ymd));
%fprintf(fid,'/start_time=%02i:%02i:%02i[GMT]\n',Hour(1), Minute(1), Second(1));
%fprintf(fid,'/end_time=%02i:%02i:%02i[GMT]\n',Hour(end), Minute(end), Second(end));
fprintf(fid,'/start_time=00:00:00[GMT]\n');
fprintf(fid,'/end_time=23:59:00[GMT]\n');
fprintf(fid,'/documents=mbari_mooring_readme.doc\n');
fprintf(fid,'/calibration_files=%s\n',Aux.CalibrationFile);
fprintf(fid,'! Comments: latitudes and longitudes above are the maximum and minimum range from points with good quality flags.\n'); 
fprintf(fid,'! Comments: The latitude and longitude values in the data are from linear interpolation of positions from the argos messages\n');
fprintf(fid,'! Comments: The median latitudes and longitudes from the interpolated data are:\n');
if ~isempty(Aux.Lat) | ~isempty(Aux.Lon)     % If Aux data is present
   fprintf(fid,'! median_longitude = %6.3f\n', Lon);
   fprintf(fid,'! median_latitude = %6.3f\n', Lat);
else                                         % If Aux data is not present
   fprintf(fid,'! median_longitude = %6.3f\n', -999);
   fprintf(fid,'! median_latitude = %6.3f\n', -999);
end
fprintf(fid,'! Comments: Last column is a quality flag: -1=bad, 0=unchecked, 1=good\n');
fprintf(fid,'! Comments: Bad quality flags may be due to:\n'); 
fprintf(fid,'! Comments:    1. Measured Ed or Lu < -2\n');
fprintf(fid,'! Comments:    2. Latitude or longitude > 0.05 degrees from the median latitude or longitude\n');
fprintf(fid,'! Comments:    3. Fouling ratio (Lu683/Lu555) > 0.1\n');
fprintf(fid,'! Comments: Unchecked quality flags occur when position data is not available\n');

% Write the fields...They are listed in satlan_ini.m. Changes to field names or
% the Field order need to be made there.
satlan_ini;
fprintf(fid,'/fields=Date1,Time,Date2,');
lenCol = length(ColumnS);
for k = 1:lenCol
   if k == lenCol
      fprintf(fid,'%s',char(ColumnS(k)));
   else
      fprintf(fid,'%s,',char(ColumnS(k)));
   end
   
end
fprintf(fid,'\n');

% Write the Units
fprintf(fid,'/units=yyyymmdd,hh:mm:ss,mm/dd/yyyy,');
for k = 1:lenCol
   if k == lenCol
      fprintf(fid,'%s',char(UnitsS(k)));
   else   
      fprintf(fid,'%s,',char(UnitsS(k)));
   end
end
fprintf(fid,'\n');

fprintf(fid,'/end_header@\n');

%=================================
% Edit the Data based on position
%=================================
if ~isempty(Lat)
   QCFlag = ones(r,1);
   i = find(abs(IntLat - Lat) > 0.05);       % Find Lons outside specifed range
   QCFlag(i) = -1;
   i = find(abs(IntLon - Lon) > 0.05);       % Find lats outside specified range
   QCFlag(i) = -1;
else
   QCFlag = zeros(r,1);
end

%===============================
% Edit the Data based on values
%===============================
Names = fieldnames(D);
for i = 1:length(Names);
   fieldName = char(Names(i));
   f = getfield(D,fieldName);
   if length(f) == r
      j         = find(isnan(f) | isinf(f));   
      f(j)      = -999;                        % non-finite values are tagged with -999
      if ~strcmp(fieldName, 'TIME_TAG')
         j      = find(f > 9999 | f < -999);   % Out of range values are tagged with -999
         f(j)   = -999;
      end
      QCFlag(j) = -1;
      j         = find(f < -2);     % Values less than -2 or greater than 9999 are flagged bad
      QCFlag(j) = -1;
      D         = setfield(D,fieldName,f);
   end
end

i = find(isnan(IntLat));
IntLat(i) = -999;
i = find(isnan(IntLon));
IntLon(i) = -999;


j = find(D.FOUL_none > 0.1);                    % Flag high fouling ratios
QCFlag(j) = -1;

%============
% Write Body
%============

for n = 1:r
   fprintf(fid,'%8i ',ymd(n));
   fprintf(fid,'%02i:%02i:%02i ',Hour(n), Minute(n), Second(n));
   fprintf(fid,'%02i/%02i/%4i ', Month(n), Day(n), Year(n));
   fprintf(fid,'%9.3f ', D.T_w(n));                  % Temp
   fprintf(fid,'%12.6f', D.FLUOR_none(n));
   fprintf(fid,'%12.6f', D.ED_412(n));
   fprintf(fid,'%12.6f', D.ED_443(n));
   fprintf(fid,'%12.6f', D.ED_490(n));
   fprintf(fid,'%12.6f', D.ED_510(n));
   fprintf(fid,'%12.6f', D.ED_555(n));
   fprintf(fid,'%12.6f', D.ED_656(n));
   fprintf(fid,'%12.6f', D.ED_670(n));
   fprintf(fid,'%12.6f', D.ED_683(n));
   fprintf(fid,'%12.6f', D.ED_PAR(n));
   fprintf(fid,'%12.6f', D.LU_412(n));
   fprintf(fid,'%12.6f', D.LU_443(n));
   fprintf(fid,'%12.6f', D.LU_490(n));
   fprintf(fid,'%12.6f', D.LU_510(n));
   fprintf(fid,'%12.6f', D.LU_555(n));
   fprintf(fid,'%12.6f', D.LU_670(n));
   fprintf(fid,'%12.6f', D.LU_683(n));
   fprintf(fid,'%12.6f', D.LU0_412(n));
   fprintf(fid,'%12.6f', D.LU0_443(n));
   fprintf(fid,'%12.6f', D.LU0_490(n));
   fprintf(fid,'%12.6f', D.LU0_510(n));
   fprintf(fid,'%12.6f', D.LU0_555(n));
   fprintf(fid,'%12.6f', D.LU0_670(n));
   fprintf(fid,'%12.6f', D.LU0_683(n));
   fprintf(fid,'%12.6f', D.LUWN_412(n));
   fprintf(fid,'%12.6f', D.LUWN_443(n));
   fprintf(fid,'%12.6f', D.LUWN_490(n));
   fprintf(fid,'%12.6f', D.LUWN_510(n));
   fprintf(fid,'%12.6f', D.LUWN_555(n));
   fprintf(fid,'%12.6f', D.LUWN_670(n));
   fprintf(fid,'%12.6f', D.LUWN_683(n));
   fprintf(fid,'%12.6f', D.CHLOC2_ugl(n));
   fprintf(fid,'%12.6f', D.CHLRAT_ugl(n));
   fprintf(fid,'%12.6f', D.CHLCZCS_ugl(n));
   fprintf(fid,'%12.6f', D.FOUL_none(n));
   fprintf(fid,'%12.6f', IntLat(n));
   fprintf(fid,'%12.6f', IntLon(n));
   fprintf(fid,' %2i \n',QCFlag(n));
end

fclose(fid);
