function [FORMAT,RANGE,Y,E,I] = datarequest(THIS,DATA,RANGE,OPT)
% datarequest  [Not a public function] Request input data.
%
% Backend IRIS function.
% No help provided.

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

ise = nargout > 3;
isi = nargout > 4;

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

ny = specget(THIS,'ny');
if isi
    ni = length(THIS.inames);
end

if any(isinf(RANGE))
    RANGE = Inf;
    infrange = true;
else
    if ~isempty(RANGE)
        RANGE = RANGE(1) : RANGE(end);
    end
    infrange = false;
end

if isstruct(DATA)
    [Y,E,I] = dostruct();
    inputformat = 'dbase';
elseif istseries(DATA)
    [Y,E] = dotseries();
    I = [];
    inputformat = 'tseries';
elseif ~isempty(DATA)
    [Y,E] = doarray();
    I = [];
    inputformat = 'array';
else
    [Y,E] = doelse();
    I = [];
    inputformat = 'tseries';
end

% Transpose data.
Y = permute(Y,[2,1,3]);
if ise
    E = permute(E,[2,1,3]);
end
if isi
    nper = length(RANGE);
    if isempty(I)
        I = nan(nper,ni,size(Y,3));
    else
        I = permute(I,[2,1,3]);
    end
end

% Determine output format.
if ~exist('OPT','var') || ~isfield(OPT,'output') ...
        || strcmpi(OPT.output,'auto')
    FORMAT = inputformat;
else
    FORMAT = OPT.output;
end

% Nested functions.

%**************************************************************************
    function [y,e,fi] = dostruct()
        ynames = THIS.ynames;
        if infrange
            RANGE = dbrange(DATA,ynames);
        end
        nper = length(RANGE);
        y = [];
        for i = 1 : ny
            name = THIS.ynames{i};
            if isfield(DATA,name) && istseries(DATA.(name))
                yi = rangedata(DATA.(name),RANGE);
                yi = permute(yi,[1,3,2]);
            else
                yi = nan(nper,1,size(y,3));
            end
            y = [y,yi]; %#ok<AGROW>
        end
        % Residuals.
        e = [];
        if ise
            for i = 1 : ny
                name = THIS.enames{i};
                if isfield(DATA,name) ...
                        && isa(DATA.(name),'tseries')
                    ei = rangedata(DATA.(name),RANGE);
                    ei = permute(ei,[1,3,2]);
                else
                    ei = zeros(nper,1,size(e,3));
                end
                e = [e,ei]; %#ok<AGROW>
            end
        end
        % Forecast instruments.
        fi = [];
        if isi
            inames = THIS.inames;
            ni = length(THIS.inames);
            for i = 1 : ni
                name = inames{i};
                if isfield(DATA,name) ...
                        && isa(DATA.(name),'tseries')
                    fii = rangedata(DATA.(name),RANGE);
                    fii = permute(fii,[1,3,2]);
                else
                    fii = nan(nper,1,size(fi,3));
                end
                fi = [fi,fii]; %#ok<AGROW>
            end
        end
    end
% dostruct().

%**************************************************************************
    function [y,e] = dotseries()
        [y,RANGE] = rangedata(DATA,RANGE);
        if size(y,2) == 2*ny
            e = y(:,ny+1:end,:);
            y = y(:,1:ny,:);
        else
            e = zeros(size(y));
        end
    end
% dotseries().

%**************************************************************************
    function [y,e] = doarray()
        if infrange
            RANGE = 1 : size(DATA,1);
        end
        nper = length(RANGE);
        index = RANGE >= 1 & RANGE <= size(DATA,1);
        y = nan([nper,size(DATA,2),size(DATA,3)]);
        y(index,:,:) = DATA(RANGE(index),:,:);
        if size(y,2) == 2*ny
            e = y(:,ny+1:end,:);
            y = y(:,1:ny,:);
        else
            e = zeros(size(y));
        end
    end
% doarray().

%**************************************************************************
    function [y,e] = doelse()
        if infrange
            nper = 0;
        else
            nper = length(RANGE);
        end
        y = nan(nper,ny);
        e = nan(nper,ny);
        % inputformat = 'array';
    end
% doelse().

end