function varargout=wldep(cmd,varargin)
%WLDEP Read/write Delft3D field files (e.g. depth files).
%   WLDEP can be used to read and write Delft3D field
%   files used for depth and roughness data.
%
%   DEPTH=WLDEP('read',FILENAME,SIZE)
%   or
%   DEPTH=WLDEP('read',FILENAME,GRID)
%   where GRID was generated by WLGRID.
%
%   STRUCT=WLDEP(...,'multiple') to read multiple fields
%   from the file. The function returns a structure vector
%   with one field: Data.
%   [FLD1,FLD2,...]=WLDEP(...,'multiple') to read multiple
%   fields from the file. The function returns one field
%   to one output argument.
%
%   WLDEP('write',FILENAME,MATRIX)
%   or
%   WLDEP('write',FILENAME,MATRIX1,MATRIX2,MATRIX3,...)
%   or
%   WLDEP('write',FILENAME,STRUCT)
%   where STRUCT is a structure vector with one field: Data.
%
%   Optionally you may add keywords between data blocks
%   by inserting Keyword strings between the matrices.
%   The keywords will be enclosed in single quotes in the
%   file. If the keyword is empty, nothing will be written.
%
%   WLDEP('write',FILENAME,KEYWORD1,MATRIX1,KEYWORD2,MATRIX2,...)
%   or
%   WLDEP('write',FILENAME,STRUCT)
%   where STRUCT is a structure vector with fields Data and
%   Keyword.
%
%   NOTE: use WLDEP('write',FILENAME,'',MATRIX1) to suppress the
%   interactive questions to change sign and extend array
%   size in case of one matrix writes.
%
%See also: WLGRID

%----- LGPL --------------------------------------------------------------------
%                                                                               
%   Copyright (C)  Stichting Deltares, 2011.                                     
%                                                                               
%   This library is free software; you can redistribute it and/or                
%   modify it under the terms of the GNU Lesser General Public                   
%   License as published by the Free Software Foundation version 2.1.                         
%                                                                               
%   This library is distributed in the hope that it will be useful,              
%   but WITHOUT ANY WARRANTY; without even the implied warranty of               
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU            
%   Lesser General Public License for more details.                              
%                                                                               
%   You should have received a copy of the GNU Lesser General Public             
%   License along with this library; if not, see <http://www.gnu.org/licenses/>. 
%                                                                               
%   contact: delft3d.support@deltares.nl                                         
%   Stichting Deltares                                                           
%   P.O. Box 177                                                                 
%   2600 MH Delft, The Netherlands                                               
%                                                                               
%   All indications and logos of, and references to, "Delft3D" and "Deltares"    
%   are registered trademarks of Stichting Deltares, and remain the property of  
%   Stichting Deltares. All rights reserved.                                     
%                                                                               
%-------------------------------------------------------------------------------
%   http://www.deltaressystems.com
%   $HeadURL$
%   $Id$

if nargin==0
   if nargout>0
      varargout=cell(1,nargout);
   end
   return
end

switch cmd
   case 'read'
      if nargout>1 % automatically add 'multiple'
         if nargin==3 % cmd, filename, size
            varargin{3}='multiple';
         end
      end
      Dep=Local_depread(varargin{:});
      if isstruct(Dep)
         if length(Dep)<nargout
            error('Too many output arguments.')
         end
         if nargout==1
            varargout{1}=Dep;
         else
            for i=1:max(1,nargout)
               varargout{i}=Dep(i).Data;
            end
         end
      elseif nargout>1
         error('Too many output arguments.')
      else % nargout<=1
         varargout={Dep};
      end
   case 'write'
      Out=Local_depwrite(varargin{:});
      if nargout>0
         varargout{1}=Out;
      end
   otherwise
      error('Unknown command')
end


function DP=Local_depread(filename,dimvar,option)
% DEPREAD reads depth information from a given filename
%    DEPTH=DEPREAD('FILENAME.DEP',SIZE)
%    or
%    DEPTH=DEPREAD('FILENAME.DEP',GRID)
%    where GRID was generated by GRDREAD.
%
%    ...,'multiple') to read multiple fields from the file.

DP=[];

if nargin<2
   error('No size or grid specified.')
end

if nargin<3
   multiple=0;
else
   multiple=strcmp(option,'multiple');
   if ~multiple
      warning('Unknown option.')
   end
end

