function NicRespObj = nicplot(RespObj,Systems,X,Y,PlotStyle);
%NICPLOT Create a Nichols Chart Response Object for the Control System Toolbox

%   Authors: Karen Gondoly, 2-18-96
%   Revised: Adam DiVergilio, 11-99
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.30 $  $Date: 2000/06/19 21:02:56 $

ni = nargin;

%---Properties
NicRespObj = struct(...
   'Frequency',[],...
   'FrequencyUnits','',...
   'MagnitudeUnits','',...
   'PhaseUnits','',...
   'PeakResponse','off',...
   'PeakResponseValue',[],...
   'StabilityMargin','off',...
   'StabilityMarginValue',[],...
   'AllStabilityMargin','off',...
   'AllStabilityMarginValue',[],...
   'GridLines',[],...
   'UnwrapPhase','');

%---Return cases (ni==0,1)
switch ni
case 0
   RespObj = response;
   NicRespObj = class(NicRespObj,'nicplot',RespObj);
   return
case 1
   if ~isa(RespObj,'response')
      error('Invalid Response Object passed to NICPLOT')
   elseif isa(RespObj,'nicplot')
      NicRespObj = RespObj;
   else
      NicRespObj = class(NicRespObj,'nicplot',RespObj);
   end
   return
end

%---Initialize NicRespObj
NicFlag = isa(RespObj,'nicplot');
if NicFlag
   NicRespObj = RespObj;
   RespObj = NicRespObj.response;
else
   Preferences = get(RespObj,'Preferences');
   NicRespObj.FrequencyUnits = Preferences.FrequencyUnits;
   NicRespObj.MagnitudeUnits = Preferences.MagnitudeUnits;
   NicRespObj.PhaseUnits = Preferences.PhaseUnits;
   NicRespObj.UnwrapPhase = Preferences.UnwrapPhase;
   set(get(RespObj,'PlotAxes'),'XScale','linear','YScale',Preferences.MagnitudeScale);
end

%---Access needed parent property values
PV = get(RespObj,{'PlotAxes','UIContextMenu','SystemNames'});
[LTIdisplayAxes,ContextMenu,SystemNames] = deal(PV{:});
if NicFlag
   RH0 = get(RespObj,'ResponseHandles');
else
   RH0 = {};
end

%---Get dimension info and names of new systems
[numout,numin] = size(LTIdisplayAxes);
NumOldSys = length(RH0);                      % number of existing systems
NewSystemNames = SystemNames(NumOldSys+1:end);
NumNewSys = length(NewSystemNames);           % number of added systems

%---Assign empty system names. This is how the code knows it needs to
%----Calculate the Plot Options for this particular system
PeakRespVals = struct('System',cell(NumNewSys,1),...
   'Frequency',[],'Peak',[],'PhaseAtPeak',[]);
MarginVals = struct('System',cell(NumNewSys,1),...
   'Stable',[],'GainMargin',[],'GMFrequency',[],'PhaseMargin',[],'PMFrequency',[]);
AllMarginVals = struct('System',cell(NumNewSys,1),...
   'Ts',cell(NumNewSys,1),'Margins',cell(NumNewSys,1));

%---Initialize ResponseHandles array
ResponseHandles = cell(NumNewSys,1);
MagData = Y{1};
PhData = Y{2};

