function [argout1, argout2, argout3, argout4, argout5, argout6] = getnscat20(...
    mode, get_ranges, get_dset, get_var, get_dset_stride, ...
    get_num_urls, get_georange, get_variables, get_archive, ...
    pass)
% old function statement:
%function [out1, out2, out3, out4, out5] = getnscat20(operation, pass)
%%%
%%% This is the get function for NSCAT level 2.0 data. It is different from
%%% getrectg with daily/monthly catalog servers in that it accesses two
%%% special inventory files (orbit data and equatorial crossing data) in
%%% order to perform the catalog function.
%%%
%%% The types of values returned by this function depend one the input
%%% arguments. That is, this function is really three functions rolled into
%%% one [Three functions would be much better!]. The formal parameters
%%% `mode' and `pass' select which of the three modes are
%%% performed. The parameters used to actually get the data (e.g., the
%%% space-time constraint) are stored in various global variables.
%%%
%%% mode: either the string `cat' or `get'. `cat' indicates that the
%%% caller wants a catalog of passes which match the current space-time
%%% constraint. `get' signals that the caller wants the data *but* that is
%%% modified by the second formal parameter.
%%%
%%% pass: if this is zero, return the approximate size in bytes of the
%%% current pending request (i.e., the request that would be made if all the
%%% orbits described in the global variable `inv' were accessed). If pass is
%%% > 0, then use that number as an index into `inv'; read the orbit at
%%% inv(pass). 
%%%
%%% Return values:
%%%
%%% When mode == `cat':
%%% out1: The inventory matrix.
%%% out2: nothing.
%%% out3: nothing.
%%% out4: Vector of pass times in decimal years.
%%% out5: Number of passes.
%%%
%%% When mode == `get' and pass == 0:
%%% out1: Megabytes in the request.
%%% out2: Number of passes.
%%%
%%% When mode == `get' and pass > 0:
%%% out1: Time for data in this file.
%%% out2: Matrix of Longitude values.
%%% out3: Matrix of Latitude values.
%%% out4: Matrix of U wind vector components.
%%% out5: Matrix of V wind vector components.
%%%
%%% Functions called:
%%%
%%% nscat_25_EQ: This function is used to compute the equatorial crossings
%%% used to build the inventory.
%%% nscat_25_inv: Given the crossings, build an inventory.
%%% nscatrows, nscatcols: Find the data's row and col bounding box.
%%%
%%% Notes: 
%%%
%%% The old getnscat20 function stored the inventory after creating it so
%%% that it would not have to be rebuilt by subsequent `get' calls. To do
%%% this, the inventory was made a global variable. Since building the
%%% inventory is very fast using local data, this function now builds an
%%% inventory for both `cat' *and* `get' requests.
%%%
%%% The mode == get, pass == 0 functionality is pretty hokey since it
%%% assumes that every request uses the entire file. In most cases that will
%%% not be the case.
%%%
%%% The get data part of this script could be enhanced by performing the data
%%% access in three steps for each pass: 1) Get the lat and lon matrices, 2)
%%% Scan the matrices to determine the indices the caller is interested based
%%% on the min/max lat/lon constraints, 3) Get the values matrices.
%%%
%%% $Id: getnscat20.m,v 1.22 1998/11/09 20:26:56 dbyrne Exp $