if strcmp(filename,'?')
   [fname,fpath]=uigetfile('*.*','Select depth file');
   if ~ischar(fname)
      return
   end
   filename=[fpath,fname];
end

fid=fopen(filename);
if fid<0
   error(['Cannot open ',filename,'.'])
end
if isstruct(dimvar) % new grid format G.X, G.Y, G.Enclosure
   dim=size(dimvar.X)+1;
elseif iscell(dimvar) % old grid format {X Y Enclosure}
   dim=size(dimvar{1})+1;
else
   dim=dimvar;
end
i=1;
More=1;
while 1
   %
   % Skip lines starting with *
   %
   line='*';
   cl=0;
   while ~isempty(line) & line(1)=='*'
      if cl>0
         DP(i).Comment{cl,1}=line;
      end
      cl=cl+1;
      currentpoint=ftell(fid);
      line=fgetl(fid);
   end
   fseek(fid,currentpoint,-1);
   %
   [DP(i).Data,NRead]=fscanf(fid,'%f',dim);
   if NRead==0 % accept dredging input files containing 'keyword' on the first line ...
      str=fscanf(fid,['''%[^' char(10) char(13) ''']%['']']);
      if ~isempty(str) & isequal(str(end),'''')
         [DP(i).Data,NRead]=fscanf(fid,'%f',dim);
         DP(i).Keyword=str(1:end-1);
      end
   end
   DP(i).Data=DP(i).Data;
   %
   % Read remainder of last line
   %
   Rem=fgetl(fid);
   if ~ischar(Rem)
      Rem='';
   else
      Rem=deblank(Rem);
   end
   if NRead<prod(dim)
      if strcmp(Rem,'')
         Str=sprintf('Not enough data in the file for complete field %i (only %i out of %i values).',i,NRead,prod(dim));
         if i==1 % most probably wrong file format
            error(Str)
         else
            warning(Str)
         end
      else
         error(sprintf('Invalid string while reading data: %s',Rem));
      end
   end
   pos=ftell(fid);
   if isempty(fscanf(fid,'%f',1))
      break % no more data (at least not readable)
   elseif ~multiple
      fprintf('More data in the file. Use ''multiple'' option to read all fields.\n');
      break % don't read data although there seems to be more ...
   end
   fseek(fid,pos,-1);
   i=i+1;
end
fclose(fid);
if ~multiple
   DP=DP.Data;
end


function OK=Local_depwrite(filename,varargin)
% DEPWRITE writes depth information to a given filename
%
% Usage: depwrite('filename',Matrix)
%
%    or: depwrite('filename',Struct)
%        where Struct is a structure vector with one field: Data

OK=0;
fid=fopen(filename,'w');
Keyword='';
interactive = length(varargin)==1;
for idp = 1:length(varargin)
   DP = varargin{idp};
   if ischar(DP)
      Keyword = DP;
   elseif isstruct(DP)
      % DP(1:N).Data=Matrix;

      for i=1:length(DP)
         if isfield(DP,'Keyword')
            Keyword = DP(i).Keyword;
         else
            Keyword = '';
         end
         writeblock(fid,DP(i).Data,Keyword);
      end
      Keyword = '';
   else
      % DP=Matrix;
      if DP(end,end)~=-999 & interactive
         switch input('Negate data points? (Y/N) ','s')
            case {'Y','y'}
               DP=-DP;
            otherwise
         end
         switch input('Grid extension: 9 (-999 values)/B (boundary values) /N (Don''t extend) ','s')
            case {'9'}
               DP=[DP -999*ones(size(DP,1),1); ...
                  -999*ones(1,size(DP,2)+1)];
            case {'B','b'}
               DP=[DP DP(:,end); ...
                  DP(end,:) DP(end,end)];
            otherwise
         end
      end
      writeblock(fid,DP,Keyword);
      Keyword = '';
   end
end
fclose(fid);
OK=1;


function writeblock(fid,DP,Keyword)
if ~isempty(Keyword)
   fprintf(fid,'''%s''\n',Keyword);
end

DP(isnan(DP))=-999;

Frmt=repmat('%15.8f  ',[1 size(DP,1)]);
k=8*12;
Frmt((k-1):k:length(Frmt))='\';
Frmt(k:k:length(Frmt))='n';
Frmt(end-1:end)='\n';

szDP=size(DP);
if length(szDP)<3
   kmax=1;
else
   kmax=prod(szDP(3:end));
end
for k=1:kmax
   fprintf(fid,Frmt,DP(:,:,k));
end
