function sel = select(xHeader,varargin);
%SELECT   Creates a modal dialog window with choices for user selection.
%   CHOICE = SELECT(HEADER, ITEM1, ITEM2, ... ) displays the HEADER
%   string followed in order by buttons entitled: ITEM1, ITEM2,
%   ... ITEMn. Returns the number of the selected button in CHOICE as
%   a scalar value. 
%   There is practically no limit to the number of buttons.
%
%   CHOICE = SELECT(HEADER, ITEMLIST) where ITEMLIST is a string cell
%   array is also a valid syntax. In this case, the return is an index
%   into the xcItems of the cell array.

%   Modeled after menu.m  12/'00
%   Fixes positioning bug, improves layout, 
%   and establishes adcp lab 'look and feel'.



% Check input
%-------------------------------------------------------------------------
if nargin < 2,
   msgbox('Select?  No items to chose from.')
   sel = 0;
   return;
elseif nargin==2 & iscell(varargin{1}),
   xcItems = varargin{1}; % a cell array was passed in
else,
   xcItems = varargin;    % use the varargin cell array
end


% Set spacing and sizing parameters for the GUI elements
%-------------------------------------------------------------------------
MenuUnits   = 'points'; % units used for all HG objects
textPadding = [18 8];   % extra [Width Height] on uicontrols to pad text
uiGap       = 5;        % space between uicontrols
uiBorder    = 5;        % space between edge of figure and any uicontol
winTopGap   = 50;       % gap between top of screen and top of figure **
winLeftGap  = 15;       % gap between side of screen and side of figure **


% Calculate the number of items in the menu
%-------------------------------------------------------------------------
numItems = length( xcItems );


% Create a generically-sized invisible figure window
%------------------------------------------------------------------------
drawnow;
menuFig = figure( ...
   'Units'       ,MenuUnits, ...
   'Visible'     ,'off', ...
   'NumberTitle' ,'off', ...
   'MenuBar'     ,'none', ...
   'Name'        ,'SELECT', ...
   'Resize'      ,'off', ...
   'Colormap'    , [] , ...
   'Color'       , [.92 .92 .97]);


% Add generically-sized header text with same background color as figure
%------------------------------------------------------------------------
hText = uicontrol( ...
   'style'       ,'text', ...
   'string'      ,xHeader, ...
   'units'       ,MenuUnits, ...
   'FontWeight'  ,'normal', ...
   'FontSize'    , 13     , ...
   'Position'    ,[ 100 100 100 20 ], ...
   'Horizontal'  ,'center',...
   'BackGround'  ,get(menuFig,'Color') );

maxsize = get( hText, 'Extent' );
textWide  = max(maxsize(3), 80);
textHigh  = maxsize(4);


% Add generically-spaced buttons below the header text
%------------------------------------------------------------------------
% Loop to add buttons in reverse order (to automatically initialize numitems).
% Note that buttons may overlap, but are placed in correct position relative
% to each other. They will be resized and spaced evenly later.

for idx = numItems : -1 : 1; % start from top of screen and go down
   n = numItems - idx + 1;  % start from 1st button and go to last
   hBtn(n) = uicontrol( ...
      'units'          ,MenuUnits, ...
      'BackgroundColor',[.87 .8 .8], ...
      'position'       ,[uiBorder uiGap*idx textHigh textWide], ...
      'callback'       ,['set(gcf,''userdata'',',int2str(n),')'], ...
      'string'         ,xcItems{n} );
end 


% Calculate Optimal UIcontrol dimensions based on max text size
%------------------------------------------------------------------------
cAllExtents = get( hBtn, {'Extent'} );  % put all data in a cell array
AllExtents  = cat( 1, cAllExtents{:} ); % convert to an n x 3 matrix
maxsize     = max( AllExtents(:,3:4) ); % calculate the largest width & height
maxsize     = maxsize + textPadding;    % add some blank space around text
btnHigh     = maxsize(2);
btnWide     = maxsize(1);


% Retrieve screen dimensions (in correct units)
%------------------------------------------------------------------------
oldUnits = get(0,'Units');         % remember old units
set( 0, 'Units', MenuUnits );      % convert to desired units
screensize = get(0,'ScreenSize');  % record screensize



% Determine how many rows and columns of buttons will fit in the screen.
% Note: vertical space for buttons is the critical dimension
%------------------------------------------------------------------------
openSpace = screensize(4) - winTopGap - 2*uiBorder - textHigh;
numRows = min( floor( openSpace/(btnHigh + uiGap) ), numItems );
if numRows == 0; numRows = 1; end % Trivial case--but very safe to do
numCols = ceil( numItems/numRows );


% Calculate the window size needed to display all buttons
%------------------------------------------------------------------------
winHigh = numRows*(btnHigh + uiGap) + textHigh + 2*uiBorder;
winWide = numCols*(btnWide) + (numCols - 1)*uiGap + 2*uiBorder;

if winWide < (2*uiBorder + textWide),   % Make sure the text header fits
   winWide = 2*uiBorder + textWide;
end

% Determine final placement coordinates for left edge & bottom of fig. window
%------------------------------------------------------------------------
leftside = screensize(3)/2 - winWide/2;               % Centered
bottom = screensize(4)/2 - (winHigh + winTopGap)/2;   % Centered

set( menuFig, 'Position', [leftside bottom winWide winHigh] );

% Size uicontrols to fit everyone in the window and see all text
%------------------------------------------------------------------------
% Calculate coordinates of bottom-left corner of all buttons
xPos = ( uiBorder + [0:numCols-1]'*( btnWide + uiGap )*ones(1,numRows) )';
xPos = xPos(1:numItems); % [ all 1st col; all 2nd col; ...; all nth col ]
yPos = ( uiBorder + [numRows-1:-1:0]'*( btnHigh + uiGap )*ones(1,numCols) );
yPos = yPos(1:numItems); % [ rows 1:m; rows 1:m; ...; rows 1:m ]

% Combine with desired button size to get a cell array of position vectors
allBtn   = ones(numItems,1);
uiPosMtx = [ xPos(:), yPos(:), btnWide*allBtn, btnHigh*allBtn ];
cUIPos   = num2cell( uiPosMtx( 1:numItems, : ), 2 );

% adjust all buttons
set( hBtn, {'Position'}, cUIPos );

% Align the Text and Buttons horizontally and distribute them vertically
%------------------------------------------------------------------------
% Calculate placement position of the Header
textWide = winWide - 2*uiBorder;

% Move Header text into correct position near the top of figure
set( hText, ...
     'Position', [ uiBorder winHigh-uiBorder-textHigh textWide textHigh ] );

% ACTIVATE
%------------------------------------------------------------------------
% Make figure visible
set( menuFig, 'Visible', 'on' );
drawnow;

% Wait for choice to be made (i.e UserData must be assigned)...
waitfor(gcf,'userdata')

% ...selection has been made. Assign to 'sel' and delete the Menu figure
sel = get(gcf,'userdata');
delete(menuFig);

set( 0, 'Units',  oldUnits );      % convert back to old units


