%HANDELSELECT   Handle selection dialog box.
%   HANDLE = HANDLESELECT(PROMPTSTRING,CURRFIG,SELECTION,TAG)
%   creates a modal dialog box which allows you to select one or more
%   image display handles from a list.
%
%   HANDLE is the selected display handles, and will be '' if the user
%   pressed "Cancel", or [] if the user pressed "none". So the test
%   ISCHAR(HANDLE) determines if the user pressed cancel.
%
%   PROMPTSTRING is a string which appears as the text above the
%   list box.
%
%   CURRFIG is a figure handle to the current figure handle. It won't be
%   in the list.
%
%   SELECTION is the list of handles that should initially be selected.
%   Can be [], in which case the topmost handle one will be selected.
%
%   TAG is a string or a cell array with strings passed on to HANDLELIST,
%   to define which figure windows to display.
%
%   Double-clicking on an item has the same effect as clicking the
%   OK button.

% (C) Copyright 1999-2005               Pattern Recognition Group
%     All rights reserved               Faculty of Applied Physics
%                                       Delft University of Technology
%                                       Lorentzweg 1
%                                       2628 CJ Delft
%                                       The Netherlands
%
% Bernd Rieger, July 2001.
% Based on imageselect.m and dipimage case 'handle'
% 16-26 August 2001 (CL): Changed DIPSHOW. This function changes accordingly.
% 15 September 2001 (CL): Added keyboard callback.
% 18 September 2001 (CL): Fixed bug for MATLAB 6: 'CurrentCharacter' is []
%                         after pressing shift key.
% 30 September 2001 (CL): Substituted some common code with a call to HANDLELIST.
% 2 February 2005 (CL):   Added TAG parameter "officialy", added SELECTION parameter
%                         a button to disselect all.

function handle = handleselect(promptstring,currfig,selection,tag)

if nargin < 4
   tag = '';
if nargin < 3
   selection = [];
if nargin < 2
   error('Invalid input.');
end,end,end
listbox = 1;

% Get list of defined handles
[figh,liststring] = handlelist(tag);
if ~isempty(figh)
   %remove current figure from list to show
   I = find(figh==currfig);
   if ~isempty(I)
      figh(I) = [];
      liststring(I) = [];
   end
end
if isempty(figh)
   listbox = 0;
else
   value = [];
   for ii=1:length(selection)
      I = find(figh==selection(ii));
      if ~isempty(I)
         value = [value,I];
      end
   end
   if isempty(value)
      value = 1;
   end
end

errormsg = '(no relevant figure windows found)';

% Create dialog box
fig = figure('name','DIPimage dialog', ...
             'units','pixels', ...
             'resize','off', ...
             'numbertitle','off', ...
             'KeyPressFcn',['DIP_Image_DLG_ch = double(get(gcbf,''CurrentCharacter''));',...
                            'if ~isempty(DIP_Image_DLG_ch),switch DIP_Image_DLG_ch,',...
                            'case 13,set(gcbf,''userdata'',''ok'');',...
                            'case 27,set(gcbf,''userdata'',''cancel'');',...
                            'end,end;clear DIP_Image_DLG_ch'],...
             'createfcn','', ...
             'closerequestfcn','set(gcbf,''userdata'',''cancel'')', ...
             'color',get(0,'defaultuicontrolbackgroundcolor'), ...
             'windowstyle','modal', ...
             'visible','off');

% These quantities are copied from DIPIMAGE:
leftmargin = 20;          % Space between left edge and controls
internalmargin = 10;      % Horizontal space between controls
rightmargin = 20;         % Space between right edge and controls
topmargin = 10;           % Space between top edge and controls
bottommargin = 10;        % Space between bottom edge and controls
vspacing = 6;             % Space between rows
vslack = 4;               % Extra space allotted to controls (around text)
hslack = 10;              % Extra space allotted to controls (around text)
mindlgsize = [300,200];

% Calculate sizes of uicontrol elements
h = uicontrol(fig,'Style','text','String','Select All','Visible','off');
extent = get(h,'Extent');
controlwidth = extent(3)+hslack;
textheight = extent(4);
controlheight = textheight+vslack;
set(h,'String',promptstring);
extent = get(h,'Extent');
listwidth = max(extent(3),3*controlwidth+2*internalmargin);
if listbox
   % Calculate size for list box
   maxlistheight = 100;
   set(h,'String',liststring);
   extent = get(h,'Extent');
   listwidth = max(listwidth,extent(3))+hslack;
   listheight = min(extent(4)+2*vslack,maxlistheight);
else
   % Calculate size for message
   set(h,'String',errormsg);
   extent = get(h,'Extent');
   listwidth = max(listwidth,extent(3));
   listheight = extent(4); % same as textheight
end
listwidth = max(2*controlwidth+internalmargin,listwidth);
listwidth = max(mindlgsize(1)-leftmargin-rightmargin,listwidth);
dlgheight = topmargin+textheight+2*vspacing+controlheight+bottommargin;
listheight = max(mindlgsize(2)-dlgheight,listheight);
dlgheight = dlgheight+listheight;
dlgwidth = leftmargin+rightmargin+listwidth;
delete(h);

% Position dialog
fp = get(fig,'position');
fp = [fp(1) fp(2)+fp(4)-dlgheight dlgwidth dlgheight];  % keep upper left corner fixed
set(fig,'position',fp);

% Create controls
uicontrol(fig,'style','text','string',promptstring,...
          'horizontalalignment','left','units','pixels',...
          'position',[leftmargin,fp(4)-topmargin-textheight,...
                      listwidth,controlheight]);
uicontrol(fig,'style','pushbutton','string','None',...
          'position',[fp(3)-rightmargin-3*controlwidth-2*internalmargin,...
                      bottommargin,controlwidth,controlheight],...
          'callback','set(gcbf,''userdata'',''none'')');
uicontrol(fig,'style','pushbutton','string','Cancel',...
          'position',[fp(3)-rightmargin-2*controlwidth-internalmargin,...
                      bottommargin,controlwidth,controlheight],...
          'callback','set(gcbf,''userdata'',''cancel'')');
okbutton = uicontrol(fig,'style','pushbutton','string','OK','Enable','off',...
          'position',[fp(3)-rightmargin-controlwidth,bottommargin,...
                      controlwidth,controlheight],...
          'callback','set(gcbf,''userdata'',''ok'')');
if listbox
   listbox = uicontrol(fig,'style','listbox','string',liststring,...
             'backgroundcolor','w','max',2,'value',value,...
             'position',[leftmargin,...
                         fp(4)-topmargin-textheight-vspacing-listheight,...
                         listwidth,listheight],...
             'callback',['if(strcmp(get(gcbf,''SelectionType''),''open'')),',...
                         'set(gcbf,''userdata'',''ok''),end']);
   set(okbutton,'Enable','on');
else
   uicontrol(fig,'style','text','string',errormsg,...
             'horizontalalignment','center','units','pixels',...
             'position',[leftmargin,...
                         fp(4)-topmargin-textheight-vspacing-textheight-...
                         (listheight-textheight)/2,listwidth,textheight]);
end

% RUN!
set(fig,'visible','on');
waitfor(fig,'userdata')
switch get(fig,'userdata')
   case 'ok'
      handle = figh(get(listbox,'value'));
   case 'none'
      handle = [];
   otherwise % 'cancel'
      handle = '';
end
delete(fig)
