function [stop, reason] = stopifclosedfigure(problem, x, info, last) %#ok<INUSL>
% Create an interactive stopping criterion based on a figure closing
%
% function stopfun = stopifclosedfigure()
%
% Use on the options structure passed to a Manopt solver, e.g.:
%
%   problem = ... % manopt problem structure with manifold, cost function, ...
%   options.stopfun = @stopifclosedfigure; % add this option
%   trustregions(problem, x0, options); % run this or any other solver
%
% This will create a figure. If this figure is closed at any time during
% the solver's execution, the solver will terminate gracefully and return
% its current iterate as soon as it gets to the point of evaluating the
% stopping criteria.
%
% Note: certain solvers (including trustregions) check stopping criteria
% only at outer iterations, not during inner iterations; hence, there may
% be a delay before actual termination.
%
% See also: statsfunhelper stopifdeletedfile

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Aug. 3, 2018.
% Contributors: 
% Change log: 

    reason = 'Interactive stopping criterion: figure closed.';

    % Fix a likely unique figure id.
    figureid = 1465489213;
    
    % If first iteration, create a figure to capture interaction.
    if last == 1
        h = figure(figureid);
        set(h, 'Name', 'Close to stop Manopt solver', 'NumberTitle', 'off');
        text(0, 0, 'Close me to stop the Manopt solver.', 'FontSize', 16);
        axis tight;
        axis off;
        set(h, 'color', 'w');
        drawnow();
    end
    
    % Call to drawnow() ensures that, if the user closed the figure, then
    % that information will have been refreshed. This may create small
    % delays, but on the other hand interactive stopping criteria are
    % mostly useful for costly problems where this overhead should be
    % marginal.
    drawnow();
    if ~ishandle(figureid)      % If the figure was closed, stop.
        stop = true;
    else
        stop = false;
    end

end
