function [a,x,range,maxlag,s] = db2dp(this,d,range,varargin)
% dp2db  Convert database to rhsmodel datapack.
%
% Backend IRIS function.
% No help provided.

%**************************************************************************

maxlag = size(this.occur,3) - 1;
available = false(1,length(this.name));
for i = find(this.nametype <= 3)
    available(i) = ...
        isfield(d,this.name{i}) && isa(d.(this.name{i}),'tseries');
end

% The variale `startdate` is the first date at which a simulation or
% filter can start. All prior observations back to |startdate - maxlag|
% are included in the output datapacks.
if isinf(range(1))
    startdate = doautostartdate();
else
    startdate = range(1);
end
if isinf(range(end))
    enddate = doautoenddate();
else
    enddate = range(end);
end

if isinf(startdate) || isnan(startdate)
    utils.error('bkwmodel', ...
        'Cannot determine the start-date of the range.');
end
if isinf(enddate) || isnan(enddate)
    utils.error('bkwmodel', ...
        'Cannot determine the end-date of the range.');
end

range = startdate : enddate;
nper = length(range);
nalt = size(this.Assign,3);
nx = sum(this.nametype == 1);
nz = sum(this.nametype == 2);
ne = sum(this.nametype == 3);
np = sum(this.nametype == 4);
na = length(this.systemid);

x = nan(nx+nz+np,nper,1);
s = zeros(nx,nper,1); 
for i = find(this.nametype <= 3)
    if available(i)
        temp = rangedata(d.(this.name{i}),range);
    else
        temp = nan([nper,nalt]);
    end
    ndata = size(x,3);
    ntemp = size(temp,2);
    if ntemp < nalt
        temp(:,end+1:nalt) = temp(:,end*ones(1,nalt-end));
    else
        if ntemp < ndata
            temp(:,end+1:ndata) = NaN;
            ntemp = ndata;
        end
        if ndata < ntemp
            x(:,:,end+1:ntemp) = NaN;
            s(:,:,end+1:ntemp) = 0;
        end
        if this.nametype(i) == 3
            temp(isnan(temp)) = 0;
        end
    end
    x(i,:,:) = permute(real(temp),[3,1,2]);
    if i <= nx 
        s(i,:,:) = permute(imag(temp),[3,1,2]);
    end
end

% Create the alpha vector, take logs of log-variables.
a = nan(na,nper,size(x,3));
for ia = 1 : na
    realid = real(this.systemid(ia));
    imagid = imag(this.systemid(ia));
    a(ia,1-imagid:end,:) = x(realid,1:end+imagid,:);
    if this.systemlog(ia)
        a(ia,:,:) = log(a(ia,:,:));
    end
end

% Add parameter values.
ndata = size(x,3);
for ip = find(this.nametype == 4)
    temp = this.Assign(1,ip,:);
    temp = temp(1,ones(1,nper),:);
    ntemp = size(temp,3);
    if ntemp < ndata
        temp(:,:,end+1:ndata) = temp(:,:,end*ones(1,ndata-end));
    end
    x(ip,:,:) = temp;
end

% Nested functions.

%**************************************************************************
    function startdate = doautostartdate()
        startdate = [];
        for ii = find(this.nametype <= 2)
            if available(ii)
                thismaxlag = find(any(this.occur(:,ii,:),1),1,'last') - 1;
                if ~isempty(thismaxlag)
                    startdate(end+1) = ...
                        get(d.(this.name{ii}),'start') + thismaxlag; %#ok<AGROW>
                end
            end
        end
        startdate = max(startdate);
    end
% doautostartdate().

%**************************************************************************
    function enddate = doautoenddate()
        enddate = Inf;
        for ii = find(this.nametype <= 2)
            if available(ii)
                enddate = min([enddate,get(d.(this.name{ii}),'end')]);
            end
        end
    end
% doautoenddate().

end