function File = open_file(diafile,varargin)
%open_file  scan internal blocks of 1 DONAR dia file + aggregate into variables
%
% File = donar.open_file(diafile) opens a file and returns contents
% in structure File, where subfield Blocks contains meta-data per 
% internal block, and subfield Variables contains an aggregation
% of the blocks into unique variables. The DONAR codes are resolved
% for international nomenclature.
%
% 300 Mb files into 4000 blocks can take up to 10 min to open.
% For this reason a cache file is stored next to the dia file
% after each donar.open call(), and this is used any next call. Set
% keyword cache to 0 to prevent reading a cache (default 1, and it is 
% always written).
%
% To open and aggregate multiple files, use donar.open_files().
%
% Example:
% 
%  File            = donar.open_file(diafile)
%                    donar.disp(File)
% [data, metadata] = donar.read(File,1,6) % 1st variable, residing in 6th column
%
%See also: open_files, read, disp, open_file = scan_file + merge_headers
%          http://www.rws.nl/water/waterdata_waterberichtgeving/watergegevens/
%          http://www.helpdeskwater.nl/onderwerpen/kust-zee/scheepvaart/historische-gegevens/
%          https://data.overheid.nl/data/dataset/rws-donar-metis-service-rijkswaterstaat

%%  --------------------------------------------------------------------
%   Copyright (C) 2013 Deltares 4 Rijkswaterstaat (SPA Eurotracks)
%
%   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, either
%   version 2.1 of the License, or (at your option) any later version.
%
%   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/>.
%   --------------------------------------------------------------------

%% Version <http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html>
% $Id$
% $Date$
% $Author$
% $Revision$
% $HeadURL$
% $Keywords: $

   OPT.disp      = 100;
   OPT.cache     = 1;
   OPT.fix_cache = 1;
   
   if nargin==0
       File = OPT;return
   end
   OPT = setproperty(OPT,varargin);

%% always make cellstr

   if iscell(diafile)
      diafiles = diafile;
   else
      diafiles = {diafile};
   end

      cachefile = strrep(diafile,'.dia','_info.mat');
      if exist(cachefile) & OPT.cache
         File        = load(cachefile);
         disp('Loading cache generated by a previous donar.open_file() call.')

if OPT.fix_cache
    File.Filename  = diafile;
    % fix old cache files
    for ibl=1:length(File.Blocks)
       File.Blocks(ibl).file_index = ones(size(File.Blocks(ibl).index)); % by definition: open_file opens 1 file only
    end
end
         
      else
         File.Filename  = diafile;
         File.Blocks    = donar.scan_file(diafile,'disp',OPT.disp);
         for ibl=1:length(File.Blocks)
            File.Blocks(ibl).file_index = ones(size(File.Blocks(ibl).block_index)); % by definition: open_file opens 1 file only
         end
         try
           save(cachefile,'-struct','File')
           disp('Stored cache for faster opening in future donar.open_file() call.')
         catch % in case you read from read-only folder
           disp('Failed storing cache for faster opening in future donar.open_file() call.')
         end
      end
      
      File.Filename  = diafile;
      File.Variables = donar.merge_headers(File.Blocks);

%%

   if OPT.disp > 0
      disp([mfilename,' # of parameters = ',    num2str(length(File.Variables))])  
      disp([mfilename,' # of values     = ',    num2str(sum([File.Blocks.nval]))])  
      disp([mfilename,' # of blocks     = ',    num2str(length(File.Blocks))])
   end
