function fxptdlg(action, arg2)
%FXPTDLG Graphical interface for Fixed-Point Blockset simulation log.
%
%   FXPTDLG('MODEL') opens the Fixed-Point Blockset graphical user
%   interface (GUI) which provides access to the simulation log displayed
%   by SHOWFIXPTSIMRANGES.  This GUI is an alternative to using that script.
%
%   'MODEL' is the name of the Fixed-Point block model the GUI will
%   use. The same GUI will be used for different Fixed-Point models. The MODEL's
%   Name, Data Type and Max/Min Values are displayed.  If the data type is
%   Fixed-Point, then the MantBits is also displayed providing the sign bit
%   value.
%
%   GUI Options:
%      LOGGING MODE      - The GUI allows you to select from the following logging
%                          modes:
%                               'UseLocalSettings'
%                               'MinMaxAndOverflow'
%                               'OverflowOnly'
%                               'ForceOff'
%      DATATYPE OVERRIDE - The current system's datatype override can be any of
%                          the following:
%                                'UseLocalSettings'
%                                'ScaledDoubles'
%                                'TrueDoubles'
%                                'TrueSingles'
%                                'ForceOff'
%      AUTOSCALE         - The percent safety margin for autoscaling exponents
%                          can be set.  Values can range from:
%                                      % Safety Margin > -100%
%                          This value appropriately sets the RangeFactor value.
%                          To update the GUI display after autoscaling, the
%                          model will need to be simulated.
%      RUN               - Running the simulation from the GUI will run the
%                          model and update the display to the latest values
%                          of FixPtSimRanges.
%      STOP              - Stops running the simulation.
%      PLOT              - Opens the plot interface containing any ToWorkspace,
%                          Outport or Scope blocks found in the model.  The raw signal
%                          data or the doubles from these blocks can be plotted.
%                        - To update the double values used for plotting, run the
%                          simulation through the GUI with the Doubles Override set
%                          to 'All'.
%                        - The data generated by the last, complete GUI simulation run
%                          is considered the latest raw signal data and is therefore used
%                          for plotting.
%
%   See also SHOWFIXPTSIMRANGES, AUTOFIXEXP.

% Copyright 1994-2004 The MathWorks, Inc.
%   $Revision: 1.44.4.5 $
%   $Date: 2004/04/15 00:34:52 $

%---------------------------------------------------------------------------------------
% Sets up some common variables, opens the system and executes any callbacks. Defaults
% to initialize.
% Parameters:
%   action, system
%---------------------------------------------------------------------------------------

% arg2, the second argument is for backwards compatibility with previous versions of
% the Fixed-Point GUI. It is not used anywhere in this code.
error(nargchk(1,2,nargin));

callbacks={'fxptdlg_initialize', 'fxptdlg_fld_cb', 'fxptdlg_scale_cb', 'fxptdlg_sim_cb', 'fxptdlg_simInit_cb','fxptdlg_closebtn_cb', ...
      'fxptdlg_stop_cb', 'fxptdlg_pause_cb', 'fxptdlg_store_cb', 'fxptdlg_win_cb', 'fxptdlg_close_cb', 'fxptdlg_presave_cb', ...
      'fxptdlg_resize_cb','fxptdlg_postsave_cb', 'fxptdlg_subsys_cb', 'fxptdlg_opensys_cb', 'fxptdlg_logdt_cb', 'fxptdlg_logtype_cb'};

if (nargin == 1) && (~any(strcmp(action, callbacks))),

   parentPath = '';    % path to the parent of current system.
   rootSystem = '';    % top level block diagram
   fullPath = '';      % full path including current subsystem

   [rootSystem, parentPath, fullPath, action] = getPathsFromHandle(action);

   % get the system name without the .mdl (just in case)
   system = strtok(rootSystem,'.');

   % Do some error checking.
   if ~ischar(system),
      error('Input argument must be a string.');
   elseif exist(system) ~= 4,
      error('%s : system not found',system);
   end

   % Open the model and prepare to initialize the GUI.
   open_system(system)
   open_system(fullPath)

   % Check for open GUIs.
   hh = findobj(allchild(0), 'flat','Tag','fxptdlgbx');
   if ~isempty(hh),
      % If a GUI is already open, make it the current
      % figure then return.
      figure(hh)

      % reset the title
      set(hh, 'Name', sprintf('Fixed-Point Settings - %s',fullPath));

      % display logged data if available
      figData = get( hh, 'userdata');

      % update the model callbacks if the root system is different
      if ~strcmp(system, figData.system)
          clearModelCallbacks(hh, figData.system);
          setModelCallbacks(hh, system);
      end

      figData.system = system;
      figData.handle = get_param(system, 'handle');
      figData.fullPath = fullPath;
      set(hh, 'userdata',figData);

      % reset the pulldown list.
      obj = get_param(fullPath, 'uddobject');
      if ~isempty(obj)
        setScope(hh, obj);
      end

      initializePlotStructures(hh);
      initializeMenuButtons(hh);
      updateListboxes( hh );

      return
   else
      % No GUI is associated with SYSTEM so open the model and prepare to
      % initialize the GUI.
      open_system(system)
      open_system(fullPath)
      %
      % Don't allow the GUI on a library or locked model
      %    This code MUST come after open_system.
      %
     if ~strcmpi(get_param(system,'BlockDiagramType'),'model')
        helpdlg(sprintf('The Simulink Fixed Point GUI can only work with unlocked block diagram models.%s This can be done by directly opening the GUI from a model or by passing a model name to FXPTDLG.','\n'),...
        'Simulink Fixed Point GUI')
        return
     elseif strcmpi(get_param(system,'Lock'),'on')
         errordlg('The Fixed Point GUI can not be opened for a locked (read-only) model.')
         return
     end

      % Dialog will be opened by by the "action" section below
      action = 'fxptdlg_initialize';
   end
else

   % Get the handle and the userdata for the GUI
   hFixGui = findobj(allchild(0), 'flat','Tag','fxptdlgbx');

   if ~isempty(hFixGui),
      figData = get( hFixGui,'userdata');
   else
      return
   end

   % get the current system and fullPath
   system = figData.system;
   fullPath = figData.fullPath;

   % Previous versions of this GUI did not use 'fxptdlg_' as the prefix to the callback names.
   % To maintain backwards compatibility, we check the callback string and add the prefix
   % if necessary.

   if isempty(findstr('fxptdlg_',action))
       % Looks like an old version of callback names. Fix it by adding the prefix.
       action = ['fxptdlg_', action];
   end

   % A callback is being executed.
   % For all callbacks, check that the model was not saved as a different name.  If it
   % was, then the presave and close callbacks will be called but the model will not
   % really be available since it is assigned its new saving name.
   %
   if ~any(strcmp(action,{'fxptdlg_closebtn_cb', 'fxptdlg_closemdl_cb', 'fxptdlg_subsys_cb', 'fxptdlg_presave_cb'})),
      %
      % Ensure that the system is still open and wasn't saved under a different name.
      try
         find_system(system);
      catch
         errordlg(sprintf('Invalid Simulink object name: ''%s''.\nTry opening ''%s''.',system,system));
         return
      end
   end
end


switch action

case 'fxptdlg_initialize',

   % create the GUI
   try
       hFixGui = makegui(system, fullPath);
   catch
       % An unexpected error creating the GUI occurred.
       % Return the error and kill the invalid GUI.
       hFixGui = findobj(allchild(0), 'flat','Tag','fxptdlgbx');
       delete(hFixGui)
       errordlg(lasterr)
       return
   end

   % update the model callbacks to notify us when simulation start/stop.
   setModelCallbacks(hFixGui, system);

   % display logged data if available
   updateListboxes( hFixGui );

   initializePlotStructures(hFixGui);

case {'fxptdlg_fld_cb', 'fxptdlg_scale_cb'}

   % Safety Margin EDIT FIELD SETTING
   %  or
   % AUTOSCALE PUSHBUTTON
   minfac  = -100;

   obj = findobj(figData.FigHandle,'tag','factorfield');

   safetyMargin = str2double(get(obj,'string'));

   if isnumeric(safetyMargin) && ~isempty(safetyMargin) && ...
      numel(safetyMargin)==1 && ~isnan(safetyMargin) && safetyMargin>minfac,

      set(obj,'string',safetyMargin(:))
   else
      errordlg(sprintf('Safety margin must be a number greater than %f%.', num2str(minfac)),...
                'Safety Margin Error','modal')
      return
   end

   % AUTOSCALE PUSHBUTTON
   if strcmp(action,'fxptdlg_scale_cb')
       %
       hBlkListbox = findobj(figData.FigHandle,'tag','blockname');
       hSigListbox = findobj(figData.FigHandle,'tag','signal');

       if isempty(get(hSigListbox,'string')),
          errordlg('Simulation must be run first with "Logging mode" set to "Min, max and overflow."','Scaling error')
          return
       end

       RangeFactor=1+(safetyMargin/100);

       assignin('base','RangeFactor',RangeFactor)
       try
          evalin('base','autofixexp;')
       catch
          errordlg(lasterr,'AUTOFIXEXP error.','modal')
          return
       end
   end

