function xsim = linsimstate(Type,varargin)
%LINSIMSTATE  Builds extended initial condition for linear simulations.
%
%   LINSIMSTATE builds a default initial condition for linear simulations 
%   assuming that all delayed signals have zero value prior to the 
%   simulation start.
%
%   XSIM = LINSIMSTATE('ss',X0,DIN,DOUT,DF) constructs an initial 
%   condition XSIM given
%     * The initial state X0
%     * The vectors DIN, DOUT, and DF of input, output, and 
%       internal delays.
%   You can use XSIM as initial condition for SSSIM.
%
%   XSIM = LINSIMSTATE('zpk',Z,P,IODELAY) constructs an initial  
%   condition XSIM given 
%     * The cell arrays Z and P of poles and zeros for each
%       I/O transfer function
%     * The matrix IODELAY of total I/O delay for each I/O pair.
%   You can use XSIM as initial condition for ZPKSIM.
%
%   Use LTIPACK.TFSIMIC to initialize simulations with TFSIM.
%
%   See also SSSIM, ZPKSIM, TOTALDELAY.

%   Copyright 1986-2011 The MathWorks, Inc.
ni = length(varargin);
switch lower(Type)
   case 'ss'
      if ni<4,
         ctrlMsgUtils.error('Controllib:utility:linsimstate1','ss')
      else
         x0 = varargin{1};
         Din = varargin{2};
         Dout = varargin{3};
         Df = varargin{4};
      end
      xsim = struct(...
         'State',x0,...
         'Input',{LocalMakeBuffers(Din)},...
         'Output',{LocalMakeBuffers(Dout)},...
         'Internal',{LocalMakeBuffers(Df)});
      
   case 'zpk'
      if ni<3,
         ctrlMsgUtils.error('Controllib:utility:linsimstate2','zpk')
      else
         z = varargin{1};
         p = varargin{2};
         Dio = varargin{3};
      end
      [ny,nu] = size(Dio);
      orders = cellfun('length',p(:));
      % Check for improper models
      no = cellfun('length',z(:));
      if any(no>orders)
          ctrlMsgUtils.error('Controllib:analysis:NotSupportedSimulationImproperSys')
      end
      xsim = struct('Input',zeros(max(orders+Dio(:)),nu),...
         'Output',zeros(max(orders),ny*nu));      
end
      
      
function buf = LocalMakeBuffers(DelayVector)
% Construct buffers to store delayed inputs, outputs, or internal variables
nd = length(DelayVector);
buf = cell(nd,1);
for ct=1:nd
   buf{ct} = zeros(DelayVector(ct),1);
end
