function self = read(self, varargin)
%
%varargin{1} ........... waitbar (boolean)
%
% $Id$

% no waitbar per default
% ----------------------
wbool = false;

% check varargin
% --------------
if nargin > 1
  if varargin{1}
    wbool = true;
  end
end

% check file validity
% -------------------
self.nc_id = netcdf.open(self.file, self.mode);
if self.nc_id == -1
  error(['netcdf:netcdf', ...
    'The specified data file ''%s'' does not exist\n' ...
    'or is not in the directory which is on the MATLAB path'],...
    self.file);
end

% update waitbar title with Tex mode disable
% ------------------------------------------
if wbool
  %set(0,'DefaulttextInterpreter','none')
  wb = waitbar(0, ['Loading file.  Please  wait...']);
  hchild = get(wb,'children');
  htitle = get(hchild,'title');
  set(htitle,'Interpreter','None');
end

% create a temporary hashtable use to store data read in file
% -----------------------------------------------------------
hash = hashtable;

% returns the number of dimensions, variables, global attributes and
% eventually unlimited dimension in a netCDF file.
% ------------------------------------------------------------------
[n_dims, nvars, ngatts, unlimdimid] = netcdf.inq(self.nc_id);

% get dimensions and store to netcdf hashtable
% --------------------------------------------
for dimid = 0:n_dims-1
  
  % initialize empty structure
  % --------------------------
  s = [];
  
  % Get name and length of id dimension
  % -------------------------------------
  [dimname, dimlen] = netcdf.inqDim(self.nc_id, dimid);
  
  % Get dimid (dimension id) from name
  % normalement pas besoin, a verifier....
  % ----------------------------------
  %dimid = netcdf.inqDimId(self.nc_id, dimname);
  
  % fill dimension structure with name and boolean for unlimdimid
  % -------------------------------------------------------------
  s.dimlen = dimlen;
  if(dimid == unlimdimid)
    s.unlimited = true;
  else
    s.unlimited = false;
  end
  
  % put dimension name and length to temporary hashtable
  % ----------------------------------------------------
  hash = put(hash, dimname, s);
end

% put dimensions hashtable to netcdf hashtable
% --------------------------------------------
self = put(self, 'DIMENSIONS', hash);

% clear temporary hashtable for next use
% --------------------------------------
hash = clear(hash);
% bug (TODO), on ne peut pas utiliser hash = hash.clear !!!!
% 09/03/2009: ce n'est pas un bug, voir subsref de hashtable

% get variables and store to netcdf hashtable
% -------------------------------------------
for id = 0:nvars-1
  
  % moves the waitbar cursor
  % ------------------------
  if wbool
    waitbar( id/nvars, wb);
  end
  
  % initialize empty structure
  % --------------------------
  s = [];
  
  % return information about variable
  % ---------------------------------
  [varName, xtype, dimids, natts] = netcdf.inqVar(self.nc_id, id);
  
  % fill structure s with variable attribute names and values
  % ---------------------------------------------------------
  for attid = 0:natts-1
    
    % get attribute name
    % ------------------
    attName = netcdf.inqAttName(self.nc_id, id, attid);
    
    % if attribute name is '_FillValue', transforme to 'FillValue,
    % because Matlab dosn't handle member name begining with '_'
    % ------------------------------------------------------------
    if strcmp(attName, '_FillValue')
      s.('FillValue_') = netcdf.getAtt(self.nc_id, id, attName);
      
    else
      
      % otherwise, dynamically fill attribute member of structure s
      % with it's value
      % -----------------------------------------------------------
      s.(attName) = netcdf.getAtt(self.nc_id, id, attName);
    end
    
  end  % end for loop over variable attributes
  
  % add internal type__ member from xtype 2->char, 6->double
  % --------------------------------------------------------
  s.type__ = getConstantNames(self, xtype);
  
  % fill temporary structure s with value
  % -------------------------------------
  try
    s.data__ = netcdf.getVar(self.nc_id, id);
  
  % under Matlab R2011b, getVar thrown an error when all _EXT dimensions
  % are 0. In that case, set data to empty
  % ------------------------------------------------------------------
  catch ME
    fprintf('Notice: netcdf_native:read: %s set to empty\n', varName);
    % fprintf('Notice: netcdf_native:read: %s: %s\n', varName, ME.message);
    s.data__ = [];
  end
  
  % If a NetCDF variable has valid scale_factor and add_offset
  % attributes, then the data is scaled accordingly.
  % ----------------------------------------------------------
  if self.autoscale
    if isfield(s, 'scale_factor') && isfield(s, 'add_offset')
      s.data__ = s.data__ * s.scale_factor + s.add_offset;
    end
  end
  
  % replace FillValue_ by NaN only for numeric variable
  % autonan mode is set to true by default
  % ---------------------------------------------------
  if self.autonan && isfield(s, 'FillValue_')
    switch(xtype)
      case self.NC_CHAR
        % For now, do nothing.
        
      case { self.NC_DOUBLE, self.NC_FLOAT, self.NC_LONG,...
          self.NC_SHORT, self.NC_BYTE }
        
        % sometimes, FillValue could be a char a badformed netcdf
        % files
        % --------------------------------------------------------
        if isnumeric(s.('FillValue_'))
          s.data__(s.data__ == s.('FillValue_')) = NaN;
        else
          s.data__(s.data__ == str2double(s.('FillValue_'))) = NaN;
          
          % verrue, pour les fichiers Roscop netcdf mal formés
          % --------------------------------------------------
          if str2double(s.('FillValue_')) > 1e35
            s.data__(s.data__ >= 1e35) = NaN;
          end
        end
        
      otherwise
        error( 'unhandled datatype %d\n', xtype );
    end
  end
  
