function detail(this,varargin)
% detail  Display details of a simulation plan.
%
% Syntax
% =======
%
%     detail(P)
%     detail(P,D)
%
% Input arguments
% ================
%
% * `P` [ plan ] - Simulation plan.
%
% * `D` [ struct ] - Input database.
%
% Description
% ============
%
% If you supply also the second input argument, an input database, both
% dates and values will be reported for exogenised and conditioning data
% points, and the values will be checked for the presence of NaNs (with a
% warning displayed should there be found any).
%
% Example
% ========
%

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

if ~isempty(varargin)
    d = varargin{1};
    varargin(1) = []; %#ok<NASGU>
else
    d = [];
end

if isfield(d,'mean') && isstruct(d.mean)
    d = d.mean;
end
    
%**************************************************************************

nx = nnzexog(this);
[ans,nnreal,nnimag] = nnzendog(this); %#ok<NOANS,ASGLU>
nq = nnznonlin(this);

disp(' ');
range = this.startdate:this.enddate;
dates = dat2str(range);

printdates = @(index) sprintf(' %s',dates{index});

[xdetail,xnan] = xxdetail(this.xanchors,this.xlist,range,d);
nrealdetail = xxdetail(this.nanchorsreal,this.nlist,range);
nimagdetail = xxdetail(this.nanchorsimag,this.nlist,range);
[cdetail,cnan] = xxdetail(this.canchors,this.clist,range,d);

qlist = {};
for i = find(any(this.qanchors,2)).'
    temp = printdates(this.qanchors(i,:));
    qlist = [qlist,{strfun.ellipsis(this.qlist{i},20),temp}];
end

checklist = [ ...
    xdetail(1:2:end), ...
    nrealdetail(1:2:end), ...
    nimagdetail(1:2:end), ...
    cdetail(1:2:end)];
maxlen = max(cellfun(@length,checklist));
format = ['\t%-',sprintf('%g',maxlen+1),'s%s\n'];
empty = @() fprintf('\t-\n');

fprintf('Exogenised %g\n',nx);
if ~isempty(xdetail)
    fprintf(format,xdetail{:});
else
    empty();
end

fprintf('Endogenised real %g\n',nnreal);
if ~isempty(nrealdetail)
    fprintf(format,nrealdetail{:});
else
    empty();
end

fprintf('Endogenised imag %g\n',nnimag);
if ~isempty(nimagdetail)
    fprintf(format,nimagdetail{:});
else
    empty();
end

fprintf('Conditioned upon %g\n',nx);
if ~isempty(cdetail)
    fprintf(format,cdetail{:});
else
    empty();
end

fprintf('Non-linearised %g\n',nq);
if ~isempty(qlist)
    fprintf(format,qlist{:});
else
    empty();
end

disp(' ');

if xnan > 0
    utils.warning('plan', ...
        ['A total of %g exogenised data points refer(s) to NaN(s) ', ...
        'in the input database.'], ...
        xnan);
end

if cnan > 0
    utils.warning('plan', ...
        ['A total of %g conditioning data points refer(s) to NaN(s) ', ...
        'in the input database.'], ...
        cnan);
end

end

% Subfunctions.

%**************************************************************************
function [det,nnan] = xxdetail(anchors,list,range,d)

isdata = exist('d','var') && isstruct(d);
dates = dat2str(range);
det = {};
nnan = 0;
for i = find(any(anchors,2)).'
    index = anchors(i,:);
    name = list{i};
    if isdata
        if isfield(d,name) && isa(d.(name),'tseries')
            [~,ndata] = size(d.(name).data);
            values = nan(ndata,size(anchors,2));
            for j = 1 : ndata
                values(j,index) = d.(name)(range(index),j).';
                nnan = nnan + sum(isnan(values(j,index)));
            end
        else
            ndata = 1;
            values = nan(ndata,size(anchors,2));
        end            
        row = '';
        for j = find(index)
            row = [row,' ',dates{j},'=[',num2str(values(:,j).',' %g'),']'];
        end
    else
        row = sprintf(' *%s',dates{index});
    end
    det = [det,list(i),{row}]; %#ok<*AGROW>
end

end