function DataSet = nc_getvarinfo ( arg1, arg2 )
% NC_GETVARINFO:  returns metadata about a specific NetCDF variable
%
% USAGE:  DataSet = nc_getvarinfo ( file_id, var_id );
%
% PARAMETERS:
% Input:
%    file_id:  
%        either a string that specifies the name of the NetCDF file, or
%        the already opened NetCDF file id
%    var_id:  
%        either a string that specifies the name of the NetCDF variable,
%        or the already accessed NetCDF variable id
%
%    If the filename and variable name are given, then the file will
%    be closed upon either successful completion of the routine or also
%    in the case of an error.  If the NetCDF IDs are given, then the
%    file is not closed (the calling routine has to take care of that).
%
% Output:
%    DataSet:
%        A structure whose fields contain information about the contents
%        of the NetCDF file.  The set of fields return in "fileinfo" are:
%
%        Name:  
%            a string containing the name of the variable.
%        Nctype:  
%            a string specifying the NetCDF datatype of this variable.
%        IsUnlimitedVariable:  
%            Flag, either 1 if the variable has an unlimited dimension
%            or 0 if not.
%        Dimensions:  
%            a cell array with the names of the dimensions upon which
%            this variable depends.
%        Rank:  
%            Array that describes the size of each dimension upon which 
%            this dataset depends.
%        Attribute:  
%            An array of structures corresponding to the attributes defined
%            for the specified variable.
%                         
%        Each "Attribute" element contains the following fields.
%
%            Name:  
%                a string containing the name of the attribute.
%            Nctype:  
%                a string specifying the NetCDF datatype of this 
%                attribute.
%            Attnum:  
%                a scalar specifying the attribute id
%            Value: 
%                either a string or a double precision value 
%                corresponding to the value of the attribute
%
% In case of an error, an exception is thrown.
%
%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% $Id: nc_getvarinfo.m 1946 2006-10-23 12:51:58Z johnevans007 $
% $LastChangedDate: 2006-10-23 08:51:58 -0400 (Mon, 23 Oct 2006) $
% $LastChangedRevision: 1946 $
% $LastChangedBy: johnevans007 $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




% Show usage if too few arguments.
%
if nargin<2 
	error ( '%s:  not enough input arguments.\n', mfilename );
end




%
% Do we use java instead of mexnc?
if strcmp ( nc_method, 'java' )
	DataSet = nc_getvarinfo_java(arg1,arg2);
	return
end




%
% If we are here, then we must have been given something local.
if ischar(arg1) & ischar(arg2)

	ncfile = arg1;
	varname = arg2;


	%
	% Open netCDF file
	%
	[ncid,status ]=mexnc('open',ncfile,nc_nowrite_mode);
	if status ~= 0
		error ( '%s:  mexnc:open failed on ''%s''.\n', mfilename, ncfile );
	end


	[varid, status] = mexnc('INQ_VARID', ncid, varname);
	if ( status < 0 )
		mexnc('close',ncid);
		fmt = '%s:  mexnc:inq_varid failed on ''%s'', variable ''%s''.\n';
		error ( fmt, mfilename, ncfile, varname );
	end

	
	% 
	% Get the information.
	try
		DataSet = get_varinfo ( ncid,  varid );
	catch
		mexnc('close',ncid);
		fmt = '%s:  get_varinfo failed on ''%s'', variable ''%s'', error msg was ''%s''.\n';
		error ( fmt, mfilename, ncfile, varname, lasterr );
	end

	%
	% close whether or not we were successful.
	mexnc('close',ncid);


elseif isnumeric ( arg1 ) & isnumeric ( arg2 )

	ncid = arg1;
	varid = arg2;

	DataSet = get_varinfo ( ncid,  varid );

else
	fmt = '%s:  cannot have mixed input types.  Either specify the filename and variable name, or give the NetCDF file id and variable id.\n';
	error ( fmt, mfilename );
end


return





function DataSet = get_varinfo ( ncid, varid )



[record_dimension, status] = mexnc ( 'INQ_UNLIMDIM', ncid );
if status < 0
	error ( '%s:  mexnc:inq failed, ''%s''.\n', mfilename, mexnc ( 'strerror', status ) );
end



[varname, datatype, ndims, dims, natts, status] = mexnc('INQ_VAR', ncid, varid);
if status < 0 
	error ( '%s:  mexnc:inq_var failed on varid %d, file %s.\n', mfilename, varid, ncfile );
end



DataSet.Name = varname;
DataSet.Nctype = datatype;

%
% Assume the current variable does not have an unlimited dimension until
% we know that it does.
DataSet.IsUnlimitedVariable = 0;

if ndims == 0
	DataSet.Dimension = [];
	DataSet.Size = 1;
	DataSet.Rank = 1;
else



	for j = 1:ndims
	
		[dimname, dimlength, status] = mexnc('INQ_DIM', ncid, dims(j));
		if ( status < 0 )
			fprintf ( 2, '%s:  mexnc:inq_dim failed on dimid %d.\n', mfilename, dims(j) );
			return
		end
	
		DataSet.Dimension{j} = dimname; 
		DataSet.Size(j) = dimlength;
	
		if dims(j) == record_dimension
			DataSet.IsUnlimitedVariable = 1;
		end
	end
	DataSet.Rank = length(dims);
end

%
% get all the attributes
if natts == 0
	DataSet.Attribute = struct([]);
else
	for attnum = 0:natts-1
		DataSet.Attribute(attnum+1) = nc_get_attribute_struct ( ncid, varid, attnum );
	end
end







return











function DataSet = nc_getvarinfo_java ( ncfile, varname )
%
% This function handles the java case.

import ucar.nc2.dods.*     % import opendap reader classes
import ucar.nc2.*          % have to import this (NetcdfFile) as well for local reads
                           % Now that's just brilliant.  



%
% Open netCDF file
%
if snc_is_url ( ncfile )
	try
		jncid = DODSNetcdfFile(ncfile);
	catch
		strformat = '%s:  DODSNetcdfFile failed on %s, ''%s''.\n';
		error ( strformat, mfilename, ncfile, lasterr ); 
	end
else
	try
		jncid = NetcdfFile(ncfile);
	catch
		strformat = '%s:  NetcdfFile failed on %s, ''%s''.\n';
		error ( strformat, mfilename, ncfile, lasterr ); 
	end
end


jvarid = jncid.findVariable(varname);
if isempty(jvarid)
	close(jncid);
	error ( '%s:  Could not locate variable %s', mfilename, varname );
end


%
% All the details are hidden here because we need the exact same
% functionality in nc_info.
DataSet = snc_java_varid_info ( jvarid );


close ( jncid );

return
