function pan7partial(varargin)

% ========================================================================
% ===================== Panel for partial execution ======================
% ========================================================================
%
%  $Id: pan7partial.m,v 1.3 2008/08/30 12:27:08 nicola Exp $

scaleX = getappdata(0, 'ltpda_gui_scalefactor');
guiFontSize = round(8*scaleX);

alltimers = timerfindall;
stop(alltimers(2));
set(alltimers(2),'TimerFcn',@ContinuousCheck,'Period',1);
start(alltimers(2));

%%

currPanel   = varargin{1};
panelDimens = get(currPanel, 'Position');
backColor   = get(currPanel, 'BackgroundColor');

  % Current system:
  uicontrol('Parent',currPanel,'BackgroundColor',backColor,'HorizontalAlignment','left','Units','normalized','Position',[0.17 0.89 0.125 0.040],'String','Current system:','FontName','Times New Roman','FontSize',guiFontSize+4,'FontWeight','normal','Visible','on','Style','text');
    currsystem = bdroot;
    if isempty(currsystem) || isempty(find_system(currsystem,'FindAll','on','Type','Annotation','Tag','ltpda model')), currsystem = 'None'; end
  uicontrol('Parent',currPanel,'BackgroundColor',backColor,'HorizontalAlignment','left','Units','normalized','Position',[0.3 0.89 0.1875 0.040],'String',currsystem,'FontName','Times New Roman','FontSize',guiFontSize+4,'FontWeight','bold','Visible','on','UserData','currsystem','Style','text');

  % Current block:
  uicontrol('Parent',currPanel,'BackgroundColor',backColor,'HorizontalAlignment','left','Units','normalized','Position',[0.5 0.89 0.125 0.040],'String','Current block:','FontName','Times New Roman','FontSize',guiFontSize+4,'FontWeight','normal','Visible','on','Style','text');
  uicontrol('Parent',currPanel,'BackgroundColor',backColor,'HorizontalAlignment','left','Units','normalized','Position',[0.62 0.89 0.1875 0.040],'String','','FontName','Times New Roman','FontSize',guiFontSize+4,'FontWeight','bold','Visible','on','UserData','currblock','Style','text');


  % =======================================================================
    FirstPanPos   = [.0125 .56 .975 .26];
  hFirstPanel = uipanel('Parent',currPanel,'BackgroundColor',backColor,'FontSize',guiFontSize-1,'Units','normalized','Position',FirstPanPos);
    logosize = [53 55]*scaleX;
    icon1 = axes('Parent',hFirstPanel,'Units','normalized','Position',[.03 .45 0.3 0.3]);
    iconSize = getpixelposition(icon1); panelSize = getpixelposition(hFirstPanel); iconSize(3:4) = logosize; iconSize(2)= (panelSize(4)-iconSize(4))/2; setpixelposition(icon1,iconSize);
    image(imread('iconpar1.jpg'),'Parent',icon1,'Tag','partial1');
    axis(icon1,'off');
    clear logosize iconSize panelSize
    
    firstText = sprintf('Execution from the beginning to the current block.\n\nThis option is always possible: are executed only those blocks parent of the current one, and the execution is stopped as soon as the current one is reached.');
    uicontrol('Parent',hFirstPanel,'BackgroundColor',backColor,'Units','normalized','HorizontalAlignment','left','Position',[0.15 0.2 0.8 0.6],'String',firstText,'FontSize',guiFontSize,'Visible','on','Style','text','Tag','infotext1');
    
  % =======================================================================
    SecondPanPos   = [.0125 .29 .975 .26];
  hSecondPanel = uipanel('Parent',currPanel,'BackgroundColor',backColor,'FontSize',guiFontSize-1,'Units','normalized','Position',SecondPanPos);
    logosize = [53 55]*scaleX;
    icon2 = axes('Parent',hSecondPanel,'Units','normalized','Position',[.03 .45 0.3 0.3]);
    iconSize = getpixelposition(icon2); panelSize = getpixelposition(hFirstPanel); iconSize(3:4) = logosize; iconSize(2)= (panelSize(4)-iconSize(4))/2; setpixelposition(icon2,iconSize);
    image(imread('iconpar2.jpg'),'Parent',icon2,'Tag','partial2');
    axis(icon2,'off');
    clear logosize iconSize panelSize
    
    secondText = sprintf('Execution of the current block only.\n\nThis option is possible only if all the inputs necessary to the currently selected block are available; this means that the model must have already been executed and either all intermediate results are maintained, or just those necessary to the current block.');
    uicontrol('Parent',hSecondPanel,'BackgroundColor',backColor,'Units','normalized','HorizontalAlignment','left','Position',[0.15 0.2 0.8 0.6],'String',secondText,'FontSize',guiFontSize,'Visible','on','Style','text','Tag','infotext2');

  % =======================================================================
    ThirdPanPos   = [.0125 .02 .975 .26];
  hThirdPanel = uipanel('Parent',currPanel,'BackgroundColor',backColor,'FontSize',guiFontSize-1,'Units','normalized','Position',ThirdPanPos);
    logosize = [53 55]*scaleX;
    icon3 = axes('Parent',hThirdPanel,'Units','normalized','Position',[.03 .45 0.3 0.3]);
    iconSize = getpixelposition(icon3); panelSize = getpixelposition(hFirstPanel); iconSize(3:4) = logosize; iconSize(2)= (panelSize(4)-iconSize(4))/2; setpixelposition(icon3,iconSize);
    image(imread('iconpar3.jpg'),'Parent',icon3,'Tag','partial3');
    axis(icon3,'off');
    clear logosize iconSize panelSize
    
    thirdText = sprintf('Execution from the current block to the end.\n\nThis option is possible only if all the inputs necessary to the currently selected block are available; this means that the model must have already been executed and either all intermediate results are maintained, or just those necessary to the current block.\nAfter the current block the execution continues, updating all the following blocks');
    uicontrol('Parent',hThirdPanel,'BackgroundColor',backColor,'Units','normalized','HorizontalAlignment','left','Position',[0.15 0.2 0.8 0.6],'String',thirdText,'FontSize',guiFontSize,'Visible','on','Style','text','Tag','infotext3');


    UpdatePanel(1);