% $Log: getnscat20.m,v $
% Revision 1.22  1998/11/09 20:26:56  dbyrne
% *** empty log message ***
%
% Revision 1.5  1998/09/10 08:56:24  dbyrne
% Changed input to getfunctions so mode is first arg.
%
% Revision 1.4  1998/09/09 20:12:47  dbyrne
% Trying to bring this up-to-date.  Definitely not functional at the moment.
%
% Revision 1.3  1998/09/09 07:57:36  dbyrne
% replaced Data_Scale with DataScale, Data_Null with DataNull, and Data_Range
% with DataRange for consistency with other variables in the archive.m files.
%
% Revision 1.2  1998/09/09 07:40:21  dbyrne
% Replaced getrectangular with getrectg
%
% Revision 1.1  1998/05/17 14:18:04  dbyrne
% *** empty log message ***
%
% Revision 1.15  1997/12/09 20:00:07  jimg
% Fixed bug where number of URLs and dataset (accessed with `get' and
% num_passes == 0) was hosed. This function was returning a vector for the
% number of URLs when the caller expected an integer.
%
% Revision 1.14  1997/12/09 06:22:21  jimg
% Fixed broken index code.
% Added to comments about functions used.
%
% Revision 1.13  1997/12/09 03:41:30  jimg
% Fixed up comments.
% Added separate retrieval of Lat, Lon and wind values to minimize data
% transfered.
% Fixed bad return of time value.
%
% Revision 1.12  1997/11/22 01:08:08  jimg
% Fix annoying error about failure to assign output arguments.
%
% Revision 1.11  1997/11/22 00:49:30  jimg
% Marked remaining debugging statements. The calculation of dataset size
% appears to be correct but the value displayed by the browser is not right.
%
% Revision 1.10  1997/11/22 00:18:10  jimg
% Fixed up comments; addedd Log.
%

global archive;		% Name of metadata `master' file for this dataset.
global Time;		% 2D array; start and stop time of dataset.
global ranges;		% Contains the current space-time constraint.
global orbits;		% The inventory built by this function.


% Global variable LON_CO corresponds to the one in nscat_25_EQ.m
% Dec.31, 97	Liang

global LON_DIS;


% Global variable ascend will be used in nascatrows.m and nascatcols.m

global ascend;

eval(archive);		% Source archive metadata

% disp('evaluating the archive')
% keyboard

% ***
disp(['Mode: ' mode]);
if (strcmp(mode, 'get') == 1)
    disp(['Pass: ' pass]);
end

% *************** Get the inventory *************

% Extract constraint information from `ranges'.
mintime = max(Time(1), ranges(4,1));
maxtime = min(Time(2), ranges(4,2));
minlon = ranges(1,1);
maxlon = ranges(1,2);
minlat = ranges(2,1); 
maxlat = ranges(2,2);
if minlon < 0; minlon = minlon+360; end
if maxlon < 0; maxlon = maxlon+360; end


% Compute the ascending and descending equatorial crossings that correspond
% to orbits that fall within the given latitude/longitude box.

[aE aW dE dW] = nscat_25_EQ('CO', minlat, maxlat, minlon, maxlon);


% Find all orbits which match the equatorial crossings above.

orbits = nscat_25_orbits(aE, aW, dE, dW);


% Select orbits which fall within the time constraint.

time_idx = find(orbits(:,2) >= mintime & orbits(:,2) <= maxtime);
orbits = orbits(time_idx,:);


% If the request was `cat' return an inventory to the caller.
if strcmp(mode, 'cat')
    out1 = orbits;			% orbit, date, crossing, # of lines
    out2 = []; 
    out3 = []; 
    out4 = orbits(:,2);			% 2nd column is decimal date
    out5 = size(orbits,1);
    
    disp(' '); 
    disp(['Inventory completed: ' int2str(out5) ' orbits selected.']);
    disp(' ');

    return;
elseif strcmp(mode,'datasize')
    % Return the approximate (very) size of the pending request.
    % Assume the caller wants all of every passes.
    num_of_passes = size(orbits(:,1), 1);
    num_of_scans = 0;
    for p = 1 : num_of_passes
	num_of_scans = num_of_scans + orbits(p, 4);
    end
    
    % Each scan contains 4 matrices each of which contains 48 floating point
    % values (8 bytes each).
    out1 = (4 * 48 * 8 * num_of_scans) / (2^20);
    out2 = num_of_passes;
    out3 = [];
    out4 = [];
    out5 = [];
    % ***
    disp(['Number of scans: ' int2str(num_of_scans)]);
    disp(['Mbytes: ' num2str(out1)]);
    return;

else
    % Return data for pass number `pass'

    names = ('Wind_Speed', 'Wind_Dir');
    % Process: 
    % 1) Read the latitude matrix and use that to determine which rows to
    % read; constrain subsequent reads to only those row.
    % 2) Read the longitude matrix and use that to determine which columns to
    % read; constrain accordingly.
    % 3) Read the Wind speed and direction matrices.
    % 4) process into U and V vector components.
    orb_num = orbits(pass, 1);
    if (orbits(pass, 1) < 1000)
	File = ['W2500' int2str(orbits(pass, 1)) '.HDF'];
    else
	File = ['W250' int2str(orbits(pass, 1)) '.HDF'];
    end
    
    s2 = int2str(orbits(pass, 4) - 1);


    % Decide which of the descending or ascending part of the orbit crosses the 
    % selected area.
    % We care about the northern part of the orbits, and try to guarantee
    % the lontitude of the orbit is positive. 192.58 = 2*|LON_DIS|, is the
    % longitude distance between the two equqtorial crossing longitudes.

    if ( orbits(pass,3) < 192.58 )
        lon_cen = LON_DIS + orbits(pass,3) + 360;
    else
        lon_cen = LON_DIS + orbits(pass,3);
    end

    if ( lon_cen < maxlon)
      %	Select ascending part.
	ascend = 1;
    else
      %	Select descending part.
	ascend = 0;
    end



    % Read the latitude matrix
    Constraint = [LatitudeName '[0:' s2 '][0:47]'];
    URL = [Server, File, '?', Constraint];
    loaddods(URL);

    [row_start, row_stop] = nscatrows(minlat, maxlat, eval(LatitudeName));

    % NB: subtract 1 from indices because DODS uses 0-based indexing.
    row_constraint = [ '[' int2str(row_start-1) ':' int2str(row_stop-1) ']' ];



    % Read the longitude matrix
    % I request the quality flag and trim it, but won't use it.
    Constraint = [LongitudeName       row_constraint '[0:47],' ...  
                  deblank(names(1,:)) row_constraint '[0:47],' ...
  	          deblank(names(2,:)) row_constraint '[0:47],' ...
                 'WVC_Quality_Flag' row_constraint '[0:47]' ];

    URL = [Server, File, '?', Constraint];
    loaddods(URL);


    [col_start, col_stop] = nscatcols(minlon, maxlon, eval(LongitudeName));

    col_constraint = [ '[' int2str(col_start-1) ':' int2str(col_stop-1) ']' ];


    % Trim the latitude and longitude matrices so that they match the
    % speed/dir matrices in shape and size.
    trim_lat = [ LatitudeName '=' LatitudeName '(' int2str(row_start) ...
	        ':' int2str(row_stop) ',' int2str(col_start) ':' ...
	         int2str(col_stop) ');' ];
    eval(trim_lat);

    % NB: Added +1 to row extent to accommodate 1's indexing
    trim_lon = [ LongitudeName '=' LongitudeName '(1:' ...
	         int2str(row_stop-row_start+1) ',' int2str(col_start) ...
	        ':' int2str(col_stop) ');' ];
    eval(trim_lon);

    trim_Var1 = [ deblank(names(1,:)) '=' deblank(names(1,:)) '(1:' ...
	          int2str(row_stop-row_start+1) ',' int2str(col_start) ...
	          ':' int2str(col_stop) ');' ];
    eval(trim_Var1);

    trim_Var2 = [ deblank(names(2,:)) '=' deblank(names(2,:)) '(1:' ...
	          int2str(row_stop-row_start+1) ',' int2str(col_start) ...
	          ':' int2str(col_stop) ');' ];
    eval(trim_Var2);

    trim_flag = [ 'WVC_Quality_Flag =' 'WVC_Quality_Flag(1:' ...
	          int2str(row_stop-row_start+1) ',' int2str(col_start) ...
	          ':' int2str(col_stop) ');' ];
    eval(trim_flag);


    % Load up the return arguments.
    if isempty(TimeName) == 1 		% TimeName has no value.
	out1 = orbits(pass, 2);
    else
	out1 = eval(TimeName);
    end
    out2 = eval(LongitudeName);
    out3 = eval(LatitudeName);

    for k = 1:size(variables,1)
      if strcmp(deblank(variables(i,:)), 'U_Wind')
	V_Wind = Wind_Speed .* cos(Wind_Dir * pi / 18000.0);
      elseif strcmp(deblank(variables(i,:)), 'V_Wind')
	U_Wind = Wind_Speed .* sin(Wind_Dir * pi / 18000.0);
      end
    end
    
%    if strcmp(Convert, 'yes')		% Convert is in the metadata file.
%	% Convert speed and direction to U and V and return these
%	% For NSCAT winds, direction is oceanographic convention 
%	out4 = Wind_Speed .* sin(Wind_Dir * pi / 18000.0);
%	out5 = Wind_Speed .* cos(Wind_Dir * pi / 18000.0);
%    else 
%	out4 = eval(deblank(DodsName(1,:)));
%	out5 = eval(deblank(DodsName(2,:)));
%    end

    % Scale the values in out*.
    % Scale is defined in the archive metadata file.
    out2 = out2 * DataScale;
    out3 = out3 * DataScale;
    out4 = out4 * DataScale;
    out5 = out5 * DataScale;
    
    % If quality needed, uncomment the next line and add 'out6' to the list of output
    % argument.
    % out6 = eval('WVC_Quality_Flag');

    return;
end