case 'fxptdlg_win_cb',

   % WINDOW SELECTION HILIGHTING OCCURRED.
   hilite=get(gcbo,'value');

   % get the handles for the two listboxes
   hBlkListbox = findobj(figData.FigHandle,'tag','blockname');
   hSigListbox = findobj(figData.FigHandle,'tag','signal');

   % don't react if data is not yet displayed in listboxes
   if ~isempty( get(hBlkListbox,'string') ) && ...
      ~isequal( get(hBlkListbox,'string'), ' ');

       % set which lines are highlighted
       if gcbo==hBlkListbox,

          blkIndex = hilite;
          sigIndex = figData.blockData(hilite).SigIndex;
          set(hSigListbox,'value',sigIndex)

       else

          blkIndex = figData.sigData(hilite).BlockIndex;
          sigIndex = hilite;
          set(hBlkListbox,'value',blkIndex)

       end

       selectedBlocks = find_system(figData.system,'LookUnderMasks','all',...
                                    'Selected','on');

       for ij = 1:length(selectedBlocks)

         set_param(selectedBlocks{ij},'Selected','off');

       end

       set_param(figData.blockData(blkIndex).Path,'Selected','on');


       % if it was a double click, then open the block dialog too.
       selectType = get(hFixGui,'SelectionType');

       if strcmp( selectType, 'open' )

         % close all subsystems and
         % open the subsystem containing the current block
         selectedBlocks = find_system(bdroot(figData.fullPath),'BlockType','SubSystem','Open','on');
         for ij = 1:length(selectedBlocks)

           set_param(selectedBlocks{ij},'Open','off');

         end

         open_system(get_param( figData.blockData(blkIndex).Path, 'Parent'),'force')

         open_system(figData.blockData(blkIndex).Path)
       end

   end

 case 'fxptdlg_sim_cb',

  % enable/disable buttons
  startbtn = figData.startBtn;
  pausebtn = figData.pauseBtn;
  stopbtn = figData.stopBtn;
  set(startbtn, 'enable','off');
  set(pausebtn, 'enable','on');
  set(stopbtn, 'enable', 'on');

  % Start button
  % Unpause simulation if paused.
  if strcmpi(get_param(figData.system,'simulationstatus'),'paused'),
    try
      evalin('base',['set_param(''', figData.system, ''',''simulationcommand'',''continue'')'])
      return
    catch
      errordlg(lasterr,'Error')
      return
    end
  end

  % Start running the simulation.
  try
    evalin('base',['set_param(''', figData.system, ''',''simulationcommand'',''start'')'])
  catch
    errordlg(lasterr,'Error','modal')
    return
  end

 case 'fxptdlg_simInit_cb',

   % Simulation Initialization callback is called by a callback stored in
   % the model and is not called by any uicontrol on the model
   
   % get the value of the doubles menu and store it in UserData
   % this value will be used at the end of simulation to determine where to
   % store data
   figData.DoubleMenu = get(findobj(figData.FigHandle,'tag','doublemenu'),'value');

   set( hFixGui,'userdata',figData);

 case 'fxptdlg_pause_cb',

  % enable/disable buttons
  startbtn = figData.startBtn;
  pausebtn = figData.pauseBtn;
  stopbtn = figData.stopBtn;
  set(startbtn, 'enable','on');
  set(pausebtn, 'enable','off');
  set(stopbtn, 'enable', 'on');

  % pause simulation if running.
  if strcmpi(get_param(figData.system,'simulationstatus'),'running'),
    try
      evalin('base',['set_param(''', figData.system, ''',''simulationcommand'',''pause'')'])
      return
    catch
      errordlg(lasterr,'Error')
      return
    end
  end

 case 'fxptdlg_stop_cb',

  % enable/disable buttons
  startbtn = figData.startBtn;
  pausebtn = figData.pauseBtn;
  stopbtn = figData.stopBtn;
  set(startbtn, 'enable', 'on');
  set(pausebtn, 'enable', 'off');
  set(stopbtn, 'enable', 'off');

   % Stop button
   % If the simulation is running or paused, we stop it.
   if any(strcmpi( get_param(figData.system,'simulationstatus'), {'running', 'paused'} )),
      try
         evalin('base',['set_param(''', figData.system, ''',''simulationcommand'',''stop'')'])
      catch
         errordlg(lasterr,'Error')
         return
      end
   end

 case 'fxptdlg_store_cb',

   % enable start button
   startbtn = figData.startBtn;
   pausebtn = figData.pauseBtn;
   stopbtn = figData.stopBtn;
   set(startbtn, 'enable','on');
   set(pausebtn, 'enable', 'off');
   set(stopbtn, 'enable', 'off');

   % Model's stop callback
   % update display of logged data
   % and get a fresh copy of userdata
   updateListboxes( hFixGui );

   figData = get( hFixGui,'userdata');
   % Determine if we are overriding with doubles.

   % Determining whether the data that has just been
   % logged is a bit tricky, because the data type override
   % setting can be controlled on a subsystem by subsystem
   % basis.  To keep things simple, only the setting at
   % the root level is used.  This design needs improvement.
   % 
   cursysHandle = get_param(figData.fullPath, 'Handle');
   
   DataTypeOverrideMode = get_param(bdroot(cursysHandle),'DataTypeOverride');
   
   switch DataTypeOverrideMode
     
    case {'ScaledDoubles', 'TrueDoubles'}
     
     storeAsDoubleData = 1;    
     
    otherwise
     
     storeAsDoubleData = 0;    
     
   end
   
   if storeAsDoubleData
      storePlotData( hFixGui, 'double');
   else
      storePlotData( hFixGui, 'raw');
   end

 case 'fxptdlg_resize_cb',

    resizegui(hFixGui);

 case 'fxptdlg_closebtn_cb',
    % called by clicking on the close button

    % restore the models callbacks to their original form
    find_system(figData.system);

    clearModelCallbacks(hFixGui, figData.system);

    hh = findobj(allchild(0),'flat','name',['Plot system: ' figData.system]);
    if ~isempty(hh),
        delete(hh)
    end

    figure(hFixGui)
    closereq

 case 'fxptdlg_close_cb',
    % called by the model

    % clear out the topObject in the scope listbox
    setScope(hFixGui);

    find_system(figData.system);

    % clear the model callbacks for the old system
    clearModelCallbacks(hFixGui, figData.system);

    % Check to see if we have other systems that we can switch to
    openSystem = findAnOpenSystem(figData.system);

    if ~isempty(openSystem)
        % We have a valid system to switch to
        figData = get( hFixGui,'userdata');

        obj = get_param(openSystem, 'uddobject');
        setScope(hFixGui, obj);

        initializePlotStructures(hFixGui);
        initializeMenuButtons(hFixGui);
        updateListboxes(hFixGui);
    else
        % Did not find a valid system to switch to. Close the GUI.
        hh = findobj(allchild(0),'flat','name',['Plot system: ' figData.system]);
        if ~isempty(hh),
            delete(hh)
        end

        figure(hFixGui)
        closereq
    end

 case 'fxptdlg_presave_cb'

   sysname = get_param(gcs,'Name');

   % check for name change
   if ((figData.handle == get_param(gcs, 'handle')) && ~strcmp(sysname, figData.system)),
       setScope(hFixGui);
       figData = get(hFixGui, 'UserData');
   end

   if ~strcmp(sysname, figData.system)

      clearModelCallbacks(hFixGui, figData.system);

      hh = findobj(allchild(0),'flat','name',['Plot system: ' figData.system]);
      if ~isempty(hh),
         delete(hh)
      end

      figure(hFixGui)
      closereq
   end

 case 'fxptdlg_subsys_cb'
    setScope(hFixGui, 'select');
    % redo our plot structures.
    initializePlotStructures(hFixGui);
    initializeMenuButtons(hFixGui);
    updateListboxes( hFixGui );

 case 'fxptdlg_opensys_cb'
    object  = setScope(hFixGui);
    if ~isempty(object)
        % lets try to open this system
        open_system(object.handle);
    end

 case 'fxptdlg_logdt_cb'
    hlogmnu = findobj( hFixGui,'tag','logmenu');
    hdatamnu = findobj( hFixGui,'tag','doublemenu');

    logind = get(hlogmnu, 'value');
    dtind = get(hdatamnu,'value');

    str1 = getLogSetting(logind);
    str2 = getDTSetting(dtind);

    object  = setScope(hFixGui);
    if ~isempty(object)
      try
        set_param(object.handle,'MinMaxOverflowLogging',str1);
        set_param(object.handle,'DataTypeOverride',str2);
      catch
        errordlg(lasterr, 'Error');
      end        
    else
      errordlg(lasterr, 'Error');
    end

 case 'fxptdlg_logtype_cb'
  hlogtypemnu = findobj(hFixGui, 'tag', 'logtypemenu');
  
  logtypeind  = get(hlogtypemnu, 'value');
  
  str1 = getLogTypeSetting(logtypeind);
  
  object = setScope(hFixGui);
  if ~isempty(object)
    try
      set_param(figData.system, 'MinMaxOverflowArchiveMode', str1);
    catch
      errordlg(lasterr, 'Error');
    end      
  else
    errordlg(lasterr, 'Error');
  end
  
  
case 'fxptdlg_postsave_cb',
end


%---------------------------------------------------------------------------------------
% Creates the HG GUI objects
% Parameters:
%   system - The root system
%   fullPath - The fullPath to the place from which this GUI was invoked.
%---------------------------------------------------------------------------------------
function hFixGui = makegui(system, fullPath)

% Determine screen size in pixels and in chars
RootUnits=get(0,'units');

set(0,'units','pixels')
scrnsize=get(0,'screensize');
scrnWt = scrnsize(3);
scrnHt = scrnsize(4);

set(0,'units',RootUnits)

fwFont = get(0,'FixedWidthFontName');

% determine size of GUI in pixels
%   if standard size is too big, reduce size for small screens
% determine position of GUI in pixels
%    center the figure
%
figWt = min(  600, floor(0.97 * scrnWt) );
figHt = min(  400, floor(0.85 * scrnHt) );

figLt = 0.5 * ( scrnWt - figWt );
figBt = 0.7 * ( scrnHt - figHt );

figPos = [ figLt figBt figWt figHt ];

hFixGui=figure(...
   'Integerhandle','off',...
   'Menubar','none',...
   'numbertitle','off',...
   'parent',0,...
   'tag','fxptdlgbx',...
   'name',['Fixed-Point Settings - ' system],...
   'Units','pixels',...
   'Position',figPos,...
   'closerequestfcn','fxptdlg(''fxptdlg_closebtn_cb'');',...
   'resizefcn','fxptdlg(''fxptdlg_resize_cb'');');

% Lets create the frames first.

% BUTTON FRAME: Play, Stop, Plot and Help buttons.
uicontrol('Units','pixels','Style','frame','Tag','frameBlocks');

% AUTOSCALING FRAME: Autoscaling controls.
uicontrol('Units','pixels','Style','frame','Tag','frameAutoScale');

% LOGGING FRAME: Logging and Doubles-control.
uicontrol('Units','pixels','Style','frame','Tag','frameLogging');

% Create the frame labels
uistr1 = {'Fixed-Point settings for blocks in the current system'};
uicontrol('Units','pixels','String',uistr1,'Style','text',...
    'horizontalalignment','left','Tag','textframeFixPoint');

uistr1 = 'Simulation data logged for current system';
uicontrol('Units','pixels','String',sprintf('%s',uistr1),'Style','text',...
    'horizontalalignment','left','Tag','textframeBlocks');

uistr1 = 'Autoscale current system';
uicontrol('Units','pixels','String',sprintf('%s',uistr1),'Style','text',...
    'horizontalalignment','left','Tag','textframeAutoscaling');


% Next, create all the ui buttons excpet the toggle buttons above.

% button: autoscale
uicontrol('Units','pixels','String','Autoscale Blocks','Tag','scalepb',...
          'callback','fxptdlg(''fxptdlg_scale_cb'');',...
          'TooltipString','Autoscale all blocks in the current system');

% button:  open system
uicontrol('Units','pixels','String','Open System','Tag','openpb',...
          'callback','fxptdlg(''fxptdlg_opensys_cb'');',...
          'TooltipString','Open the current (sub)system');

% button: help
uicontrol('Units','pixels','String','Help','Tag','helppb',...
          'callback','web(fpbhelp(''fxptdlg''));', 'TooltipString', ...
          'Show Simulink Fixed Point help');

% button: close
uicontrol('Units','pixels','String','Close','Tag','closepb',...
          'callback','fxptdlg(''fxptdlg_closebtn_cb'');',...
          'TooltipString', 'Close Simulink Fixed Point dialog');

% Subsystem pulldown
uistr1 = 'Select current system:';
uicontrol('Units','pixels','String',uistr1,'Style','text',...
    'horizontalalignment','left','Tag','textSubsys');

% Logging
uistr1 = 'Logging mode:';
tooltipstr = 'Determines if min, max and overflow data for blocks in this system are stored in the MATLAB workspace and displayed.';
uicontrol('Units','pixels','String',uistr1,'Style','text',...
   'horizontalalignment','left','Tag','textLogMode', 'TooltipString',tooltipstr);

% Datatype Override
uistr1 = 'Data type override:';
tooltipstr = 'Determines if data types specified in the block dialogs of this system are overridden.';
uicontrol('Units','pixels','String',uistr1,'Style','text',...
   'horizontalalignment','left','Tag','textDataMode','TooltipString',tooltipstr);

% Logging type
uicontrol('Units','pixels','String','Logging type:','Style','text',...
   'horizontalalignment','left','Tag','textLogType','TooltipString','Choose logging type.');

% Safety Margin
uistr1 = 'Safety margin:';
uicontrol('Units','pixels','String',uistr1,'Style','text',...
   'horizontalalignment','left','Tag','textSafeMarg');

% List Box Display
% 'FontName',fwFont,
%            1             2         3         4         5
%          12345678901234567890123456789012345678901234567890
uistr2 = '  Min       Max     Data Type   Scaling';
      %    '                    Type           '};
uicontrol('FontName',fwFont,'Units','pixels','horizontalalignment', ...
    'left','Style','text','string',sprintf(uistr2),'Tag','textRightDisplay');

% text field: Datatype, actual settings
hDTActField = uicontrol('Units','pixels','Style','text','Tag', ...
    'editDTActual', 'horizontalalignment','left',...
    'TooltipString', 'System that is setting the Data Type Override parameter');

% text field: Logging, actual settings
hLogActField = uicontrol('Units','pixels','Style','text','Tag', ...
    'editLoggingActual', 'horizontalalignment','left',...
    'TooltipString','System that is setting the Logging parameter');

% Edit field: safety margin
hfacfield = uicontrol('Units','pixels','String','0.0','enable','on','Style','edit', ...
                      'Tag','factorfield','callback', ...
                      'fxptdlg(''fxptdlg_fld_cb'');',...
                      'TooltipString','Enter scaling percentage. (Must be greater than -100' );


% Create popups

% popup for logging enable
droplist={'Use local settings';'Min, max and overflow';'Overflow only';'Force off'};
hlgmnu = uicontrol('Units','pixels','String',droplist,'Style','popupmenu',...
                   'enable','on','Value',3,'Tag','logmenu', ...
                   'callback', 'fxptdlg(''fxptdlg_logdt_cb'');',...
                   'TooltipString', 'Choose logging setting for current system');

% popup for doubles override
droplist={'Use local settings';'Scaled doubles';'True doubles';'True singles';'Force off'};
hdblmnu = uicontrol('Units','pixels','String',droplist,'Style','popupmenu',...
                    'Tag','doublemenu','Value',3,'enable','on', ...
                    'callback', 'fxptdlg(''fxptdlg_logdt_cb'');',...
                    'TooltipString','Choose datatype setting for current system');

% popup for log merging
hlgtypmnu = uicontrol('Units','pixels','Style','popupmenu','Tag','logtypemenu','Value',1,...
                      'String',{'Overwrite log'; 'Merge log'}, ...
                      'TooltipString','Choose logging type', ...
                      'callback', 'fxptdlg(''fxptdlg_logtype_cb'');');

% popup for BD hierarchy
droplist = {'  '};
hsubsysmnu = uicontrol('Units','pixels','String',droplist,'Style','popupmenu',...
                    'Tag','subsysmenu','Value',1,'enable','on', 'FontName', fwFont, ...
                    'CallBack', 'fxptdlg(''fxptdlg_subsys_cb'');');

% MIDDLE FRAME: Left display area
%
hBlkListbox = uicontrol('FontName',fwFont,'Units','pixels','listboxtop',1, ...
                        'Style','listbox','Tag','blockname',...
                        'TooltipString', 'List of Fixed-Point blocks in current system', ...
                        'callback','fxptdlg(''fxptdlg_win_cb'');');

%
% MIDDLE FRAME: Text for Left display area
%
uicontrol('FontName',fwFont,'Units','pixels','horizontalalignment','left', ...
          'Style','text','string','Block Name:','Tag','textLeftDisplay');
% Listbox for fxpt info.
hSigListbox = uicontrol('FontName',fwFont,'Units','pixels','listboxtop',1,'Style', ...
                        'listbox','Tag','signal','callback', ...
                        'fxptdlg(''fxptdlg_win_cb'');',...
                        'TooltipString', 'Logging information for blocks from previous simulation');


% SET SIMULINK CALLBACKS:
figData.Fcn.Names{1} = 'InitFcn';
figData.Fcn.Names{2} = 'StartFcn';
figData.Fcn.Names{3} = 'StopFcn';
figData.Fcn.Names{4} = 'CloseFcn';
figData.Fcn.Names{5} = 'PreSaveFcn';

% Find out what the callbacks are for SYSTEM.
for i=1:length(figData.Fcn.Names)
    figData.Fcn.Old{i} = get_param(system,figData.Fcn.Names{i});
end

% Define what callbacks to use for SYSTEM.
figData.Fcn.New{1}    = ';fxptdlg(''fxptdlg_simInit_cb'');';
figData.Fcn.New{2}    = ';fxptdlg(''fxptdlg_sim_cb'');';
figData.Fcn.New{3}    = ';fxptdlg(''fxptdlg_store_cb'');';
figData.Fcn.New{4}    = ';fxptdlg(''fxptdlg_close_cb'');';
figData.Fcn.New{5}    = ';fxptdlg(''fxptdlg_presave_cb'');';


% RELEVANT HANDLES FROM TOP, MIDDLE AND BOTTOM OBJECTS.
figData.FigHandle = [hlgmnu hlgtypmnu hdblmnu hsubsysmnu hfacfield hBlkListbox hSigListbox];
figData.DoubleMenu = [];

% SET PARENT AND BACKGROUND COLORS.
set(allchild(hFixGui),'Parent',hFixGui,'BackgroundColor',[0.8 0.8 0.8]);
set(figData.FigHandle,'BackgroundColor',[1 1 1]);

% load the button image data
startBtnData = load('startbtn.mat');
stopBtnData  = load('stopbtn.mat');
pauseBtnData = load('pausebtn.mat');
plotBtnData  = load('plotbtn.mat');

% create the start and stop buttons.
toolbarHandle = uitoolbar('parent',hFixGui);
startBtn = uitoggletool('parent',toolbarHandle, ...
                        'cdata', startBtnData.data, ...
                        'enable', 'on', ...
                        'TooltipString','Start simulation');
pauseBtn = uitoggletool('parent',toolbarHandle, ...
                       'cdata', pauseBtnData.data, ...
                       'enable', 'off', ...
                       'TooltipString','Pause simulation');
stopBtn = uitoggletool('parent',toolbarHandle, ...
                       'cdata', stopBtnData.data, ...
                       'enable', 'off', ...
                       'TooltipString','Stop simulation');
plotBtn = uitoggletool('parent',toolbarHandle,'OnCallback', ...
                       'set(gcbo, ''state'', ''off'');fxptplt;', ...
                       'TooltipString', 'Show plot dialog', ...
                       'cdata', plotBtnData.data);

set(startBtn, 'OnCallBack', ...
    'set(gcbo, ''state'', ''off''); fxptdlg(''fxptdlg_sim_cb'');');

set(pauseBtn, 'OnCallBack', ...
    'set(gcbo, ''state'', ''off''); fxptdlg(''fxptdlg_pause_cb'');');

set(stopBtn, 'OnCallBack', ...
    'set(gcbo, ''state'', ''off''); fxptdlg(''fxptdlg_stop_cb'');');

%Store the toolbar handle, we need it when destroying the gui
figData.toolbarHandle = toolbarHandle;
figData.startBtn = startBtn;
figData.pauseBtn = pauseBtn;
figData.stopBtn = stopBtn;

% SYSTEM NAME AND GUI HANDLES ARE STORED IN THE FIGURE'S USERDATA PROPERTY.
% TURN HANDLEVISIBILITY AND RESIZE OFF.
figData.system = system;
figData.handle = get_param(system, 'handle');
figData.fullPath = fullPath;

% initialize the plot data to be empty
figData.RawData = [];
figData.DblData = [];

set(hFixGui,'userdata',figData,'resize','on','handlevisibility','off');

% get the top level udd object and set it setScope
uddObj = get_param(fullPath, 'uddobject');

if ~isempty(uddObj)
    setScope(hFixGui, uddObj);
end

% populate the pulldown and layout the gui
setScope(hFixGui);
resizegui(hFixGui);


%---------------------------------------------------------------------------------------
% Moves all HG objects to their correct position on the screen. Responsible for layout.
% Parameters:
%   hFixGui - This GUI handle
%---------------------------------------------------------------------------------------
function resizegui(hFixGui)

% Determine screen size in pixels and in chars
RootUnits=get(0,'units');

set(0,'units','pixels')
scrnsize=get(0,'screensize');
scrnWt = scrnsize(3);
scrnHt = scrnsize(4);

set(0,'units',RootUnits)

fwFont = get(0,'FixedWidthFontName');

hx = uicontrol(hFixGui,'FontName',fwFont,'Units','pixels','String','XX'    ,'Style','text',...
    'horizontalalignment','left');
ex1 = get(hx,'extent');
delete(hx);

hx = uicontrol(hFixGui,'FontName',fwFont,'Units','pixels','String',sprintf('XXX\nXXX')   ,'Style','text',...
    'horizontalalignment','left');
ex2 = get(hx,'extent');
delete(hx);

exdiff = ex2-ex1;

% The character size used in calculations must be limited
% otherwise the height or width of some sections of
% the dialog become negative, we results in HG errors.
% If a customers machine is somehow set to have a 
% very big font.  The dialog will be laid out
% with overlaping parts.
charHt = min(21,exdiff(4));
charWt = min( 9,exdiff(3));

% set size for popup menus, buttons, and edit fields
%  and for standard gap size
butWt  = 10  * charWt;

butHt = ceil(1.5 * charHt);
comHt = ceil(1.5 * charHt);

gap = 6;

figPos = get(hFixGui,'Position');

figLt = figPos(1);
figBt = figPos(2);
figWt = figPos(3);
figHt = figPos(4);

% don't allow figure to get so small that things collide
% and don't allow figure to hang too far off the screen
minFigHt = 400;
minFigWt = 600;

if ( figWt <  minFigWt )

    figWt = minFigWt;

    figPos(3) = figWt;
end

if ( figHt <  minFigHt )

    figHt = minFigHt;

    figPos(4) = figHt;
end

if ( figWt > scrnWt )

    figWt = scrnWt;

    figPos(3) = figWt;
end

minOnScrn = 60;

if ( (scrnWt - figLt + 1) < minOnScrn )

    figLt = scrnWt + 1 - minOnScrn;

    figPos(1) = figLt;
end

if ( ( figLt + figWt - 1 ) < minOnScrn )

    figLt = minOnScrn - figWt + 1;

    figPos(1) = figLt;
end

maxFigHt = scrnHt - 5;

if ( figHt > maxFigHt )

    figHt = maxFigHt;

    figPos(4) = figHt;
end

if ( (figBt + figHt - 1) > maxFigHt )

    figBt = maxFigHt - figHt + 1;

    figPos(2) = figBt;
end

if ( ( figBt + figHt - 1 ) < minOnScrn )

    figBt = minOnScrn - figHt + 1;

    figPos(2) = figBt;
end

set(hFixGui,'Position',figPos);

% divide figure into horizontal sections

% topSect contains the system path information
topSectHt  =     comHt;
% logSect contains the logging and datatype info
logSectHt  = 2 * comHt + 2 * gap + comHt/2;
% AutoSect contains the autoscaling info.
autoSectHt =     comHt + 1 * gap + comHt/2;
% botSect contains the close and help buttons
botSectHt  =     butHt;

gapVeryBot     = gap;
gapCloseToAuto = gap;
gapAutoToList  = comHt/2 + gap;
gapListToSet   = comHt/2 + gap;
gapSetToSys    = comHt/2 + gap;
gapVeryTop     = gap;

totSectGaps = gapVeryBot + gapCloseToAuto + gapAutoToList + gapListToSet + gapSetToSys + gapVeryTop;

% contains the listbox
midSectHt = figHt - botSectHt - autoSectHt - logSectHt - topSectHt - totSectGaps;

% calculate the lower left hand position for each frame.
botSectBt  =                           gapVeryBot;
autoSectBt = botSectBt  + botSectHt  + gapCloseToAuto;
midSectBt  = autoSectBt + autoSectHt + gapAutoToList;
logSectBt  = midSectBt  + midSectHt  + gapListToSet;
topSectBt  = logSectBt  + logSectHt  + gapSetToSys;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bottom section.
rowBt = botSectBt;

% button: close, plot
hor1Lt = figWt - gap - butWt;
hor2Lt = figWt - 2*gap - 2*butWt;

curPos = [ hor1Lt rowBt butWt butHt ];
uuu = findobj(hFixGui,'Tag','helppb');
set(uuu,'Position',curPos);

curPos = [ hor2Lt rowBt butWt butHt ];
uuu = findobj(hFixGui,'Tag','closepb');
set(uuu,'Position',curPos);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% draw the autoscale section
fram1Wt = figWt - 2* gap;
fram1Lt = gap;

hor1Wt = 15*charWt; 
hor2Wt = 10*charWt;
hor3Wt = 18*charWt;
totWt = hor1Wt + hor2Wt + 2*butWt;

hor1Lt = 2 * gap;
hor2Lt = hor1Lt + hor1Wt + 2 * gap;  % safety margin edit box
hor3Lt = hor2Lt + hor2Wt + 2 * gap;  % autoscale button

row1Bt = autoSectBt + gap;

%frame: autoscale
curPos = [ fram1Lt autoSectBt fram1Wt autoSectHt ];
uuu = findobj(hFixGui,'Tag','frameAutoScale');
set(uuu,'Position',curPos);

%text: frame title
curPos = [ (fram1Lt + gap) (autoSectBt + autoSectHt - comHt/2) 24*charWt  comHt ];
uuu = findobj(hFixGui,'Tag','textframeAutoscaling');
set(uuu,'Position',curPos);

%text safety margin
curPos = [ hor1Lt row1Bt hor1Wt  comHt ];
uuu = findobj(hFixGui,'Tag','textSafeMarg');
set(uuu,'Position',curPos);

%edit Autoscale
curPos = [ hor2Lt row1Bt hor2Wt  comHt ];
uuu = findobj(hFixGui,'Tag','factorfield');
set(uuu,'Position',curPos);

% button: autoscale
curPos = [ hor3Lt row1Bt hor3Wt comHt ];
uuu = findobj(hFixGui,'Tag','scalepb');
set(uuu,'Position',curPos);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TOP FRAME CONTAINS: path display
row1Bt = topSectBt;

hor1Wt = 23 * charWt;
hor3Wt = 15 * charWt;
hor2Wt = figWt - hor1Wt - hor3Wt - 4 * gap;

hor1Lt =  gap;
hor2Lt =  gap + hor1Lt + hor1Wt;
hor3Lt =  gap + hor2Lt + hor2Wt;

% text  field: subsystem pulldown text
curPos = [ hor1Lt row1Bt hor1Wt  comHt ];
uuu = findobj(hFixGui,'Tag','textSubsys');
set(uuu,'Position',curPos);

% list  field: subsystem pulldown
curPos = [ hor2Lt row1Bt hor2Wt  comHt ];
uuu = findobj(hFixGui,'Tag','subsysmenu');
set(uuu,'Position',curPos);

% open system button
curPos = [ hor3Lt row1Bt hor3Wt comHt ];
uuu = findobj(hFixGui,'Tag','openpb');
set(uuu,'Position',curPos);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LOG FRAME CONTAINS: logging setting and datatype override setting display
framWt = figWt - 2 * gap;
framLt = gap;

row1Bt = logSectBt      + 1 * gap;
row2Bt = row1Bt + comHt + 1 * gap;

hor1Wt = 20 * charWt;  % datatype text
hor2Wt = 14 * charWt;  % logging text
hor12Wt = max(hor1Wt,hor2Wt);
hor3Wt = 28 * charWt;  % Local Settings width

hor3aWt = framWt - hor12Wt - hor3Wt - 4*gap;
hor4Wt = 53 * charWt;  % frame title width

hor1Lt = framLt + gap;           % datatype and logging text left pos.
hor2Lt = hor1Lt + hor12Wt + gap; % Local Settings left pos
hor3Lt = hor2Lt + hor3Wt  + gap; % Actual Settings left pos

% FRAME: Logging
curPos = [ framLt logSectBt framWt logSectHt ];
uuu = findobj(hFixGui,'Tag','frameLogging');
set(uuu,'Position',curPos);

%text: frame title
curPos = [ (framLt + gap) (logSectBt+logSectHt-comHt/2) hor4Wt  comHt ];
uuu = findobj(hFixGui,'Tag','textframeFixPoint');
set(uuu,'Position',curPos);

%text DataType override
curPos = [ hor1Lt row1Bt hor1Wt  comHt ];
uuu = findobj(hFixGui,'Tag','textDataMode');
set(uuu,'Position',curPos);

%text logging
curPos = [ hor1Lt row2Bt hor2Wt  comHt ];
uuu = findobj(hFixGui,'Tag','textLogMode');
set(uuu,'Position',curPos);

% popup for doubles override
curPos = [ hor2Lt row1Bt hor3Wt comHt ];
uuu = findobj(hFixGui,'Tag','doublemenu');
set(uuu,'Position',curPos);

% popup for logging enable
curPos = [ hor2Lt row2Bt hor3Wt comHt ];
uuu = findobj(hFixGui,'Tag','logmenu');
set(uuu,'Position',curPos);

% static text box for Data type Actual
curPos = [ hor3Lt row1Bt hor3aWt  comHt ];
uuu = findobj(hFixGui,'Tag','editDTActual');
set(uuu,'Position',curPos);

% static text box for logging actual
curPos = [ hor3Lt row2Bt hor3aWt  comHt  ];
uuu = findobj(hFixGui,'Tag','editLoggingActual');
set(uuu,'Position',curPos);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MIDDLE FRAME CONTAINS: two list boxes
% divide bottom frame into two sections
framWt = figWt - 2 * gap;
framLt = gap;

remSectWt = framWt - 3 * gap;

% get the list box contents data
hBlkListbox = findobj( hFixGui,'tag','blockname');
hSigListbox = findobj( hFixGui,'tag','signal');

blkListStr = get(hBlkListbox,'string');
sigListStr = get(hSigListbox,'string');

minWidthBlkList = 10;
widthBlkList = minWidthBlkList;

if iscell(blkListStr)

  for iw = 1:length(blkListStr)

     widthBlkList = max(widthBlkList,length(blkListStr{iw}));
  end
else
   widthBlkList = max(widthBlkList,length(blkListStr));
end

minWidthSigList = 30;
widthSigList = minWidthSigList;

if iscell(sigListStr)

  for iw = 1:length(sigListStr)

     widthSigList = max(widthSigList,length(sigListStr{iw}));
  end
else
   widthSigList = max(widthSigList,length(sigListStr));
end

minSigPercent = 0.50;
maxSigPercent = 0.85;

if widthBlkList == 0

  sigPercent = maxSigPercent;

else
  sigPercent = widthSigList / ( widthSigList + widthBlkList );

  sigPercent = min( maxSigPercent, max( minSigPercent, sigPercent ) );
end

minHor2Wt = 275;
hor2Wt = max(minHor2Wt,remSectWt * sigPercent);

hor1Wt = remSectWt - hor2Wt;

hor1bWt = 14 * charWt;
hor2bWt = 19 * charWt;

hor1Lt =  framLt + gap;
hor2Lt =  hor1Lt + hor1Wt + gap;
hor2bLt = hor1Lt + hor1bWt + gap;

logtypeHt = comHt;
midTextHt = comHt;
midListHt = midSectHt - midTextHt - logtypeHt - 3.5 * gap;

logtypeBt = midSectBt + gap;
midListBt = logtypeBt + logtypeHt + gap;
midTextBt = midListBt + midListHt;

% FRAME: MIDDLE
midPosXXX = [ framLt midSectBt framWt midSectHt ];
uuu = findobj(hFixGui,'Tag','frameBlocks');
set(uuu,'Position',midPosXXX);

%text: frame title
titleWt = 41*charWt;
curPos = [ (framLt + gap) (midSectBt + midSectHt - comHt/2) titleWt  comHt ];
uuu = findobj(hFixGui,'Tag','textframeBlocks');
set(uuu,'Position',curPos);

% MIDDLE FRAME: Left display area
curPos = [ hor1Lt midListBt hor1Wt midListHt ];
uuu = findobj(hFixGui,'Tag','blockname');
set(uuu,'Position',curPos);
%
% MIDDLE FRAME: Text for Left display area
curPos = [ hor1Lt midTextBt hor1Wt midTextHt ];
uuu = findobj(hFixGui,'Tag','textLeftDisplay');
set(uuu,'Position',curPos);

% MIDDLE FRAME: right display area
curPos = [ hor2Lt midListBt hor2Wt midListHt ];
uuu = findobj(hFixGui,'Tag','signal');
set(uuu,'Position',curPos);

% popup for logging type enable
curPos = [ hor1Lt logtypeBt hor1bWt comHt ];
uuu = findobj(hFixGui,'Tag','textLogType');
set(uuu,'Position',curPos);

curPos = [ hor2bLt logtypeBt hor2bWt comHt ];
uuu = findobj(hFixGui,'Tag','logtypemenu');
set(uuu,'Position',curPos);

% MIDDLE FRAME: Text for Right display area
%                   1         2         3         4         5
%          12345678901234567890123456789012345678901234567890
curPos = [ hor2Lt midTextBt hor2Wt midTextHt ];
uuu = findobj(hFixGui,'Tag','textRightDisplay');
set(uuu,'Position',curPos);


%---------------------------------------------------------------------------------------
% Updates the list boxes after a simulation is run. Populates with current values.
% Parameters:
%   hFixGui - This GUI handle
%---------------------------------------------------------------------------------------
function updateListboxes( hFixGui )

%  This function UPDATES USERDATA

% get the user data
figData = get( hFixGui, 'userdata');

% Initialize variables:
blk = {};
sig = {};

blkCounter = 1;
sigCounter = 1;

blockData = [];
sigData   = [];

% process the logged data if available
%
%   if autoscaling is in progress, then
%   the FixPtSimRange data can be temporarily
%   corrupted.  The autoscaling tool makes
%   a backup of that data.  That data will be restored if present
%
restoreGlobalFixPtSimRanges;

global FixPtSimRanges

% process each block
for i = 1:length(FixPtSimRanges),

   % get the path of the current block
   curPath = FixPtSimRanges{i}.Path;

   % process this block only if its root corresponds to the current system
   try

      % be careful, because path may not correspond to an open system
      curRoot = bdroot(curPath);
   catch
      curRoot = '';
   end

   % Only display blocks at this subsystem level and lower.
   if findstr( curPath,[figData.fullPath, '/'])
       % block may have been deleted since the data was 
       % logged, so make sure it is still reachable
       try
           get_param( curPath, 'Name' );
           blkIsInCurrentModel = 1;
       catch
           blkIsInCurrentModel = 0;
       end
   else
       blkIsInCurrentModel = 0;
   end
   
   if blkIsInCurrentModel

       % Use a flag to determine if the minmax list box entry for this block
       % is one line or two.
       flag = 0;

       % get the path of the current block
       blockData(blkCounter).Path = curPath;

       % store the index to the line in the min max listbox that
       % corresponds to the first output of the current block
       blockData(blkCounter).SigIndex = sigCounter;

       % Get name of the current block
       blk{blkCounter} = get_param( curPath, 'Name' );

       blk{blkCounter} = strrep( blk{blkCounter}, sprintf('\n'), ' ');

       if isfield( FixPtSimRanges{i}, 'SignalName' )

         blk{blkCounter} = sprintf('%s : %s',blk{blkCounter},FixPtSimRanges{i}.SignalName);

       end
       
       % process error info if any
       bo = isfield(FixPtSimRanges{i},'OverflowOccurred');
       bs = isfield(FixPtSimRanges{i},'SaturationOccurred');
       bp = isfield(FixPtSimRanges{i},'ParameterSaturationOccurred');
       bd = isfield(FixPtSimRanges{i},'DivisionByZeroOccurred');

    	if bo
              % store the index to the line in the block listbox that
              % corresponds to the block containing this signal
              sigData(sigCounter).BlockIndex = blkCounter;

    	     str = sprintf('OVERFLOW occurred %d time(s).',FixPtSimRanges{i}.OverflowOccurred);
             flag = 1;
             sig{sigCounter} = str;
             sigCounter = sigCounter + 1;
    	end

    	if bs
              % store the index to the line in the block listbox that
              % corresponds to the block containing this signal
              sigData(sigCounter).BlockIndex = blkCounter;

    	     str = sprintf('SATURATION occurred %d time(s).',FixPtSimRanges{i}.SaturationOccurred);
             flag = 1;
             sig{sigCounter} = str;
             sigCounter = sigCounter + 1;
    	end

    	if bp
              % store the index to the line in the block listbox that
              % corresponds to the block containing this signal
              sigData(sigCounter).BlockIndex = blkCounter;

    	     str = sprintf('PARAMETER SATURATION occurred %d time(s).',FixPtSimRanges{i}.ParameterSaturationOccurred);
             flag = 1;
             sig{sigCounter} = str;
             sigCounter = sigCounter + 1;
    	end

    	if bd
              % store the index to the line in the block listbox that
              % corresponds to the block containing this signal
              sigData(sigCounter).BlockIndex = blkCounter;

    	     str = sprintf('DIVISION BY ZERO occurred %d time(s).',FixPtSimRanges{i}.DivisionByZeroOccurred);
             flag = 1;
             sig{sigCounter} = str;
             sigCounter = sigCounter + 1;
    	end

        % process min max info if any
       if isfield(FixPtSimRanges{i},'DataType')
          % store the index to the line in the block listbox that
          % corresponds to the block containing this signal

          sigData(sigCounter).BlockIndex = blkCounter;

         if flag
          blkCounter = blkCounter + 1;
          blk{blkCounter} = '';
          blockData(blkCounter).Path = blockData(blkCounter-1).Path;
          blockData(blkCounter).SigIndex = sigCounter - 1;
          flag = 0;
         end

         typev = FixPtSimRanges{i}.DataType;

          if strcmp(typev,'DblOv')

            isDoubleOverride = 1;
          else
            isDoubleOverride = 0;
          end

          if isDoubleOverride || strcmp(typev,'FixPt')

              bits = FixPtSimRanges{i}.MantBits;

              if bits >= 0
                  typev = sprintf('U%-3d',bits);
              else
                  typev = sprintf('S%-3d',-1*bits);
              end

              if isDoubleOverride

                  typev = ['FLT_' typev];
              end

              if isfield(FixPtSimRanges{i},'FixExp')

                  fixexp = FixPtSimRanges{i}.FixExp;
              else
                  fixexp = 0;
              end

              if isfield(FixPtSimRanges{i},'Slope')

                  slope  = FixPtSimRanges{i}.Slope;
              else
                  slope = 1;
              end

              if isfield(FixPtSimRanges{i},'Bias')

                  bias   = FixPtSimRanges{i}.Bias;
              else
                  bias = 0;
              end

              if  ( slope ~= 1 )
                 typev = sprintf('%s       V=Q*%g',typev,slope*(2^fixexp));
              elseif  ( fixexp ~= 0 )
                 typev = sprintf('%s       V=Q*2^%g',typev,fixexp);
              else
                 typev = sprintf('%s       V=Q',typev);
              end
              if ( bias > 0 )
                 typev = sprintf('%s+%g',typev,bias);
              elseif ( bias < 0 )
                 typev = sprintf('%s-%g',typev,-bias);
              end

              % add items for data type range
              if bits >= 0
                  dt_max = bias+slope*(2^fixexp)*(2^(bits  )-1);
                  dt_min = bias;
              else
                  dt_max = bias+slope*(2^fixexp)*(2^(-1-bits)-1);
                  dt_min = bias-slope*(2^fixexp)*(2^(-1-bits)  );
              end
              sdt_max = num2str(sprintf('%-6.4g',dt_max));
              sdt_min = num2str(sprintf('%-6.4g',dt_min));
              dt_range = dt_max-dt_min;

              % add items for percent range used
              used_max = ceil(100*((FixPtSimRanges{i}.MaxValue-bias)/(dt_max-bias)));
              if bits >= 0
                  used_min = 0;
              else
                  used_min = ceil(100*((FixPtSimRanges{i}.MinValue-bias)/(dt_min-bias)));
              end
              if used_max > used_min
                 s_used = num2str(sprintf('%4d%%',used_max));
              else
                 s_used = num2str(sprintf('%4d%%',used_min));
              end
          else

              if isfield(FixPtSimRanges{i},'ExpBits')
                % custom float
                expBits = FixPtSimRanges{i}.ExpBits;

                totBits = 1+FixPtSimRanges{i}.MantBits+expBits;

                typev = sprintf('%s_%d_%d',typev,totBits,expBits);
              end

              sdt_max    = '';
              sdt_min    = '';
              s_used = '';
          end

          if 1 % Improvements Not Yet Ready
              sdt_max    = '';
              sdt_min    = '';
              s_used = '';
          end

          vminv = FixPtSimRanges{i}.MinValue;
          minv = num2str(sprintf('%-6.4g',vminv));

          vmaxv = FixPtSimRanges{i}.MaxValue;
          maxv = num2str(sprintf('%-6.4g',vmaxv));

         % for percent of range used

         if vminv > vmaxv
             str = [sprintf('%-18s','Did Not Execute')...
                    sprintf('  %s  ',typev) ];
         elseif vminv == vmaxv
             str = [sprintf('%-9s ',minv)...
                    sprintf('%-9s ','Static')...
                    sprintf('%s',typev) ];
         elseif 1 % Improvements Not Yet Ready
             str = [sprintf('%-9s ',minv)...
                    sprintf('%-9s ',maxv)...
                    sprintf('%s',typev) ];
         else
             str = [sprintf('%-9s ',minv)...
                    sprintf('%-9s ',maxv)...
                    sprintf('%-9s ',sdt_min)...
                    sprintf('%-9s ',sdt_max)...
                    sprintf('%-5s ',s_used)...
                    sprintf('%s',typev) ];
         end
         sig{sigCounter} = str;

         sigCounter = sigCounter + 1;
       end
       blkCounter = blkCounter + 1;
    end
end

% set the list box contents data
hBlkListbox = findobj( hFixGui,'tag','blockname');
hSigListbox = findobj( hFixGui,'tag','signal');

% keep highlighting the same unless
% the sizes have shrunk below previous highlight.
% In that case, defaults of 1 will be used
blkIndex = get(hBlkListbox,'Value');
sigIndex = get(hSigListbox,'Value');

if ( blkIndex > length(blk) ) || ( sigIndex > length(sig) )
    blkIndex = 1;
    sigIndex = 1;
end

% If the string field for the list boxes is set to {},
% prior text is the list boxes is NOT being erased.
% As work around, set the string to {' '}, and then to {}
if isempty(blk)
  blk = ' ';
end
if isempty(sig)
  sig = ' ';
end

set(hBlkListbox,'string',blk,'Value',blkIndex);
set(hSigListbox,'string',sig,'Value',sigIndex);

% set the user data
figData.blockData = blockData;
figData.sigData   = sigData;

set( hFixGui, 'userdata', figData);

% set the logging and data type fields
hlogmnu = findobj( hFixGui,'tag','logmenu');
hlogtypemnu = findobj( hFixGui, 'tag', 'logtypemenu');
hdatamnu = findobj( hFixGui,'tag','doublemenu');
hActLogTxt = findobj(hFixGui, 'tag', 'editLoggingActual');
hActDataTxt = findobj(hFixGui, 'tag', 'editDTActual');

try
    cursysHandle = get_param(figData.fullPath, 'Handle');

    [actualLogSys,actualLogValue] = fxptdlgGetSysParam(cursysHandle,'MinMaxOverflowLogging');
    [actualDataSys,actualDataValue] = fxptdlgGetSysParam(cursysHandle,'DataTypeOverride');
    actualLogTypeValue = get_param(figData.system, 'MinMaxOverflowArchiveMode');
    
    logmnuind = getLogMenuIndex(actualLogValue);
    datamnuind = getDataMenuIndex(actualDataValue);
    logtypeind = getLogTypeMenuIndex(actualLogTypeValue);
    
    set(hlogmnu, 'value', logmnuind);
    set(hdatamnu, 'value', datamnuind);
    set(hlogtypemnu, 'value', logtypeind);
    
    if isequal(cursysHandle, actualLogSys)
        % Log settings are controlled by this system.
        set(hlogmnu, 'Enable' ,'on');
        set(hActLogTxt, 'Visible','off');
    else
        % Log settings are inherited from above.
        set(hlogmnu, 'Enable', 'off');
        parent = get_param(actualLogSys, 'Parent');
        name = get_param(actualLogSys, 'Name');
        if isempty(parent)
            path = name;
        else
            path = [parent, '/', name];
        end
        set(hActLogTxt, 'Visible', 'on', 'String', ['Controlled by: ', path]);
    end

    if isequal(cursysHandle, actualDataSys)
        % Data type override settings are controlled by this system.
        set(hdatamnu, 'Enable' ,'on');
        set(hActDataTxt, 'Visible','off');
    else
        % Log type override settings are inherited from above.
        set(hdatamnu, 'Enable' ,'off');
        parent = get_param(actualDataSys, 'Parent');
        name = get_param(actualDataSys, 'Name');
        if isempty(parent)
            path = name;
        else
            path = [parent, '/', name];
        end
        set(hActDataTxt, 'Visible', 'on', 'String', ['Controlled by: ', path]);
    end

catch
    errordlg('Unable to populate Datatype override and logging pulldowns.');
end

%resizegui(hFixGui);

%---------------------------------------------------------------------------------------
% This function gets the INFORMATION about signals that could be handled
% by the plotting GUI.  It does NOT get the actual DATA to be plotted.
%
% Plotable signals come from
%
%  1) Root level outports, provided SaveTime and SaveOutput are ON
%
%  2) Scopes that save as structure with time
%
%  3) Scopes that save as matrix
%
%  4) ToWorkspace that save as structure with time
%
% Other forms of Scope and ToWorkspace saving log signals but
% they are not guaranteed to have both the time and signal data
% need for a useful plot, so they are excluded.
%
%  This function UPDATES USERDATA
%
% Parameters:
%   hFixGui - The GUI handle
%---------------------------------------------------------------------------------------
function getPlotableSignalInfo( hFixGui )

% get the user data
figData = get( hFixGui, 'userdata');

system = figData.system;

% handle root level outports
%   only if both time and outputs have saving ON in workspace IO
rootOutputs = {};
rootTime    = {};

rootOutports = find_system(system,...
                               'BlockType','Outport',...
                               'Parent',system);

rootSaveForm = get_param(system,'saveformat');

if ~isempty(rootOutports) && ...
   strcmp( get_param(system,'SaveOutput'), 'on') && ...
   ( ...
     strcmp( rootSaveForm, 'StructureWithTime' ) || ...
     ( ...
        strcmp( rootSaveForm, 'Array' ) && ...
        strcmp( get_param(system,'SaveTime'), 'on') ...
     ) ...
   )

    rootTime = get_param(system,'TimeSaveName');

    str = get_param(system,'OutputSaveName');

    while ~isempty(str)

        [ curVar, str ] = strtok( str, ', ');

        if ~isempty(curVar)

            rootOutputs = { rootOutputs{:} curVar };
        end
    end
end

% handle scopes giving struct with time
scopeList1 = find_system(system,'LookUnderMasks','all',...
                               'BlockType','Scope',...
                               'SaveToWorkspace','on',...
                               'DataFormat','StructureWithTime');

% handle scopes giving matrix
scopeList2 = find_system(system,'LookUnderMasks','all',...
                               'BlockType','Scope',...
                               'SaveToWorkspace','on',...
                               'DataFormat','Array');

% handle ToWorkspace blocks
toWorkList1 = find_system(system,'LookUnderMasks','all',...
                                 'BlockType','ToWorkspace',...
                                 'SaveFormat','StructureWithTime');


% build up a list of blocks that are valid for plotting
plotableElements = { rootOutputs{:} scopeList1{:} scopeList2{:} toWorkList1{:} };

% build up plot info
n = length(plotableElements);

emptyPlotableSignalInfoStruct = struct('name',[],'type',[],'timeName',[]);

if n > 0
    figData.plotableSigInfo(1:n) = emptyPlotableSignalInfoStruct;
else
    figData.plotableSigInfo = [];
end

iplotData = 1;

for i = 1:length(rootOutputs)

    figData.plotableSigInfo(iplotData).name     = rootOutputs{i};

    if strcmp( rootSaveForm, 'Array')
        figData.plotableSigInfo(iplotData).type     = 'OutportMatrix';
        figData.plotableSigInfo(iplotData).timeName = rootTime;
    else
        figData.plotableSigInfo(iplotData).type     = 'OutportStructWithTime';
    end

    iplotData = iplotData + 1;
end

for i = 1:length(scopeList1)

    SCname = char( get_param( scopeList1{i}, 'SaveName'));

    figData.plotableSigInfo(iplotData).name     = SCname;
    figData.plotableSigInfo(iplotData).type     = 'ScopeStructWithTime';

    iplotData = iplotData + 1;
end

for i = 1:length(scopeList2)

    SCname = char( get_param( scopeList2{i}, 'SaveName'));

    figData.plotableSigInfo(iplotData).name     = SCname;
    figData.plotableSigInfo(iplotData).type     = 'ScopeMatrix';

    iplotData = iplotData + 1;
end

for i = 1:length(toWorkList1)

    SCname = char( get_param( toWorkList1{i}, 'VariableName'));

    figData.plotableSigInfo(iplotData).name     = SCname;
    figData.plotableSigInfo(iplotData).type     = 'ToWorkStructWithTime';

    iplotData = iplotData + 1;
end

% set the user data
set( hFixGui, 'userdata', figData);

%---------------------------------------------------------------------------------------
% This function gets the DATA for signals that can be handled
% by the plotting GUI.
%
% The data is stored as RAW or as DOUBLESOVERRIDE
%
% If a data is not available as expected, then an empty matrix is used for
% that signals data.
%
% This function UPDATES USERDATA
%
% Parameters:
%   hFixGui - The GUI handle
%   updateType - update type
%---------------------------------------------------------------------------------------
function storePlotData( hFixGui, UpdateType)

% get the user data
figData = get( hFixGui, 'userdata');

% build up plot data
n = length(figData.plotableSigInfo);

emptyPlotDataStruct = struct('time',[],'signals',[]);

if n > 0
    plotData(1:n) = emptyPlotDataStruct;
else
    plotData = [];
end

nonEmptyDataFound = 0;

for i = 1:n

    try
        switch figData.plotableSigInfo(i).type

        case 'OutportMatrix'

            rootTimeName   = figData.plotableSigInfo(i).timeName;
            rootOutputName = figData.plotableSigInfo(i).name;

            curData.time           = evalin('base',rootTimeName);
            curData.signals.values = evalin('base',rootOutputName);

        case {'ScopeStructWithTime', 'ToWorkStructWithTime', 'OutportStructWithTime'}

            sigStructName = figData.plotableSigInfo(i).name;

            sigStruct = evalin('base',sigStructName);

            curData.time    = sigStruct.time;
            curData.signals = sigStruct.signals;

        case 'ScopeMatrix'

            matName = figData.plotableSigInfo(i).name;

            mat = evalin('base', matName);

            curData.time              = mat(:,1);
            curData.signals.values    = mat(:,2:end);

        end

        plotData(i) = curData;
    catch
        plotData(i) = emptyPlotDataStruct;
    end
    
    if ~isempty(plotData(i).time)
      nonEmptyDataFound = 1;
    end
end

if nonEmptyDataFound
  % 
  % Protect against the empty case.  When autoscaling tool is executed
  % it puts the model in compiled mode and then terminates it.  This is
  % like an update diagram with at least one major difference.  It 
  % treats logged variables as if the simulation had run but for zero
  % time steps.  All the logged variables are replaced with empty
  % variables.  We don't want to replace prior data with empty data
  % in this case.
  %  
  % store the plot data in UserData
  if strcmpi( UpdateType, 'raw')
    figData.RawData = plotData;
  else
    figData.DblData = plotData;
  end

  set( hFixGui, 'userdata', figData);
end
  
%---------------------------------------------------------------------------------------
% Populates the subsystem pulldown
% Parameters:
%   object          the object to select (optional)
%   fig         this GUI handle
% Returns:
%   the current top level scope
%---------------------------------------------------------------------------------------
function scope = setScope (fig, varargin)
    persistent topObject;

    % initialize the return value
    scope = topObject;

    % get the figure's user data
    figData = get(fig, 'UserData');

    % get the optional parameter
    select = [];
    if (nargin == 2)
        select = varargin{1};
    end

    % get the scope menu
    scopeMenu = findobj(figData.FigHandle,'tag','subsysmenu');

    % define the figure title
    figTitle = 'Fixed-Point Settings';

    % flag as to whether there is a side effect
    sideEffect = 0;

    root = Simulink.Root;

    scopeIterator = root.down;

    % clear everything if there are no scopes
    if isempty(scopeIterator)
        % reset the title
        set(fig, 'Name', figTitle);

        % clear all the info from the uicontrol
        set(scopeMenu, 'UserData', [], 'Value', 1, 'String', ' ');

        % clear topObject
        topObject = [];
        return;
    end

    % ensure that topObject is set
    if isempty(topObject)
        topObject = scopeIterator;
    end

    % get the selection
    data = get(scopeMenu, 'UserData');
    value = get(scopeMenu, 'Value');
    strings = get(scopeMenu, 'String');

    if ~isempty(data)
        newObject = data.objects(value);
        if ~isempty(select)
            if (ischar(select) && strcmp(select, 'select'))
                % toggle expansion
                expanded = find(data.expanded == newObject);
                if (~isempty(expanded))
                    data.expanded(expanded) = [];
                else
                    data.expanded = [data.expanded newObject];
                end
            elseif ~select.isa('Simulink.Root')
                % select the argument
                newObject = select;
            end
        end
        if newObject ~= topObject
            topObject = newObject;
            sideEffect = 1;
        end
    else
        % first instance, expand models
        modelIterator = down(root);
        data.expanded = [];
        while ~isempty(modelIterator);
            data.expanded = [data.expanded modelIterator];
            modelIterator = right(modelIterator);
        end
        sideEffect = 1;
        if (~isempty(select) && ~ischar(select) && ~select.isa('Simulink.Root'))
            topObject = select;
        end
    end

    scopeIterator = up(topObject);
    rootSys = topObject.name;

    while (~isempty(scopeIterator) && scopeIterator ~= root)
        data.expanded = unique([data.expanded scopeIterator]);
        rootSys = scopeIterator.name;
        scopeIterator = up(scopeIterator);
    end

    scopeIterator = root.down;

    strings = {};
    data.objects = [];

    tab = 1;
    depth = 0;

    while (depth>=0)
        isHier = 0;
        if (scopeIterator.isa('Simulink.SubSystem') || (scopeIterator.isa('Simulink.BlockDiagram') && ~strcmp(scopeIterator.BlockDiagramType, 'library')))
            isHier = 1;
        
            % force load references by getting name
            refstoberesolved = scopeIterator.find('-isa', 'Simulink.Reference', '-depth', 1);
            for i=1:length(refstoberesolved)
                % extra check to open the real references that havent gotten
                % resolved yet.
                if (refstoberesolved(i).isa('Simulink.Reference'))
                    try
                        refstoberesolved(i).name;
                    catch
                    end;
                end;
            end;
            
            try
                name = scopeIterator.name;
                if (~isempty(name))
                    name(name==10) = ' ';
                    subSystems = scopeIterator.find('BlockType', 'SubSystem', '-depth', 1);
                    subSystems(subSystems==scopeIterator) = [];
                    if (isempty(subSystems))
                        data.expanded(data.expanded==scopeIterator) = [];
                        prefix = '  ';
                    else
                        if (find(data.expanded == scopeIterator))
                            prefix = '- ';
                        else
                            prefix = '+ ';
                        end
                    end
                    strings = [strings {[repmat(' ',1,depth*tab) prefix name]}];
                    data.objects = [data.objects scopeIterator];
                end
            catch
                % scopeIterator didn't have a name
            end
        end
        if (isHier & find(data.expanded == scopeIterator))
            depth = depth+1;
            scopeIterator = down(scopeIterator);
        else
            next = right(scopeIterator);
            while(isempty(next))
                depth = depth-1;
                scopeIterator = up(scopeIterator);
                if (scopeIterator == root)
                    next = root;
                else
                    next = right(scopeIterator);
                end
            end
            scopeIterator = next;
        end
    end

    % the index of the topObject
    value = find(data.objects==topObject);
    if isempty(value)
        if isempty(data.objects)
            topObject = [];
            rootSys = '';
        else
            topObject = data.objects(1);
            rootSys = topObject.name;
        end
        value = 1;
    end


    if isempty(topObject)
        fullpath = '';
    else
        if topObject.isa('Simulink.BlockDiagram')
            fullpath = topObject.name;
        else
            fullpath = topObject.getFullName;
        end
        % enhance the figure title
        figTitle =  [figTitle ' - ' fullpath];
    end

    % check for name change
    if (figData.handle == get_param(rootSys, 'handle')),
        figData.system = rootSys;
    end
    
    % update the model callbacks if the root system is different
    if ~strcmp(rootSys, figData.system)
        clearModelCallbacks(fig, figData.system);
        setModelCallbacks(fig, rootSys);
        figData.system = rootSys;
        figData.handle = get_param(rootSys, 'handle');
    end

    % update the fullpath
    figData.fullPath = fullpath;

    % reset the title and userdata
    set(fig, 'Name', figTitle, 'UserData', figData);

    % set all the info into the uicontrol
    set(scopeMenu, 'UserData', data, 'Value', value, 'String', strings, 'ToolTipString', fullpath);

    % return the topObject
    scope = topObject;


%---------------------------------------------------------------------------------------
% Gets the log menu index for the string passed in
% Parameters:
%   logmnu          the string to convert
% Returns:
%   the index
%---------------------------------------------------------------------------------------
function varargout = getLogMenuIndex(varargin)

ind = 1;

try
    switch varargin{1}
    case 'UseLocalSettings'
        ind = 1;
    case 'MinMaxAndOverflow'
        ind = 2;
    case 'OverflowOnly'
        ind = 3;
    case 'ForceOff'
        ind = 4;
    end
catch
    ind = 1;
end

varargout{1} = ind;


%---------------------------------------------------------------------------------------
% Gets the logging setting string for the log menu selection passed in
% Parameters:
%   varargin:  value of the log menu
% Returns:
%   the logging string to set on the model
%---------------------------------------------------------------------------------------
function varargout = getLogSetting(varargin)

str = '';

try
    switch varargin{1}
    case 1
        str = 'UseLocalSettings';
    case 2
        str = 'MinMaxAndOverflow';
    case 3
        str = 'OverflowOnly';
    case 4
        str = 'ForceOff';
    end
catch
    errordlg('Could not get Logging property string from pulldown.');
end

varargout{1} = str;

%---------------------------------------------------------------------------------------
% Gets the data menu index for the string passed in
% Parameters:
%   logmnu          the string to convert
% Returns:
%   the index
%---------------------------------------------------------------------------------------
function varargout = getDataMenuIndex(varargin)

ind = 1;

try
    switch varargin{1}
    case 'UseLocalSettings'
        ind = 1;
    case 'ScaledDoubles'
        ind = 2;
    case 'TrueDoubles'
        ind = 3;
    case 'TrueSingles'
        ind = 4;
    case 'ForceOff'
        ind = 5;
    end
catch
    ind = 1;
end

varargout{1} = ind;

%---------------------------------------------------------------------------------------
% Gets the datatype override setting string for the dt menu selection passed in
% Parameters:
%   varargin:  value of the dt menu
% Returns:
%   the dt override string to set on the model
%---------------------------------------------------------------------------------------
function varargout = getDTSetting(varargin)

str = '';

try
    switch varargin{1}
    case 1
        str = 'UseLocalSettings';
    case 2
        str = 'ScaledDoubles';
    case 3
        str = 'TrueDoubles';
    case 4
        str = 'TrueSingles';
    case 5
        str = 'ForceOff';
    end
catch
    errordlg('Could not get date type property string from pulldown.');
end

varargout{1} = str;

%---------------------------------------------------------------------------------------
% Gets the log type setting string for the logtypemenu selection passed in
% Parameters:
%   varargin:  value of the logtypemenu
% Returns:
%   the log type string to set on the model
%---------------------------------------------------------------------------------------
function varargout = getLogTypeSetting(varargin)
  
  str = '';
  
  try
    switch varargin{1}
     case 1
      str = 'Overwrite';
     case 2
      str = 'Merge';
    end
  catch
    errordlg('Could not get log type property string from pulldown.');
  end
  
  varargout{1} = str;

  
%---------------------------------------------------------------------------------------
% Gets the log type menu index for the string passed in
% Parameters:
%   logtypemnu          the string to convert
% Returns:
%   the index
%---------------------------------------------------------------------------------------
function varargout = getLogTypeMenuIndex(varargin)

  ind = 1;

  try
    switch varargin{1}
     case 'Overwrite'
      ind = 1;
     case 'Merge'
      ind = 2;
    end
  catch
    ind = 1;
  end

  varargout{1} = ind;  
  
%---------------------------------------------------------------------------------------
% Gets the actual settings for logging and data type override and the ssystem that
% controls it.
% Parameters:
% curSystem -    The current system
% paramNameStr - the param for which we want the value.
% Returns:
%   the dominant system and the param value
%---------------------------------------------------------------------------------------
function [dominantSystem,dominantParamValue] = fxptdlgGetSysParam(curSystem,paramNameStr)

switch paramNameStr
 case {'DataTypeOverride','MinMaxOverflowLogging'}
   % valid
 otherwise
  error('Unknown parameter name.');
end

curParamValue = get_param(curSystem,paramNameStr);

dominantSystem =   curSystem;
dominantParamValue = curParamValue;

curParent = get_param(curSystem,'parent');

while ~isempty(curParent)
  curSystem = curParent;
  curParamValue = get_param(curSystem,paramNameStr);

  if ~strcmp('UseLocalSettings',curParamValue)
    dominantSystem =   curSystem;
    dominantParamValue = curParamValue;
  end

  curParent = get_param(curSystem,'parent');
end

%---------------------------------------------------------------------------------------
% Set model callbacks.
% Parameters:
%   sysName         System to set.
%   hFixGui         this GUI handle
% Returns:
%   nothing
%---------------------------------------------------------------------------------------
function setModelCallbacks(hFixGui, sysName)

% get the figure's user data
figData = get(hFixGui, 'UserData');

% Find out what the callbacks are for SYSTEM.
for i=1:length(figData.Fcn.Names)

    tmpstr = get_param(sysName,figData.Fcn.Names{i});

    % Sometimes, Fixed-Point GUI callbacks are left behind in the model
    % due to crashes or other malfunctions! We go through and remove them
    % before adding new callbacks to the model.

    if ~isempty(tmpstr)
        figData.Fcn.Old{i} = regexprep(tmpstr,'fxptdlg\(.*?\);',' ');
    else
        figData.Fcn.Old{i} = tmpstr;
    end

end

try
    % Store the status of the Dirty property.
    % Then toggle it to 'Off' to avoid changing the user's system.
    DIRTY = get_param(sysName,'dirty');
    set_param(sysName,'dirty','Off')

    % Set SYSTEM's callback to call this GUI.
    % don't add the callback if it is already there
    for i=1:length(figData.Fcn.Names)

        if isempty( findstr( figData.Fcn.Old{i}, figData.Fcn.New{i} ) )

            set_param( sysName, figData.Fcn.Names{i}, ...
                [figData.Fcn.Old{i}, figData.Fcn.New{i}]);
        end
    end
catch
    error('Unable to set model callbacks used by the Fixed-Point GUI.');
end

% Then toggle Dirty property back to what it was.
set_param(sysName,'dirty',DIRTY)

set(hFixGui,'userdata',figData);

%---------------------------------------------------------------------------------------
% Clear model callbacks.
% Parameters:
%   sysName         System to clear.
%   hFixGui         this GUI handle
% Returns:
%   nothing
%---------------------------------------------------------------------------------------
function clearModelCallbacks(hFixGui, sysName)

% get the figure's user data
figData = get(hFixGui, 'UserData');

try
    % Store the status of the Dirty property.
    % Then toggle it to 'Off' to avoid changing the user's system.
    DIRTY = get_param(sysName,'dirty');
    set_param(sysName,'dirty','Off')

    for i=1:length(figData.Fcn.Names)

        set_param(sysName, figData.Fcn.Names{i}, figData.Fcn.Old{i} );
    end

    % Then toggle Dirty property back to what it was.
    set_param(sysName,'dirty',DIRTY)
catch
    error('Unable to clear model callbacks set by the Simulink Fixed Point GUI.');
end

set( hFixGui, 'userdata', figData);

%---------------------------------------------------------------------------------------
% Create plot structures.
%   hFixGui         this GUI handle
% Returns:
%   nothing
%---------------------------------------------------------------------------------------
function initializePlotStructures(hFixGui)

% get the figure's user data
figData = get(hFixGui, 'UserData');

% clear out plot info struct
figData.plotableSigInfo = struct('name',[],'type',[],'timeName',[]);

% initialize the plot data to be empty
figData.RawData = [];
figData.DblData = [];

set(hFixGui,'userdata',figData);

% get plotable signal info
% and store any already available data as 'RAW' for the new system
getPlotableSignalInfo( hFixGui );

storePlotData( hFixGui, 'raw');

%---------------------------------------------------------------------------------------
% Sets the buttons according the simulation status of the system.
%   hFixGui         this GUI handle
% Returns:
%   nothing
%---------------------------------------------------------------------------------------
function initializeMenuButtons(hFixGui)

% get the figure's user data
figData = get(hFixGui, 'UserData');

startbtn = figData.startBtn;
pausebtn = figData.pauseBtn;
stopbtn = figData.stopBtn;

if strcmpi(get_param(figData.system,'simulationstatus'),'running'),
    set(startbtn, 'enable','off');
    set(pausebtn, 'enable','on');
    set(stopbtn, 'enable', 'on');
elseif strcmpi(get_param(figData.system,'simulationstatus'),'paused'),
    set(startbtn, 'enable','on');
    set(pausebtn, 'enable','off');
    set(stopbtn, 'enable', 'on');
else %stopped
    set(startbtn, 'enable','on');
    set(pausebtn, 'enable','off');
    set(stopbtn, 'enable', 'off');
end

%---------------------------------------------------------------------------------------
% Gets the root system, parent path, full path and name of the handle passed in.
%   hdle         Handle or string containg the gcs.
% Returns:
%   rootSystem, parentPath, fullPath, name
%---------------------------------------------------------------------------------------
function [rootSystem, parentPath, fullPath, name] = getPathsFromHandle(hdle)

 parentPath = '';    % path to the parent of current system.
 rootSystem = '';    % top level block diagram
 fullPath = '';      % full path including current subsystem
 name   = '';

 % determine the parentPath and name.
 if isnumeric(hdle)
     parentPath = get_param(hdle,'Parent');
     name = get_param(hdle,'Name');
 else
     [t,r] = strtok(fliplr(hdle),'/');
     parentPath = fliplr(r);
     name = fliplr(t);
 end

 % We allow blocks to have '/' in their names. We need to escape the slash
 % so that the block opens right
 name = strrep(name,'/','//');
 
 % get the rootSystem
 if isempty(parentPath)
     rootSystem = name;
 else
     rootSystem = strtok(parentPath,'/');
 end

 % get the full path
 if isempty(parentPath)
     fullPath = name;
 else
     if strcmp(parentPath(length(parentPath)),'/')
         fullPath = [parentPath,name];
     else
         fullPath = [parentPath,'/',name];
     end
 end

%---------------------------------------------------------------------------------------
% Gets the next open system if any. Search excludes the current system.
%   currentSystem  system to exclude from the search.
% Returns:
%   name of valid open system or ''.
%---------------------------------------------------------------------------------------
function openSystem = findAnOpenSystem(currentSystem)

openSystem = '';

% Get a list of open systems
systems = find_system('Type','block_diagram');

for i = 1:length(systems)
    sys = systems{i};
    % Is this a valid system?
    if ~strcmpi(get_param(sys,'BlockDiagramType'),'library') && ~strcmp(currentSystem, sys)
        openSystem = sys;
        break;
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function restoreGlobalFixPtSimRanges()
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if any(strcmp('pre_autoscale_FixPtSimRanges',who('global')))
  
  global FixPtSimRanges
  global pre_autoscale_FixPtSimRanges
  FixPtSimRanges = pre_autoscale_FixPtSimRanges;
  clear global pre_autoscale_FixPtSimRanges
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% end restoreGlobalFixPtSimRanges()
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% END   fxptdlg.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
