function [val, dlgShown]=uigetpref(prefGroup, prefPref, dlgTitle, dlgQuestion,prefOptions, varargin)
%UIGETPREF question dialog box with preference support
%  VALUE=UIGETPREF(GROUP, PREF, TITLE, QUESTION, PREF_CHOICES)
%  Returns one of the strings in PREF_CHOICES, either by prompting the user with
%  a multiple-choice question dialog box, or by returning a previous answer
%  stored in the preferences database.  By default, the dialog box is shown each
%  time, with each choice on a different pushbutton, and with a checkbox controlling
%  whether the returned value should be stored in preferences and automatically reused
%  in subsequent invocations.  When the user clicks the checkbox before choosing one
%  of the pushbuttons, the pushbutton choice is stored in preferences and returned.
%  Subsequent calls to UIGETPREF detect that the last choice was stored in preferences,
%  and return that choice immediately without displaying the dialog.  If the user does
%  not click the checkbox before choosing a pushbutton, a special value is stored in
%  preferences which indicates that subsequent calls to UIGETPREF should display
%  the dialog box.
%
%  GROUP and PREF define the preference.  If the preference does not already exist,
%  UIGETPREF creates it.
%
%  TITLE defines the string displayed in the dialog's titlebar.
%
%  QUESTION is a descriptive paragraph displayed in the dialog, specified as a string
%  array or cell array of strings.  This should contain the question the user is being
%  asked, and should be detailed enough to give the user a clear understanding of their
%  choice and its impact.  UIGETPREF inserts line breaks between rows of the string array,
%  between elements of the cell array of strings, or between '|' or newline characters in the
%  string vector.
%
%  PREF_CHOICES is either a string, cell array of strings, or '|'-separated string
%  specifying the strings to be displayed on the pushbuttons.  Each string element is
%  displayed in a separate pushbutton.  The string on the selected pushbutton is returned.
%  If the checkbox has been clicked, that string is also stored in preferences.  If the
%  checkbox has not been clicked, a special value is stored in preferences.
%
%  PREF_CHOICES may also be an 2xN cell array of strings, if the internal preference
%  values should be different than the strings displayed on the pushbuttons.  The first
%  row should contain the preference strings, and the second row should contain the
%  related pushbutton strings.  Note that the preference values are still returned in VALUE,
%  not the button labels.
%
%  [VAL,DLGSHOWN] = UIGETPREF(...)  will return whether or not the dialog was shown.
%
%  Additional arguments may be passed in as parameter-value pairs:
%
%  (...'CheckboxState',0 or 1) sets the initial state of the checkbox,
%                              either checked or unchecked.  By default it is not checked.
%
%  (...'CheckboxString',CBSTR) sets the string on the checkbox.  By default
%                              it is 'Never show this dialog again'
%
%  (...'HelpString',HSTR)      sets the string on the help button.  By default the string
%                              is empty and there is no help button.
%
%  (...'HelpFcn',HFCN)         sets the callback that is executed when the help button is
%                              pressed.  By default it is doc('uigetpref').  Note that if
%                              there is no 'HelpString', a button will not be created.
%
%  (...'ExtraOptions',EO)      creates extra buttons which are not mapped to any preference
%                              settings.  Can be a string or a cell array of strings.  By
%                              default it is {} and no extra buttons are created.
%
%  (...'DefaultButton',DB)     sets the button value that is returned if the dialog is closed.
%                              By default, it is the first button.  Note that DB does not have
%                              to correspond to a preference or ExtraOption.
%
%  Example:
%
%  [selectedButton,dlgShown]=uigetpref('graphics','savefigurebeforeclosing',...
%       'Closing Figure',...
%       {'Do you want to save your figure before closing?'
%         ''
%	      'You can save your figure manually by typing ''hgsave(gcf)'''},...
%       {'always','never';'Yes','No'},...
%       'ExtraOptions','Cancel',...
%       'DefaultButton','Cancel',...
%       'HelpString','Help',...
%       'HelpFcn','doc(''closereq'');')
%
%  SEE ALSO UISETPREF, GETPREF, SETPREF, ADDPREF, RMPREF

%  Copyright 1999-2000 The MathWorks, Inc.
%  $Revision: 1.9 $


dlgShown=logical(0);
askVal='ask';

val=getpref(prefGroup, prefPref, askVal); 

if ~ischar(val) | ~strcmp(val, askVal)
    return;
end
dlgShown=logical(1);

dlgQuestion=locParseQuestion(dlgQuestion);

[pValues,pNames]=locParseOptions(prefOptions);
uisetpref('addpref',prefGroup,prefPref,pValues);

checkboxInitState=locParseInputs(varargin,'CheckboxState',0);
checkboxString=locParseInputs(varargin,'CheckboxString','Do not show this dialog again');

defaultButton=locParseInputs(varargin,'DefaultButton',pNames{1});

extraButtons=locParseInputs(varargin,'ExtraOptions',{});
if ischar(extraButtons)
    extraButtons={extraButtons};
end

