function [EData,ErrorStr,Status] = CalcMoreExportVariables(ExportStructure,ExportData,VariableNames)
% CalcMoreExportVariables: computes additional variables for exporting based on the export data set
%                          and exogenous variables stored the ExportStructure.
%
% USAGE:
%
%       [EData,ErrorStr,Status] = CalcMoreExportVariables(ExportStructure,ExportData,VariableNames)
%
% REQUIRED INPUT:  ExportStructure (structure) with fields "names", "titles", and the actual names
%                                  of the variables to be created and that are stored as strings in
%                                  the cell array field names. Each of the variables has 5 sub-fields:
%                                  fcn (string) with the function to apply, x (matrix) with data on
%                                  any exogenous variables, y (cell array) of string with the names
%                                  in the VariableNames string matrix to use in ExportData for the
%                                  "endogenous" variables, subsample (vector) with start and end point
%                                  of the data to use, and priordata (vector) with data on the
%                                  constructed data to prepend to the used part of the constructed
%                                  variable.
%
%                  ExportData (matrix) of dimension Txk with T observations on the k variables to
%                                  export.
%
%                  VariableNames (string matrix) of dimension kxk1 with the names of the variables
%                                  in the ExportData matrix.
%
% REQUIRED OUTPUT: EData (matrix) of dimension Txs where s is the number of variables that were
%                                  created.
%
%                  ErrorStr (string vector) with an error message if anything went wrong.
%
%                  Status (boolean) that is 1 if all variables were created successfully and 0
%                                  otherwise.
%
%
%                       Written by: Anders Warne
%                                   New Area Wide Model Project
%                                   DG-R/EMO
%                                   European Central Bank (ECB)
%                                   Email: anders.warne@ecb.europa.eu
%                                   Copyright © 2006-2008 European central Bank.
%
%                       First version: August 20, 2008.
%                        This version: December 18, 2008.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 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:
%
% * 28-8-2008:  Fixed a bug where the index i was multiply used.
%
% * 15-10-2008: Added a check for the size of the ExportData and the subsample max period such
%               that NaN entries are removed from the x-matrix if all entries after the length
%               of ExportData in the x-matrix are NaN's.
%
% * 18-12-2008: Updated the documentation.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

%
% initialize
%
EData = [];
ErrorStr = '';
Status = 0;
for i=1:length(ExportStructure.names);
   CurrVariable = StringTrim(ExportStructure.names{i});
   CurrField = getfield(ExportStructure,CurrVariable);
   CurrField.subsample = sort(CurrField.subsample);
   if (CurrField.subsample(2)>size(ExportData,1))&(CurrField.subsample(2)<=length(CurrField.x));
      X = CurrField.x;
      if size(X,1)<size(X,2);
         X = X';
      end;
      %
      % check if XPart is a matrix with NaN's only
      %
      if min(min(isnan(X(size(ExportData,1)+1:size(X,1),:))))==1;
         if size(X,1)==size(CurrField.x,1);
            CurrField.x = CurrField.x(1:size(ExportData,1),:);
         elseif size(X,1)==size(CurrField.x,2);
            CurrField.x = CurrField.x(:,1:size(ExportData,1));
         end;
      end;
      CurrField.subsample(2) = size(ExportData,1);
   end;
   if (CurrField.subsample(2)>size(ExportData,1))|(CurrField.subsample(1)<1);
      ErrorStr = ['YADA is unable to use the subsample for "' CurrVariable '". The positions don''t match the possible positions in the export data set.'];
      break;
   end;
   Y = [];
   X = CurrField.x;
   GoodYVar = 1;
   if isempty(CurrField.y)==0;
      for j=1:length(CurrField.y);
         VarPos = loc(VariableNames,StringTrim(CurrField.y{j}));
         if isempty(VarPos)==1;
            ErrorStr = ['Unable to locate the variable "' StringTrim(CurrField.y{j}) '" among the export data. This variable is needed by the export function for "' CurrVariable '".'];
            GoodYVar = 0;
            break;
         else;
            Y = [Y ExportData(:,VarPos)];
         end;
      end;
      if GoodYVar==0;
         break;
      end;
   end;
   %
   if (isempty(X)==0)&(isempty(Y)==0);
      if size(X,1)~=size(Y,1);
         if size(X,2)==size(Y,1);
            X = X';
         else;
            ErrorStr = ['The number of observations for the export data (' int2str(size(Y,1)) ') and the exogenous data (' int2str(size(X,1)) ') don''t match for "' CurrVariable '".'];
            break;
         end;
      end;
   end;
   %
   % create the inline function
   %
   try;
      YADAfcn = YADAInline(CurrField.fcn);
   catch;
      ErrorStr = ['The was an error creating the inline function for ' CurrVariable '. The following message was caught: ' lasterr];
      break;
   end;
   %
   % create the vector of variables
   %
   InputVars = YADASymvar(CurrField.fcn);
   %
   % check if we should locate positions of the y and x variables
   %
   Ypositions = [];
   if isempty(CurrField.y)==0;
      for i1=1:length(InputVars);
         for j=1:length(CurrField.y);
            if strcmp(InputVars{i1},CurrField.y{j})==1;
               Ypositions = [Ypositions i1];
            end;
         end;
      end;
   end;
   Xpositions = [];
   if isempty(X)==0;
      Xpositions = setdiff((1:length(InputVars)),Ypositions);
   end;
   %
   % create the input data that has the same ordering as
   % the InputVars that YADAfcn requires
   %
   if isempty([X Y])==0;
      InputData = zeros(size([X Y]));
      if isempty(Xpositions)==0;
         InputData(:,Xpositions) = X;
      end;
      if isempty(Ypositions)==0;
         InputData(:,Ypositions) = Y;
      end;
   else;
      InputData = [];
   end;
   %
   % set up the command line
   %
   RunArg = '';
   for i1=1:size(InputData,2);
      eval(['x' int2str(i1) ' = InputData(:,' int2str(i1) ');']);
      if i1>1;
         RunArg = [RunArg ',x' int2str(i1)];
      else;
         RunArg = 'x1';
      end;
   end;
   %
   % try to execute the function
   %
   try;
      eval(['y = YADAfcn(' RunArg ');']);
   catch;
      ErrorStr = ['YADA caught the following error message while applying the export function for the variable "' CurrVariable '": ' lasterr];
      break;
   end;
   %
   % take the subsample into account
   %
   y = y(CurrField.subsample(1):CurrField.subsample(2));
   %
   % check if we have priordata
   %
   if isempty(CurrField.priordata)==0;
      CurrField.priordata = vec(CurrField.priordata);
   end;
   y = [CurrField.priordata;y];
   %
   if size(ExportData,1)==size(y,1);
      EData = [EData y];
   else;
      ErrorStr = ['The data created by the export function for the variable "' CurrVariable '" doesn''t have the same number of observations as the export data set. The created variable has ' int2str(size(y,1)) ' observations instead of ' int2str(size(ExportData,1)) '.'];
      break;
   end;
end;
if length(ExportStructure.names)==size(EData,2);
   Status = 1;
end;

%
% end of CalcMoreExportVariables.m
%
