function fig_handle = cpsarimshow(u0,varargin)
%%
% Usage: fig_handle = cpsarimshow(u0,Name,Value)
%
% cpsarimshow can be used to display the modulus (or square modulus) of a
% SAR image into a Matlab Figure, with tight borders AND without any
% interpolation (one pixel of the screen = one pixel of the image), which
% is unfortunately not the case of imshow.
%
%   u0          : (matrix of real double) input image (e.g., modulus of a
%                 complex image)
%   fig_handle  : (figure handle) figure handle of the Matlab Figure used
%                 for display
%
% Optional Name-Value pair arguments:
%
%   'Name' name        : (string) set window title = name
%   'saturation' q     : (scalar real number in [0,100]) saturate a ratio
%                        of 'q' percents pixels with maximal values
%   'showsaturation' s : (scalar logical, default s=false) draw in red the
%                        saturated pixels
%

%% License & copyright
%
% Copyright (C) 2017, Rémy Abergel (Remy.Abergel AT parisdescartes.fr), Loïc
% Denis (Loic.Denis AT univ-st-etienne.fr), Saïd Ladjal (Said.Ladjal AT
% telecom-paristech.fr) and Florence Tupin (Florence.Tupin AT
% telecom-paristech.fr).
%
% GNU GPL License, see <http://www.gnu.org/licenses/>.

%% usage displayer
function display_usage()
    fprintf('\n Usage: fig_handle = cpsarimshow(u0,Name,Value)\n\n');
    fprintf(' cpsarimshow can be used to display the modulus (or square modulus) of a\n');
    fprintf(' SAR image into a Matlab Figure, with tight borders AND without any\n');
    fprintf(' interpolation (one pixel of the screen = one pixel of the image), which\n');
	fprintf(' is unfortunately not the case of imshow.\n\n');
    fprintf('   u0          : (matrix of real double) input image (e.g., modulus of a\n');
    fprintf('                 complex image)\n');
    fprintf('   fig_handle  : (figure handle) figure handle of the Matlab Figure used\n');
    fprintf('                 for display\n\n');
	fprintf(' Optional Name-Value pair arguments:\n\n');
	fprintf('   ''Name'' name    : (string) set window title = name\n');
	fprintf('   ''saturation'' q : (scalar real number in [0,100]) saturate a ratio of\n');
	fprintf('                    ''q'' percents pixels with maximal values\n\n');
end
%% keyboard event handler function (callback function)
function callback_keyboard_pressed(fig_hdl,evt)
    if strcmp(evt.Key,'q') % stop process & quit
        close(fig_hdl);
    end
end
%% parser (consistency checks are done after, to allow precise error messages)
p = inputParser;
p.addRequired('u0');
p.addParameter('Name','');
p.addParameter('saturation',0);
p.addParameter('showsaturation',false);
parse(p,u0,varargin{:});
name = p.Results.Name;
q = p.Results.saturation;
s = p.Results.showsaturation;
%% consistency checks
if(~ismatrix(u0) || isscalar(u0) || ~isreal(u0))
  display_usage();
  error('CPSAR_TOOLBOX:cpsarimshow:badinputdatatype','input image u0 must be a (non-scalar) matrix of real numbers\nif u0 is complex-valued, you can visualize its modulus using cpsarimshow(abs(u0))');
end
if(~isscalar(q) || ~isreal(q) || q < 0 || q > 100)
  display_usage();
  error('CPSAR_TOOLBOX:cpsarimshow:badinputdatatype','input ''q'' must be a real number in [0,100]');
end
if(~isscalar(s) || ~islogical(s))
  display_usage();
  error('CPSAR_TOOLBOX:cpsarimshow:badinputdatatype','input ''s'' must be a scalar logical (s=true or s=false)');
end
%% Main
gr = groot();
u0 = double(u0);
[ny,nx] = size(u0);
cmap = gray(256);
if(q > 0)
    u0_sorted = sort(u0(:));
    id = round(0.01*(100-q)*nx*ny);
    id = max(0,min(id,nx*ny-1));
    thresh = u0_sorted(1+id);
    u0(u0>thresh) = thresh;
    if(s)
        cmap(end+1,:) = [1,0,0];
    end
end
image(u0,'CDataMapping','scaled','XData',0:nx-1,'YData',0:ny-1);
axis 'image';
fig_handle = gcf();
set(fig_handle,'Name',name,'Colormap',cmap,'KeyPressFcn',@callback_keyboard_pressed);
set(gca(),'XLim',[0,nx-1],'YLim',[0,ny-1],'Visible','off','Units','pixels','ActivePositionProperty','position','Position',[1,1,nx,ny]);
pos = get(fig_handle,'Position');
pos(1:2) = [min(100,gr.ScreenSize(3)-nx),min(gr.ScreenSize(4)-ny-100,gr.ScreenSize(4)-ny)];
set(fig_handle,'Position',pos);
set(fig_handle,'Visible','on');
pause(1e-6);
pos(3:4) = [nx,ny];
set(fig_handle,'Position',pos);

end