%   % if var is char and as vertical alignment, transpose it
%   % ------------------------------------------------------
%   %         if xtype == self.NC_CHAR && (size(s.data__, 1) ~= 1)
%   %           s.data__ = s.data__';
%   %         end
%   
%   % add internal dimension__ member
%   % Because MATLAB uses FORTRAN-style ordering, however, the order of
%   % the dimension IDs is reversed relative to what would be obtained
%   % from the C API
%   % ----------------------------
%   if length(dimids) > 1
%     s.data__ = permute(s.data__, fliplr(1:length(dimids)));
%     dimids = fliplr(dimids);
%   end
  
  % if var is char and as vertical alignment, transpose it
  % ------------------------------------------------------
  if xtype == self.NC_CHAR && (size(s.data__', 1) == 1)
    s.data__ = s.data__';
  
  % Because MATLAB uses FORTRAN-style indexing, we need to transpose
  % N-D array (k,i,j,...) to (i,j,k,...) however, the order of
  % the dimension IDs is reversed relative to what would be obtained
  % from the C API
  % If s.data__ is a vector, NetCDF API return vertical vector, 
  % do nothing, it's OK
  % -----------------------------------------------------------------
  elseif length(dimids) > 1
    s.data__ = permute(s.data__, fliplr(1:length(dimids)));
    dimids = fliplr(dimids);
  end
  
  for dimid = 1:numel(dimids)
    dimname = netcdf.inqDim(self.nc_id, dimids(dimid));
    
    % we need to reverse dimid
    % a verifier imperativement avec plusieurs dimensions
    % ---------------------------------------
    s.dimension__{dimid} = dimname;
  end
  
  % put variable name and value to temporary hashtable
  % --------------------------------------------------
  hash = put(hash, varName, s);
  
end


% put variable temporary hash to netcdf hashtable
% -----------------------------------------------
self = put(self, 'VARIABLES', hash);

% clear temporary hashtable for next use
% --------------------------------------
hash = clear(hash);

% get gloabal attributes and store to netcdf hashtable
% -----------------------------------------------------
for id = 0:ngatts-1
  
  % initialize empty structure
  % --------------------------
  s = [];
  
  % Get the name of the global attribute associated with the
  % variable.
  % --------------------------------------------------------
  gattName = netcdf.inqAttName(self.nc_id, ...
    self.NC_GLOBAL, id);
  
  % Get value of global attribute.
  % ------------------------------
  attVal = netcdf.getAtt(self.nc_id, ...
    self.NC_GLOBAL, gattName);
  
  % fill global attribute structure
  % -------------------------------
  s.key__  = gattName;
  s.data__ = attVal;
  
  % put attribute name and value to temporary hashtable
  % ---------------------------------------------------
  hash = put(hash, gattName, s);
end

% put attribute temporary hash to netcdf hashtable
% ------------------------------------------------
self = put(self, 'ATTRIBUTES', hash);

% Close waitbar
% -------------
if wbool
  close(wb)
end

% close netcdf file
% -----------------
netcdf.close(self.nc_id)

end % end of read function