helpString=locParseInputs(varargin,'HelpString','');
if ~isempty(helpString)
    helpFcn=locParseInputs(varargin,'HelpFcn','');
    if isempty(helpFcn)
        helpTopic=locParseInputs(varargin,'HelpTopic','uigetpref');
        helpFcn=['doc(''' helpTopic ''');'];
    end
else
    helpFcn='';
end

allProps.Units='points';

%build dialog
hFig=figure(allProps,...
            'Tag','uigetpref',...
            'Resize','off',...
            'IntegerHandle','off',...
            'MenuBar','none',...
            'NumberTitle','off',...
            'Name',dlgTitle,...
            'userdata','$none$set',...
            'CloseRequestFcn',['set(gcbf,''UserData'',''', defaultButton, ''');'],...
            'KeyPressFcn',{@doKeyPress, defaultButton},...
            'Visible','off');

hQuestion=uicontrol(allProps,...
    'style','text',...
    'HorizontalAlignment','left',...
    'String',dlgQuestion,...
    'BackgroundColor',get(hFig,'color'),...
    'Parent',hFig);

hCheckbox=uicontrol(allProps,...
    'style','checkbox',...
    'String',checkboxString,...
    'Value',checkboxInitState,...
    'BackgroundColor',get(hFig,'color'),...
    'Parent',hFig);

for i=1:length(pNames)
    optButton(i)=uicontrol(allProps,...
        'style','pushbutton',...
        'String',pNames{i},...
        'Callback',['set(gcbf,''UserData'',''' pValues{i},''');'],...
        'Parent',hFig);
    if strcmp(pNames{i}, defaultButton)
        set(optButton(i),'FontWeight','bold')
    end
end

%create additional buttons
for i=1:length(extraButtons)
    optButton(end+1)=uicontrol(allProps,...
        'style','pushbutton',...
        'String',extraButtons{i},...
        'Callback',['set(gcbf,''UserData'',''' extraButtons{i},''');'],...
        'Parent',hFig);
    if strcmp(extraButtons{i}, defaultButton)
        set(optButton(end),'FontWeight','bold')
    end
end

if ~isempty(helpString)
    %disp(helpFcn);
    hHelp = uicontrol(allProps,...
        'style','pushbutton',...
        'String',helpString,...
        'Callback',['set(gcbf,''Pointer'',''watch'');',helpFcn,';set(gcbf,''Pointer'',''arrow'');'],...
        'Parent',hFig);
else
    hHelp=[];
end

%position controls
textExtent=get(hQuestion,'Extent');
checkExtent=get(hCheckbox,'Extent');

if ~isempty(hHelp)
    helpExtent = get(hHelp,'Extent');
else
    helpExtent=[0 0 0 0];
end

btnMargin=1.4;
horizExtent(length(optButton)+1)=45;
for i=length(optButton):-1:1
    ex=get(optButton(i),'Extent');
    horizExtent(i)=ex(3)*btnMargin;
end
btnHeight=ex(4)*btnMargin;
pad = btnHeight/3;

%cumHorizExtent=sum(horizExtent)+pad*(length(optButton)-1);
cumHorizExtent=max(horizExtent)*length(optButton)+pad*(length(optButton)-1);
horizSize=max([cumHorizExtent, checkExtent(3), textExtent(3), helpExtent(3)]);

numRows=2+~isempty(hHelp);
vertSize=(btnHeight+pad)*numRows+textExtent(4);

dFigPos=get(0,'DefaultFigurePosition');
set(hFig,'position',[dFigPos(1) dFigPos(2) horizSize+2*pad, vertSize+2*pad]);

set(hQuestion,'position',[pad (btnHeight+pad)*numRows+pad textExtent(3) textExtent(4)]);

helpButtonWidth=max(helpExtent(3)*btnMargin, max(horizExtent));
set(hHelp,...
    'position',[horizSize+pad-helpButtonWidth,...
        (btnHeight+pad)*2+pad,...
        helpButtonWidth,...
        btnHeight]);

set(hCheckbox,'position',[pad (btnHeight+pad)+pad, horizSize, btnHeight]);

rightPos=horizSize+2*pad;
for i=length(optButton):-1:1
    %rightPos=rightPos-horizExtent(i)-pad;
    %set(optButton(i),'position',[rightPos pad, horizExtent(i), btnHeight]);
    
    rightPos=rightPos-max(horizExtent)-pad;
    set(optButton(i),'position',[rightPos pad, max(horizExtent), btnHeight]);
end

%Activate dialog
set(hFig,'visible','on');
waitfor(hFig,'UserData');
val=get(hFig,'UserData');
newCheckValue=get(hCheckbox,'value');

delete(hFig);

if newCheckValue ~= checkboxInitState
    %the checkbox state has been tripped.  We will need to set preferences
    valIndex=find(strcmp(val,pValues));
    if ~isempty(valIndex)
        newPref=pValues{valIndex(1)};
        setpref(prefGroup,prefPref,newPref);
        uisetpref('addpref',prefGroup,prefPref,pValues);
    end
end
val=lower(val);


%%%%%%%%%%%%%%%%%%
function val=locParseInputs(inputs, key, default)

keyIndex=find(strcmpi(inputs(1:2:end-1),key));
if isempty(keyIndex)
    val=default;
else
    val=inputs{2*keyIndex(1)};
end

%%%%%%%%%%%
function dlgQuestion=locParseQuestion(dlgQuestion)

dlgQuestion=strrep(dlgQuestion,'|',sprintf('\n'));

%%%%%%%%%%%
function [pValues,pNames]=locParseOptions(prefOptions)

if iscell(prefOptions)
    if min(size(prefOptions))>1
        pValues=prefOptions(1,:);
        pNames=prefOptions(2,:);
    else
        pValues=prefOptions;
        pNames=prefOptions;
    end
else %input is a pipe-delimited string
    pipeLoc=findstr(prefOptions,'|');
    pipeLoc=[0,pipeLoc, length(prefOptions)+1];
    
    pNames=cell(1,length(pipeLoc)-1);
    for i=1:length(pipeLoc)-1
        pNames{i}=prefOptions(pipeLoc(i)+1:pipeLoc(i+1)-1);
    end
    pValues=pNames;
end

%%%%%%
function doKeyPress(obj,evd,default,checkbox)
fig = gcbf;
AsciiVal= abs(get(fig,'CurrentCharacter'));
if ~isempty(AsciiVal)
    if AsciiVal==13,
        set(fig,'UserData',default);
    end
end
