function createResponse(this,View,Systems,Styles,varargin)
%CREATERESPONSE  Creates one response per system for a given plot.

%   Authors: Kamesh Subbarao
%   Copyright 1986-2010 The MathWorks, Inc. 

PlotType = View.Tag;
for ct=1:length(Systems)
   src = Systems(ct);
   r = View.addresponse(src);
   switch PlotType
      case {'step','impulse'}
         r.DataFcn = {@LocalTimeDataFcn this src PlotType r};
         Config = RespConfig();
         r.Context = struct('Type',PlotType,'Time',[],'Parameter',[],'Config',Config);
         if strcmpi(PlotType,'step')
             DefinedCharacteristics = src.getCharacteristics('step');
             DefinedCharacteristics(end+1) = struct(...
            'CharacteristicLabel', ctrlMsgUtils.message('Control:compDesignTask:strMultiModelDisplay'), ...
            'CharacteristicID', 'MultipleModelView', ...
            'CharacteristicData', 'resppack.UncertainStepData', ...
            'CharacteristicView', 'resppack.UncertainTimeView', ...
            'CharacteristicGroup', 'MultiModel');
             r.setCharacteristics(DefinedCharacteristics); 

         else
             DefinedCharacteristics = src.getCharacteristics('impulse');
             DefinedCharacteristics(end+1) = struct(...
                 'CharacteristicLabel', ctrlMsgUtils.message('Control:compDesignTask:strMultiModelDisplay'), ...
                 'CharacteristicID', 'MultipleModelView', ...
                 'CharacteristicData', 'resppack.UncertainImpulseData', ...
                 'CharacteristicView', 'resppack.UncertainTimeView', ...
                 'CharacteristicGroup', 'MultiModel');
             r.setCharacteristics(DefinedCharacteristics); 
         end
      case 'initial'
         r.DataFcn = {@LocalTimeDataFcn this src PlotType r};
         % Note: IC resolution deferred to createView
         Config = struct('InitialState',[]);
         r.Context = struct('Type','initial','Time',[],'Parameter',[],'Config',Config);
         DefinedCharacteristics = src.getCharacteristics('initial');
         r.setCharacteristics(DefinedCharacteristics);
      case 'lsim'
         r.DataFcn = {'lsim' src r};
         % Note: Input data and IC resolution deferred to createView
         r.Context = struct('InputIndex',[],'IC',[],'Parameter',[]);
      case {'bode','bodemag'}
         r.DataFcn = {@LocalMagPhaseDataFcn src r 'bode' this};
         DefinedCharacteristics = src.getCharacteristics('bode');
         DefinedCharacteristics(end+1) = struct(...
             'CharacteristicLabel', ctrlMsgUtils.message('Control:compDesignTask:strMultiModelDisplay'), ...
             'CharacteristicID', 'MultipleModelView', ...
             'CharacteristicData', 'resppack.UncertainMagPhaseData', ...
             'CharacteristicView', 'resppack.UncertainBodeView', ...
             'CharacteristicGroup', 'MultiModel');
         r.setCharacteristics(DefinedCharacteristics);
         wchar = r.initializeCharacteristic('MultipleModelView');
         wchar.DataFcn = {@LocalMultiModelMagPhaseDataFcn wchar 'bode' this};
      case 'nichols'
         r.DataFcn = {@LocalMagPhaseDataFcn src r 'nichols' this};
         DefinedCharacteristics = src.getCharacteristics('nichols');
         r.setCharacteristics(DefinedCharacteristics);
      case 'nyquist'
         r.DataFcn = {@LocalFreqDataFcn src r PlotType this};
         DefinedCharacteristics = src.getCharacteristics('nyquist');
%          DefinedCharacteristics(end+1) = struct(...
%              'CharacteristicLabel', ctrlMsgUtils.message('Control:compDesignTask:strMultiModelDisplay'), ...
%              'CharacteristicID', 'MultipleModelView', ...
%              'CharacteristicData', 'resppack.UncertainMagPhaseData', ...
%              'CharacteristicView', 'resppack.UncertainNyquistView', ...
%              'CharacteristicGroup', 'MultiModel');
         r.setCharacteristics(DefinedCharacteristics);
      case 'sigma'
         r.DataFcn = {@LocalFreqDataFcn src r PlotType this};
         DefinedCharacteristics = src.getCharacteristics('sigma');
         r.setCharacteristics(DefinedCharacteristics);
      case 'pzmap'
         r.DataFcn = {@LocalPZMapDataFcn 'pzmap' src r this};
