function [status,param,np,modname,neq,nlag,nlead,eqname,eqtype,endog,delay,vtype,DOSMessage] = AiMInitialize(ModelFile,NameOfModel,OutputDirectory)
% AiMInitialize: Runs the AiM parser to create the matlab files compute_aim_data.m and compute_aim_matrices.m
%                in the model file directory. The latter file is then rewritten into a matlab function rather
%                than a script file. The model parameters are there also renamed so that the function accepts
%                a structure as input, where the structure has the correct parameters names, e.g., omega is
%                rewritten as ModelParameters.omega. Finally, AiMInitialize saves certain model information,
%                such as parameter names, names of variables, number of equations, lags, and leads, into a
%                mat file. This mat file is saved in the same directory as the "ModelFile", and it takes the
%                name given by the input variable "NameOfModel", with the file extension .mat appended.
%
% USAGE:
%
%       [status,param,np,modname,neq,nlag,nlead,eqname,eqtype,endog,delay,vtype] = AiMInitialize(ModelFile,NameOfModel,OutputDirectory)
%
% REQUIRED INPUT:   ModelFile (string vector) with full path and name of the model file to parse with AiM.
%
%                   NameOfModel (string vector) with a name for the model.
%
% OPTIONAL INPUT:   OutputDirectory (string vector) with the full path to the output directory
%
% REQUIRED OUTPUTS: status (integer). Indicates the status when attempting to solve the model.
%                          0: Everything is OK
%                          1: AiMParsing did not work out. Either an error message from dos or the
%                             file compute_aim_matrices.m was not found in the ModelFile directory.
%                          2: Number of data variables not equal to number of stochastic equations
%                          3: Illegal parameter names were used.
%
%                   param (string matrix), parameter names.
%
%                   np (integer), number of parameters
%
%                   modname (string vector), model name.
%
%                   neq (integer), number of equations.
%
%                   nlag (integer), number of lags.
%
%                   nlead (integer), number of leads.
%
%                   eqname (string matrix), equation names.
%
%                   eqtype (vector), equation types.
%
%                   endog (string matrix), endogenous names.
%
%                   delay (vector), indicators.
%
%                   vtype (vector), indicators.
%
%                   DOSMessage (string vector), with the error message from the AiM parser.
%
%
%                       Written by: Anders Warne
%                                   New Area Wide Model Project
%                                   DG-R/EMO
%                                   European Central Bank (ECB)
%                                   Email: anders.warne@ecb.europa.eu
%                                   Copyright © 2006-2009 European Central Bank.
%
%                       First version: July 18, 2006.
%                        This version: March 9, 2009.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LICENSE INFORMATION:
%
%      YADA is free software: you can redistribute it and/or modify
%      it under the terms of the GNU General Public License as published by
%      the Free Software Foundation, either version 3 of the License, or
%      (at your option) any later version.
%
%      This program 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 General Public License for more details.
%
%      You should have received a copy of the GNU General Public License
%      along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%      YADA is released under the GNU General Public License, Version 3,
%      29 June 2007 <http://www.gnu.org/licenses/>. The current release of
%      the program was last modified by the ECB on the "This version" date
%      above.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CHANGELOG:
%
% * 19-07-2006: Updated function documentation.
%
% * 20-07-2006: The function now also saves model information into a mat file in the subdirectory NameOfModel to the
%               ModelPath directory. This is also the location where "compute_aim_data.m" and "compute_aim_matrices.m"
%               are stored.
%
% * 02-08-2006: The optional input argument OutputDirectory was added.
%
% * 03-08-2006: Copies "compute_aim_data.m" to the YADA tmp directory instead of changing the path! Similarly, when
%               computing the posterior mode and when running the random walk Metropolis algorithm, YADA
%               copies "compute_aim_matrices.m" to YADA's tmp directory. If files having the same name already exists
%               in the tmp directory, they are overwritten. When YADA is being shut down, all files in the tmp
%               directory are automatically deleted. With tmp being on the path, this method of dealing with different
%               AiM parser output files has the advantage that the path need never be updated. Such updating can, of
%               course, become complicated as one directory has to be removed and another added... and YADA, YADA, YADA.
%
% * 17-11-2006: Fixed a bug where a number of outputs were not assigned values. The DOSMessage from running the AiM parser
%               is now also given as function output.
%
% * 29-03-2007: Updated the documentation.
%
% * 28-08-2007: Changed a length call to a size call for the param string matrix. (Thanks to Ferdinand for spotting
%               this bug).
%
% * 30-10-2007: The DOSCommand now includes quotes around the "ModelFile" argument to cover cases when the path to
%               this file includes spaces.
%
% * 23-05-2008: Updated the documentation.
%
% * 21-10-2008: Made sure that parameters called "g", "h", and "UserVariables" are not allowed in the AiM code. Also,
%               the local names for the output from the "compute_aim_matrices" function is now g and h instead of
%               cofg and cofh.
%
% * 22-10-2008: Altered the reserved parameter names to "YADAg", "YADAh", and "UserVariables". This means that "g"
%               and "h" may now be used as regular parameter names.
%
% * 29-10-2008: Added file creation information to the file "compute_aim_matrices".
%
% * 05-12-2008:  Made sure that the AiMParserExe string has quotes around it if the string contains space
%               characters.
%
% * 03-03-2009: Added a pause command after copying the "compute_aim_data.m" file to the "tmp" directory. The pause command
%               was also added after the "MakeDir" call. In addition, the function now checks if "compute_aim_data.m"
%               exists in the "OutputDirectory".
%
% * 09-03-2009: Added quotation marks around paths for the dos copy command.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