for ctR=1:length(ResponseHandles)  % each system
   % Get plot data
   AllMagdata = MagData{ctR};
   AllPhdata = PhData{ctR};
   SizeArray = size(AllMagdata);
   NumArray = prod(SizeArray);

   % Get the style and legend
   Style = struct2cell(PlotStyle(ctR));
   [CC,LL,MM,LegendStr] = deal(Style{:});
   if NumArray>1
      ArrayDimsStr = sprintf('%dx',SizeArray);
      LegendStr = sprintf('%s array: %s',ArrayDimsStr(1:end-1),LegendStr);
   end

   %---Add legend to system name for new systems
   set(ContextMenu.Systems.Names(NumOldSys+ctR),...
      'Label',sprintf('%s (%s)',NewSystemNames{ctR},LegendStr),...
      'ForegroundColor',CC)

   LineHandle = cell(numout,numin);
   for ctin=1:numin
      for ctout=1:numout
         RH = cell(SizeArray);
         for ctArray=1:NumArray
            X{ctR}{ctArray} = unitconv(X{ctR}{ctArray},'rad/sec',NicRespObj.FrequencyUnits);
            Magdata = unitconv(AllMagdata{ctArray},'abs',NicRespObj.MagnitudeUnits);
            %---Wrap phase data if necessary, and convert to correct units
            Phdata = unitconv(AllPhdata{ctArray},'deg','rad');
            if strcmpi(NicRespObj.UnwrapPhase,'off')
               Phdata = mod(Phdata+pi,2*pi)-pi;
            end
            Phdata = unitconv(Phdata,'rad',NicRespObj.PhaseUnits);

            %---Response line UserData
            LineUd = struct('System',NewSystemNames{ctR},'Input',ctin,...
               'Output',ctout,'Array',rguihelper('ind2sub',SizeArray,ctArray));

            RH{ctArray}(1,1)=line(squeeze(Phdata(ctout,ctin,:)),squeeze(Magdata(ctout,ctin,:)),...
               'Color',CC,'DeleteFcn','delresp(gcbo)',...
               'ButtonDownFcn','rguifcn(''showbox'',gcbf);',...
               'Tag','LTIresponseLines','Marker',MM,'LineStyle',LL,...
               'Parent',LTIdisplayAxes(ctout,ctin),...
               'Visible','off','UserData',LineUd);
         end
         LineHandle{ctout,ctin} = RH;
      end
   end
   ResponseHandles{ctR} = LineHandle;
end

%---Set the BackgroundAxes labels
BackAxLabels = {...
      'Title','Nichols Chart',...
      'Ylabel',sprintf('Open-Loop Gain (%s)',NicRespObj.MagnitudeUnits),...
      'Xlabel',sprintf('Open-Loop Phase (%s)',NicRespObj.PhaseUnits)};

if NicFlag  % Append Data
   RespObj = pvset(RespObj,'UIContextMenu',ContextMenu,...
      'ResponseHandles',[RH0;ResponseHandles],...
      BackAxLabels{:});
   NicRespObj.Frequency = [NicRespObj.Frequency , X];
   NicRespObj.PeakResponseValue = [NicRespObj.PeakResponseValue;PeakRespVals];
   NicRespObj.StabilityMarginValue = [NicRespObj.StabilityMarginValue;MarginVals];
   NicRespObj.AllStabilityMarginValue = [NicRespObj.AllStabilityMarginValue;AllMarginVals];
   NicRespObj.response = RespObj;

else
   % Add extra zoom option
   ContextMenu.ZoomMenu.ZoomTight = uimenu(ContextMenu.ZoomMenu.Main,...
      'label','Tight','ForegroundColor',CC,'Separator','on',...
      'Callback',['menufcn(''zoomcallback'')']);

   %---Add Characteristics menu
   ContextMenu.PlotOptions.PeakResponse = uimenu(ContextMenu.PlotOptions.Main,...
        'label',xlate('Peak Response'),...
      'Callback',['menufcn(''togglepeak'')']);

   RespObj = pvset(RespObj,'ResponseHandles',ResponseHandles,...
      'UIContextMenu',ContextMenu,BackAxLabels{:});
   NicRespObj.Frequency = X;
   NicRespObj.PeakResponseValue = PeakRespVals;
   NicRespObj.StabilityMarginValue = MarginVals;
   NicRespObj.AllStabilityMarginValue = AllMarginVals;
   NicRespObj = class(NicRespObj,'nicplot',RespObj);
end

%---Update HG pointer to Response Object
builtin('set',ContextMenu.Main,'userdata',NicRespObj)