%          DefinedCharacteristics = src.getCharacteristics('pzmap');
         DefinedCharacteristics(1) = struct(...
             'CharacteristicLabel', ctrlMsgUtils.message('Control:compDesignTask:strMultiModelDisplay'), ...
             'CharacteristicID', 'MultipleModelView', ...
             'CharacteristicData', 'resppack.UncertainPZData', ...
             'CharacteristicView', 'resppack.UncertainPZView', ...
             'CharacteristicGroup', 'MultiModel');
         r.setCharacteristics(DefinedCharacteristics);
         wchar = r.initializeCharacteristic('MultipleModelView');
         wchar.DataFcn = {@LocalMultiModelPZDataFcn wchar [] this};
      case 'iopzmap'
         r.DataFcn = {@LocalPZMapDataFcn 'pzmap' src r 'io' this};
         DefinedCharacteristics = src.getCharacteristics('iopzmap');
         r.setCharacteristics(DefinedCharacteristics);
   end
   % Styles and preferences
   initsysresp(r,PlotType,View.Options)
   r.Style = Styles(ct);
end



%%%%%%%%%%%%%%%%%%%%
% LocalTimeDataFcn %
%%%%%%%%%%%%%%%%%%%%
function LocalTimeDataFcn(this,src,PlotType,r)
% Note: This indirection is needed to react to change in time vector, in
% particular for sparse models.
r.Context.Time = this.Preferences.TimeVector*tunitconv(this.Preferences.TimeVectorUnits,src.getTimeUnits);
timeresp(src,PlotType,r)

%%%%%%%%%%%%%%%%%%%%%%%%
% LocalMagPhaseDataFcn %
%%%%%%%%%%%%%%%%%%%%%%%%
function LocalMagPhaseDataFcn(src,r,PlotType,this)
% Data function for Frequency Mag, Phase plots
f = this.Preferences.FrequencyVector;

sw = warning('off','Control:analysis:ScalingIssue');[lw,lwid] = lastwarn;
if iscell(f)
   % Frequency range specified
    fc = [f{:}]*funitconv(this.Preferences.FrequencyVectorUnits,'rad/TimeUnit',src.getTimeUnits);
   magphaseresp(src,PlotType,r,{fc(1) fc(2)})
else
   % f is [] or a vector
   magphaseresp(src,PlotType,r,f*funitconv(this.Preferences.FrequencyVectorUnits,'rad/TimeUnit',src.getTimeUnits));
end
warning(sw); lastwarn(lw,lwid);



%%%%%%%%%%%%%%%%%%%%
% LocalFreqDataFcn %
%%%%%%%%%%%%%%%%%%%%
function LocalFreqDataFcn(src,r,PlotType,this)
% Data function for Frequency Response plots
f = this.Preferences.FrequencyVector;
sw = warning('off','Control:analysis:ScalingIssue');[lw,lwid] = lastwarn;
if iscell(f)
   % Frequency range specified
   fc = [f{:}]*funitconv(this.Preferences.FrequencyVectorUnits,'rad/TimeUnit',src.getTimeUnits);
   feval(PlotType,src,r,{fc(1) fc(2)});
else
   % f is [] or a vector
   feval(PlotType,src,r,f*funitconv(this.Preferences.FrequencyVectorUnits,'rad/TimeUnit',src.getTimeUnits));
end
warning(sw); lastwarn(lw,lwid);


%%%%%%%%%%%%%%%%%%%%
% LocalPZMapDataFcn %
%%%%%%%%%%%%%%%%%%%%
function LocalPZMapDataFcn(PlotType,Src,r,this)
PadeOrder = this.Parent.Preferences.PadeOrder;
sw = warning('off','Control:transformation:StateSpaceScaling');[lw,lwid] = lastwarn;
feval(PlotType,Src,r,[],PadeOrder);
warning(sw); lastwarn(lw,lwid);

function LocalIOPZMapDataFcn(PlotType,Src,r,ioflag,this)
PadeOrder = this.Parent.Preferences.PadeOrder;
sw = warning('off','Control:transformation:StateSpaceScaling');[lw,lwid] = lastwarn;
feval(PlotType,Src,r,ioflag,PadeOrder);
warning(sw); lastwarn(lw,lwid);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LocalMultiModelMagPhaseDataFcn %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LocalMultiModelMagPhaseDataFcn(wchar,PlotType,this)
sw = warning('off','Control:analysis:ScalingIssue');[lw,lwid] = lastwarn;
wf = wchar.Parent; % parent waveform
for ct=1:length(wchar.Data)
   % Propagate exceptions
   wchar.Data(ct).Exception = wf.Data(ct).Exception;
   if ~wchar.Data(ct).Exception
      getUncertainMagPhaseData(wf.DataSrc,PlotType,wf,wchar.Data,this.Parent.Preferences.getMultiModelFrequency);
   end
end
warning(sw); lastwarn(lw,lwid);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LocalMultiModelPZDataFcn       %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LocalMultiModelPZDataFcn(wchar,ioflag,this)

PadeOrder = this.Parent.Preferences.PadeOrder;
wf = wchar.Parent; % parent waveform
for ct=1:length(wchar.Data)
   % Propagate exceptions
   wchar.Data(ct).Exception = wf.Data(ct).Exception;
   if ~wchar.Data(ct).Exception
      getUncertainPZData(wf.DataSrc,wf,wchar.Data,ioflag,PadeOrder);
   end
end