status = 0;
mcode = 0;
MaxAbsError = NaN;
CurrentDir = pwd;
[ModelPath,ModelName,ModelExt] = fileparts(ModelFile);
if nargin<3;
   OutputDirectory = [ModelPath '\' NameOfModel];
   %
   % check if the subdirectory NameOfModel exists in ModelPath.
   % if not make sure it's created
   %
   DirStatus = MakeDir(ModelPath,NameOfModel);
   pause(0.5);
end;
%
% Parse the model file with AiM
%
AiMParserExe = AiMParser;
if isempty(findstr(AiMParserExe,' '))==0;
   AiMParserExe = ['"' AiMParserExe '"'];
end;
cd(OutputDirectory);
DOSCommand = [AiMParserExe ' "' ModelFile '"'];
[DOSStatus,DOSMessage] = dos(DOSCommand);
cd(CurrentDir);
if DOSStatus~=0;
   status = 1;
   param = '';
   np = [];
   modname = '';
   neq = [];
   nlag = [];
   nlead = [];
   eqname = '';
   eqtype = [];
   endog = '';
   delay = [];
   vtype = [];
   return;
end;
%
% Now we should check if compute_aim_matrices.m exists in the OutputDirectory directory
%
file = [OutputDirectory '\compute_aim_matrices.m'];
if (FileExist(file)==1)&(FileExist([OutputDirectory '\compute_aim_data.m'])==1);
   %
   % copy the compute_aim_data.m file to pwd \tmp
   %
   [FilePath,FileName,FileExt] = fileparts([OutputDirectory '\compute_aim_data.m']);
   if strcmp(lower(FilePath),lower([pwd '\tmp']))==0;
      [stat,msg] = dos(['copy /Y "' OutputDirectory '\compute_aim_data.m" "' pwd '\tmp"']);
      pause(0.5);
   end;
   %
   % call compute_aim_data
   %
   [param,np,modname,neq,nlag,nlead,eqname,eqtype,endog,delay,vtype] = compute_aim_data;
   %
   % we need the information in param_ to fix the compute_aim_matrices script
   %
   %
   % rewrite the file to make it into a function instead of a script
   %
   AiMTxt = ReadText(file);
   fid = fopen(file,'wt');
   fprintf(fid,'function [g,h] = compute_aim_matrices(ModelParameters)\n\n');
   BadAiMFile = 0;
   for i=1:length(AiMTxt);
      %
      % get the cellstr variable
      %
      TxtStr = AiMTxt{i};
      TxtStr = StrSwap(TxtStr,'g = zeros','YADAg = zeros');
      TxtStr = StrSwap(TxtStr,'h = zeros','YADAh = zeros');
      TxtStr = strrep(TxtStr,'g(','YADAg(');
      TxtStr = strrep(TxtStr,'h(','YADAh(');
      TxtStr = strrep(TxtStr,'cofg = g;','');
      TxtStr = strrep(TxtStr,'cofh = h;','');
      %
      if isempty(StringTrim(TxtStr))==0;
         for j=1:size(param,1);
            %
            % search and replace all occurances of param_(j) string with ModelParameters.param_(j) string.
            % We can then send the ModelParameters structure to compute_aim_matrices when this function is
            % called
            %
            p_str = deblank(param(j,:));
            if (strcmp(p_str,'YADAg')==0)&(strcmp(p_str,'YADAh')==0)&(strcmp(p_str,'UserVariables')==0);
               TxtStr = StrSwap(TxtStr,p_str,['ModelParameters.' p_str]);
            else;
               status = 3;
               DOSMessage = 'YADA has located a parameter called "YADAg", "YADAh", or "UserVariables" in your AiM model file. These names are reserved and may not be used as parameter names.';
               BadAiMFile = 1;
               break;
            end;
         end;
         if BadAiMFile==1;
            break;
         end;
         TxtStr = StrSwap(TxtStr,'YADAg = zeros','g = zeros');
         TxtStr = StrSwap(TxtStr,'YADAh = zeros','h = zeros');
         TxtStr = strrep(TxtStr,'YADAg(','g(');
         TxtStr = strrep(TxtStr,'YADAh(','h(');
         TxtStr = strrep(TxtStr,'compute_aim _matrices()','compute_aim_matrices:');
         if strcmp(TxtStr,strrep(TxtStr,'This script will compute the G and H matrices.','This function computes the g and h matrices.'))==1;
            fprintf(fid,'%s \n',StringTrim(TxtStr));
         else;
            fprintf(fid,'%s \n',StringTrim(strrep(TxtStr,'This script will compute the G and H matrices.','This function computes the g and h matrices from the parameter values in the fields of "ModelParameters"..')));
            fprintf(fid,'%%\n%% This file was created by YADA on: %s \n%%\n\n',datestr(now,0));
         end;
      end;
   end;
   if BadAiMFile==0;
      fprintf(fid,'\n%%\n%% end of compute_aim_matrices.m\n%%\n');
      fclose(fid);
   else;
      fclose(fid);
      return;
   end;
   %
   % Some consistency checking
   %
   seq  = find(eqtype==0);
   dvar = find(vtype==0);
   if length(seq)==length(dvar);
      %
      % save model information to disk
      %
      file = [OutputDirectory '\' NameOfModel '.mat'];
      save(file,'param','eqname','eqtype','endog','neq','nlag','nlead','np','modname','delay','vtype');
   else;
      status = 2;
   end
else;
   status = 1;
   param = '';
   np = NaN;
   modname = '';
   neq = NaN;
   nlag = NaN;
   nlead = NaN;
   eqname = '';
   eqtype = NaN;
   endog = '';
   delay = NaN;
   vtype = NaN;
   return;
end;

%
% end of AiMInitialize.m
%
