function varargout = ArcGisRead(fname,varargin)
%ARCGISREAD  read gridded data set in Arc ASCII Grid Format, and save as *.mat, *.nc file
%
%   S      = arcgisread(filename,<keyword,value>)
%  [X,Y,D] = arcgisread(filename,<keyword,value>)
%
% reads contents of <a href="http://en.wikipedia.org/wiki/ESRI_grid">ESRI arcGIS file</a> into 
% variables X,Y and D, or into a struct S that
% directly can be plotted with pcolor(D.x,D.y.D.val)
%
% The following keywords are recommended when using struct S:
%
%  OPT.varname       - name of data block (default 'val')
%  OPT.long_name     - netCDF-CF convention
%  OPT.standard_name - netCDF-CF convention
%  OPT.units         - netCDF-CF convention
%
%See web: <a href="http://en.wikipedia.org/wiki/ESRI_grid">http://en.wikipedia.org/wiki/ESRI_grid</a>
%         <a href="http://webhelp.esri.com/arcgisdesktop/9.2/index.cfm?id=1309&pid=1308&topicname=ASCII_to_Raster_%28Conversion%29">@ESRI</a>
%See also: ARCGIS2NC, ARC_SHAPE_READ, ARCGRIDREAD (in $ mapping toolbox)

%% User defined keywords

   OPT.plot          = 0;  % plot (default off, to prevent grinding of PC with big matrices)
   OPT.clim          = [-5 45]; % in OPT.units
   OPT.export        = 1;  % export plot
   OPT.mat           = 1;  % save as mat
   OPT.nc            = 0;  % save as netCDF
   OPT.type          = 'single';% 'double','int'
   
   OPT.varname       = 'val'; % name of data block 
   OPT.long_name     = ''; % netCDF-CF convention
   OPT.standard_name = ''; % netCDF-CF convention
   OPT.units         = ''; % netCDF-CF convention
   
   if nargin==0;D = OPT;return;end; % make function act as object
   
   OPT      = setproperty(OPT,varargin{:});

   D.varname         = OPT.varname;      
   D.long_name       = OPT.long_name;    
   D.standard_name   = OPT.standard_name;
   D.units           = OPT.units;        

%% Open file (TO DO: perform checks on file)

   D.filename = fname{1};
   fid        = fopen(D.filename);
   basename   = fullfile(fileparts(D.filename),filename(D.filename));

%% Read header

   s=fgetl(fid);[tmp rest]=strtok(s);D.ncols        = str2num(rest);
   s=fgetl(fid);[tmp rest]=strtok(s);D.nrows        = str2num(rest);
   s=fgetl(fid);[tmp rest]=strtok(s);D.xllcorner    = str2num(rest);
   s=fgetl(fid);[tmp rest]=strtok(s);D.yllcorner    = str2num(rest);
   s=fgetl(fid);[tmp rest]=strtok(s);D.cellsize     = str2num(rest);
   s=fgetl(fid);[tmp rest]=strtok(s);D.nodata_value = str2num(rest);

%% Read data

   D.(D.varname) = repmat(nan(OPT.type),[D.ncols,D.nrows]);
   D.(D.varname) = fscanf(     fid,'%f',[D.ncols,D.nrows])';
   D.(D.varname)(D.(D.varname)==D.nodata_value)=nan;

%% Create rectangular grid

   for irow=1:D.ncols
      D.x(irow)=D.xllcorner+D.cellsize*(  irow-0.5           );
   end
   for jcol=1:D.nrows
      D.y(jcol)=D.yllcorner+D.cellsize*(-(jcol-0.5)+(D.nrows)); % fixed bug in OET revision 2120
      % lowest row lies 0.5* cellsize above yllcorner
      % substitution of lowest row index jcol = nrows, gives
      % (-(jcol  -0.5)+(D.nrows)) = ...
      % (-(nrows -0.5)+(  nrows)) = ...
      %   -nrows +0.5+    nrows   = +0.5
   end

%% Write to *.mat file

   if OPT.mat
      save([basename,'.mat'],'-struct','D');
   end

%% Write to netCDF (*.nc) file

   if OPT.nc

      arcgrid2nc([basename,'.nc'],D,'long_name',OPT.long_name,'units',OPT.units);
   
   end

%% Plot data (do this last, as it can be really sloooow)

   if OPT.plot
%       TMP = figure;
      pcolor(D.x,D.y,D.(D.varname));
      clim=OPT.clim;
      clim(1) = min(min(D.val));
      clim(2) = max(max(D.val));
      shading interp;
      axis    equal;
      caxis  (clim)
     %tickmap('xy')
      xlim([D.xllcorner D.xllcorner+D.cellsize*D.ncols])
      ylim([D.yllcorner D.yllcorner+D.cellsize*D.nrows])
      colorbarwithtitle([OPT.long_name,' [',OPT.units,']']);
      if OPT.export
         print2screensize([basename,'.png'])
      end
%       try;close(TMP);end
      hold on
      
   end
   
%% output

   if nargout==1
      varargout = {D};
   elseif nargout==3
      varargout = {D.x,D.y,D.(D.varname)};
   end

%% EOF