function plot_irfs(M_,irfs,options_,var_list)
% plot_irfs(M_,irfs,options_,var_list)
%
% INPUTS
% - M_                      [structure]     MATLAB's structure describing the model
% - irfs                    [structure]     IRF results
% - options_                [structure]     MATLAB's structure describing the current options
% - var_list                [character array]  list of endogenous variables specified
%
% OUTPUTS
%   none
%
% SPECIAL REQUIREMENTS
%   none.

% Copyright © 2022-2025 Dynare Team
%
% This file is part of Dynare.
%
% Dynare 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.
%
% Dynare 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 Dynare.  If not, see <https://www.gnu.org/licenses/>.

if (isfield(options_,'irf_shocks')==0)
    shock_names  = M_.exo_names;
else
    shock_names  = options_.irf_shocks;
end

simul_name = options_.occbin.plot_irf.simulname;
if isempty(simul_name)
    save_name = simul_name;
else
    save_name = [ simul_name '_' ];
end

if isempty(var_list)
    var_list = M_.endo_names(1:M_.orig_endo_nbr);
end

[i_var, ~, index_uniques] = varlist_indices(var_list, M_.endo_names);
vars_irf=var_list(index_uniques);

endo_scaling_factor = options_.occbin.plot_irf.endo_scaling_factor;
length_irf = options_.irf;

steps_irf = 1;

DirectoryName = CheckPath('graphs',M_.dname);
latexFolder = CheckPath('latex',M_.dname);
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
    fidTeX = fopen([latexFolder '/' M_.fname '_occbin_irfs.tex'],'w');
    fprintf(fidTeX,'%% TeX eps-loader file generated by occbin.plot_irfs.m (Dynare).\n');
    fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
    fprintf(fidTeX,' \n');
end

iexo=[];
for var_iter=1:size(shock_names,1)
    itemp = strmatch(shock_names{var_iter},M_.exo_names,'exact');
    if isempty(itemp)
        error(['Shock ',shock_names{var_iter},' is not defined!'])
    else
        iexo=[iexo, itemp];
    end
end

ncols     = options_.occbin.plot_irf.ncols;
nrows     = options_.occbin.plot_irf.nrows;
npan      = ncols*nrows;

shocksigns = options_.occbin.plot_irf.shocksigns;
threshold = options_.impulse_responses.plot_threshold;

for shock_sign_iter = 1:numel(shocksigns)
    shocksign = shocksigns{shock_sign_iter};
    if strcmp(shocksign,'pos')
        plot_title_sign='positive';
    elseif strcmp(shocksign,'neg')
        plot_title_sign='negative';
    else
       error('Unknown shock sign %s',shocksign);
    end

    for shock_iter=1:size(shock_names,1)
        j1   = 0;
        isub = 0;
        ifig = 0;
        % Variables
        for var_iter = 1:length(vars_irf)
            j1=j1+1;
            if mod(j1,npan)==1
                % vector corresponds to [left bottom width height]. 680 and 678 for the left and bottom elements correspond to the default values used by MATLAB while creating a figure and width, .
                screensize = get( groot, 'Screensize' );
                hfig = dyn_figure(options_.nodisplay,'name',['OccBin IRFs to ' plot_title_sign ' ' shock_names{shock_iter} ' shock ' simul_name],'OuterPosition' ,[50 50 min(1000,screensize(3)-50) min(750,screensize(4)-50)]);
                ifig=ifig+1;
                isub=0;
            end
            isub=isub+1;
            if isempty(endo_scaling_factor)
                exofactor = 1;
            else
                exofactor = endo_scaling_factor{var_iter};
            end

            subplot(nrows,ncols,isub)
            irf_field   = strcat(vars_irf{var_iter},'_',shock_names{shock_iter},'_',shocksign);

            %%linear IRFs
            if ~isfield(irfs.linear,irf_field)
                warning('occbin.plot_irfs: no linear IRF for %s to %s detected',vars_irf{var_iter,1},shock_names{shock_iter})
            else
                irfvalues   = irfs.linear.(irf_field);
                irfvalues(abs(irfvalues) <threshold) = 0;
                if options_.occbin.plot_irf.add_steadystate
                    irfvalues = irfvalues + get_mean(vars_irf{var_iter,1});
                end
                max_irf_length_1=min(length_irf,length(irfvalues));
                plot(irfvalues(1:steps_irf:max_irf_length_1)*exofactor,'linewidth',2);
            end
            hold on

            if ~isfield(irfs.piecewise,irf_field)
                warning('occbin.plot_irfs: no piecewise linear IRF for %s to %s detected',vars_irf{var_iter,1},shock_names{shock_iter})
            else
                irfvalues   = irfs.piecewise.(irf_field);
                irfvalues(abs(irfvalues) <threshold) = 0;
                if options_.occbin.plot_irf.add_steadystate
                    irfvalues = irfvalues + get_mean(vars_irf{var_iter,1});
                end
                max_irf_length_2=min(length_irf,length(irfvalues));
                plot(irfvalues(1:steps_irf:max_irf_length_2)*exofactor,'r--','linewidth',2);
            end

            plot(irfvalues(1:steps_irf:max(max_irf_length_1,max_irf_length_2))*0,'k-','linewidth',1.5);

            if options_.occbin.plot_irf.grid
                grid on
            end
            xlim([1 max(max_irf_length_1,max_irf_length_2)]);
            if options_.TeX
                title(['$' M_.endo_names_tex{i_var(var_iter)}, '$'],'Interpreter','latex')
            else
                title(M_.endo_names{i_var(var_iter)},'Interpreter','none')
            end
            % Annotation Box + save figure
            % ----------------------
            if mod(j1,npan)==0 || (mod(j1,npan)~=0 && var_iter==length(vars_irf))
                annotation('textbox', [0.1,0,0.35,0.05],'String', 'Linear','Color','Blue','horizontalalignment','center','interpreter','none');
                annotation('textbox', [0.55,0,0.35,0.05],'String', 'Piecewise','Color','Red','horizontalalignment','center','interpreter','none');
                dyn_saveas(hfig,[DirectoryName,filesep,M_.fname,'_irf_occbin_',save_name,shock_names{shock_iter},'_',shocksign,'_',int2str(ifig)],options_.nodisplay,options_.graph_format);
                if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
                    fprintf(fidTeX,'\\begin{figure}[H]\n');
                    fprintf(fidTeX,'\\centering \n');
                    fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s_irf_occbin_%s}\n',options_.figures.textwidth*min((j1-1)/ncols,1),...
                        [DirectoryName '/' ,M_.fname],[save_name,shock_names{shock_iter},'_',shocksign,'_',int2str(ifig)]);
                    fprintf(fidTeX,'\\caption{OccBin IRFs to  %s shock to %s}\n',plot_title_sign,shock_names{shock_iter});
                    fprintf(fidTeX,'\\label{Fig:occbin_irfs:%s}\n',[save_name,shock_names{shock_iter},'_',shocksign,'_',int2str(ifig)]);
                    fprintf(fidTeX,'\\end{figure}\n');
                    fprintf(fidTeX,'\n');
                end
            end
        end
    end
end

if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
    fprintf(fidTeX,'%% End Of TeX file.');
    fclose(fidTeX);
end