%%
    %----------------------------------------------------------------------
    function ContinuousCheck(varargin)   
        % This is the function to execute a continuous timer check
        
       % Keep alive the first timer:
         alltimers = timerfindall;
         if strcmp(get(alltimers(1),'Running'),'off')
             start(alltimers(1))
         end

         currsys   = bdroot;
         oldsys    = get(findobj('UserData', 'currsystem'), 'String');
         currselection = utils.prog.gcbsh;
         if numel(currselection)>1, UpdatePanel(1); return; end
         if isempty(currsys) || isempty(currselection), UpdatePanel(1); return; end
         currblock = get_param(currselection,'Name');
         oldblock  = get(findobj('UserData', 'currblock'), 'String');
         if strcmp(currsys,oldsys) && strcmp(currblock,oldblock), return; end
         
         if ~isempty(currsys) && ~isempty(find_system(currsys,'FindAll','on','Type','Annotation','Tag','ltpda model'))
            currchild = find_system(currselection,'LookUnderMasks','all','BlockType','M-S-Function');
            if isempty(currchild) || ~strcmp(get_param(currchild,'FunctionName'),'ltpdasim')
             % disp('*** The model is valid, but the selected block is not an LTPDA function block.')
               UpdatePanel(2)
               return;
            else
               annotation  = find_system(bdroot,'FindAll','on','Type','Annotation','Tag','ltpda model');
               execHistory = get_param(annotation,'UserData');
               if isempty(execHistory)
                % disp('*** The model is valid, but has never been run.')
                  UpdatePanel(3)
                  return;
               else
                  blockIndex = -1;
                  for i=1:size(execHistory,1), if execHistory{i,2}==currselection, blockIndex=i; break; end; end
                  if blockIndex==-1 % the current block is not included in the execution history
                   % disp('*** The model is valid, but the selected block is not included in the execution history.')
                     UpdatePanel(3)
                     return;
                  end
                  for i=3:size(execHistory,2)
                     if execHistory{blockIndex,i}==-1 % one of the necessary input has been deleted
                      % disp('*** The model and the selected block are valid, but at least one necessary input has been deleted.')
                        UpdatePanel(3)
                        return;
                     end
                  end
                % disp('*** The model and the selected block are valid, all necessary inputs available.')
                  UpdatePanel(4)
               end
            end
         else
          % disp('*** The model is not valid.')
            UpdatePanel(1)
         end
         
    end
    %----------------------------------------------------------------------

    %----------------------------------------------------------------------
    function UpdatePanel(varargin)
       % varargin{1}= 1 if all disabled (not a valid ltpda model or ltpda
       %                                 block)
       %              2 if the model is valid but the block is not.
       %              3 if the model and the block are valid, but the block
       %                lacks the necessary inputs.
       %              4 model and block valid, all necessary inputs present.

       switch varargin{1}
          case 1
             set(findobj('UserData', 'currsystem'), 'String', 'None')
             set(findobj('UserData', 'currblock'), 'String', '---')
             set(findobj('Tag','partial1'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','partial2'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','partial3'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','infotext1'),'ForegroundColor',[.8 .8 .8]);
             set(findobj('Tag','infotext2'),'ForegroundColor',[.8 .8 .8]);
             set(findobj('Tag','infotext3'),'ForegroundColor',[.8 .8 .8]);
          case 2
             set(findobj('UserData', 'currsystem'), 'String', bdroot)
             set(findobj('UserData', 'currblock'), 'String', 'Not valid')
             set(findobj('Tag','partial1'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','partial2'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','partial3'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','infotext1'),'ForegroundColor',[.8 .8 .8]);
             set(findobj('Tag','infotext2'),'ForegroundColor',[.8 .8 .8]);
             set(findobj('Tag','infotext3'),'ForegroundColor',[.8 .8 .8]);
          case 3
             set(findobj('UserData', 'currsystem'), 'String', bdroot)
             set(findobj('UserData', 'currblock'), 'String', get_param(gcbh,'Name'))
             set(findobj('Tag','partial1'),'CData',imread('iconpar1.jpg'),'ButtonDownFcn',@Run1);
             set(findobj('Tag','partial2'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','partial3'),'CData',imread('iconpar4.jpg'),'ButtonDownFcn','');
             set(findobj('Tag','infotext1'),'ForegroundColor',[0 0 0]);
             set(findobj('Tag','infotext2'),'ForegroundColor',[.8 .8 .8]);
             set(findobj('Tag','infotext3'),'ForegroundColor',[.8 .8 .8]);
          case 4
             set(findobj('UserData', 'currsystem'), 'String', bdroot)
             set(findobj('UserData', 'currblock'), 'String', get_param(gcbh,'Name'))
             set(findobj('Tag','partial1'),'CData',imread('iconpar1.jpg'),'ButtonDownFcn',@Run1);
             set(findobj('Tag','partial2'),'CData',imread('iconpar2.jpg'),'ButtonDownFcn',@Run2);
             set(findobj('Tag','partial3'),'CData',imread('iconpar3.jpg'),'ButtonDownFcn',@Run3);
             set(findobj('Tag','infotext1'),'ForegroundColor',[0 0 0]);
             set(findobj('Tag','infotext2'),'ForegroundColor',[0 0 0]);
             set(findobj('Tag','infotext3'),'ForegroundColor',[0 0 0]);
       end

    end
    %----------------------------------------------------------------------

    %----------------------------------------------------------------------
    function Run1(varargin)
     % Execution from the beginning to the current block
       
     % To find all parents, up to the beginning of the model:
       parentsBlock = unique(utils.prog.findparent(gcbh));
       parentsBlock = [parentsBlock ; find_system(gcbh,'LookUnderMasks','all','BlockType','M-S-Function');];
       
       assignin('base','executionList',parentsBlock);
       ltpdagui('redraw',1.1);
     
    end
    %----------------------------------------------------------------------

    %----------------------------------------------------------------------
    function Run2(varargin)
     % Execution of the current block only
       
       assignin('base','executionList',find_system(gcbh,'LookUnderMasks','all','BlockType','M-S-Function') );
       ltpdagui('redraw',1.1);
       
    end
    %----------------------------------------------------------------------

    %----------------------------------------------------------------------
    function Run3(varargin)
     % Execution from the current block to the end
       
     % To find all children, up to the end of the model:
       childrenBlock = unique(utils.prog.findchildren(gcbh));
       childrenBlock(:,2) = 0;
       while min(childrenBlock(:,2))==0
          for i=1:size(childrenBlock,1)
             if childrenBlock(i,2)==0
                nextGenerationChildren = utils.prog.findchildren(childrenBlock(i,1));
                nextGenerationChildren(:,2) = 0;
                if nextGenerationChildren(1,1)~=0
                   childrenBlock = [childrenBlock ; nextGenerationChildren];
                end
                childrenBlock(i,2) = 1;
             end
          end
          childrenBlock = unique(childrenBlock,'rows');
       end
       childrenBlock(:,2)=[];
       childrenBlock = [gcbh ; childrenBlock];
       
       assignin('base','executionList',childrenBlock);
       ltpdagui('redraw',1.1);

    end
    %----------------------------------------------------------------------

end
