function cancelflag = axesmui(callback,action)
%AXESMUI Define axesm-based map and modify projection properties
%
%   AXESMUI(HNDL) interactively manipulates the map properties of the axes
%   specified by HNDL.
%
%   C = AXESMUI(...) provides an optional output argument indicating if the
%   dialog window was closed by the cancel button.  If the Cancel button is
%   pushed, C = 1.  Otherwise, C = 0.
%
%   See also AXESM

% Copyright 1996-2023 The MathWorks, Inc.
% Written by:  E. Byrns, E. Brown, A. Kim

%  Parse the inputs
if nargin > 0
    callback = convertStringsToChars(callback);
end
if nargin > 1
    action = convertStringsToChars(action);
end

if nargin == 0
    hndl = gca;
    callback = 'initialize';
elseif nargin == 1
    if ~ischar(callback)
        hndl = callback;
        callback = 'initialize';
    end
end


%  Initialize the output cancel flag if necessary.

if nargout == 1
    cancelflag = [];
end


switch callback      %  Basic switchyard
    case 'initialize'

        %  Test for a valid axis handle

        if isempty(hndl)
            hndl = gca;
        end

        if ~ishghandle(hndl,'axes')
            notifyuser('Valid axis handle required','Initialization Error')
            return
        end

        %  Get the map structure
        try
            mstruct = gcm(hndl);
        catch e
            notifyuser(e.message,'Initialization Error')  
            return
        end

        %  Display the dialog box, initialize the entries, and wait until dialog
        %  is closed

        errorcondition = 0;
        workstruct = mstruct;
        while 1
            h = AxesmuiDialog(hndl);   %  Main dialog window

            set(h.hiddenaxes,'UserData',workstruct)      %  Working map structure
            axesmui('MainDialog','AxesEntries')
            uiwait(h.fig)
            if ~ishghandle(h.fig)
                figure(get(h.axes,'Parent'))
                if errorcondition
                    setm(h.axes,get(h.axes,'UserData'));
                end
                if nargout == 1
                    cancelflag = 1;
                end
                return
            end

            axesmui('MainDialog','AxesUpdate')          %  Update structure based on dialog entries
            workstruct = get(h.hiddenaxes,'UserData');  %  Working map structure
            btn = get(h.fig,'CurrentObject');
            delete(h.fig)

            if btn == h.apply
                try
                    setm(h.axes,workstruct);
                    axes(h.axes);
                    if nargout == 1
                        cancelflag = 0;
                    end
                    break
                catch e
                    notifyuser(e.message,'Mapping Error')
                    errorcondition = 1;
                end

            else    %  Canceled.  Reset axes if an error condition existed
                figure(get(h.axes,'Parent'))
                if errorcondition; setm(h.axes,get(h.axes,'UserData'));  end
                if nargout == 1;  cancelflag = 1;  end
                break
            end
        end

        h = findobj(gcf,'Type','uicontrol','Tag','TextObjectToDelete');
        if ishghandle(h)
            delete(h);
        end

    case 'numbercheck'      %  Check for valid numbers in selected edit boxes
        %  These boxes can be linked to others so that emptying
        %  one empties its links too.  (such as Map Lat Limits)
        obj=get(get(0,'CurrentFigure'),'CurrentObject');
        linkobjects = get(obj,'UserData');
        if isempty(linkobjects);   linkobjects = obj;   end

        str = get(obj,'String');
        if isempty(str);   set(linkobjects,'String','');  end

    otherwise               %  Switch for all other actions, including nested dialogs
        eval([callback,'(''',action,''')'])

end

%-----------------------------------------------------------------------

function MainDialog(action)

%  MAINDIALOG contains the switch yard for almost all actions occurring
%  during the AXESMUI CallBacks.  The only other switches are above in
%  the AXESMUI function.

%  These callbacks typically assume that a hidden axes has been placed
%  on the dialog window (visible off, h.hiddenaxes) where a copy of
%  the map structure is kept.  This is the working copy of the map
%  structure which is different than the current map structure used
%  to display the current map.  If the map dialog is accepted, then
%  this working structure is transferred (and used to reproject) the
%  current map.


switch action
    case 'AxesEntries'   %  Set the main dialog entries using the current map structure

        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        listdata = get(h.projection,'UserData');
        indx = find(strcmp(mstruct.mapprojection,cellstr(listdata.idstr)));

        set(h.projection,'String',listdata.namestr(:,:),...
            'Value',indx,'UserData',listdata)

        indx = strmatch(mstruct.angleunits,get(h.angleunits,'String'),'exact');
        set(h.angleunits,'Value',indx)       %  Set the angle units value

        indx = strmatch(mstruct.aspect,get(h.aspect,'String'));
        set(h.aspect,'Value',indx)       %  Set the aspect value

        set(h.maplat(1),'String',mstruct.maplatlimit(1))    %  Map Limits
        set(h.maplat(2),'String',mstruct.maplatlimit(2))
        set(h.maplon(1),'String',mstruct.maplonlimit(1))
        set(h.maplon(2),'String',mstruct.maplonlimit(2))

        set(h.frmlat(1),'String',mstruct.flatlimit(1))    %  Frame Limits
        set(h.frmlat(2),'String',mstruct.flatlimit(2))
        set(h.frmlon(1),'String',mstruct.flonlimit(1))
        set(h.frmlon(2),'String',mstruct.flonlimit(2))

        switch length(mstruct.origin)  %  Origin may not be length == 3 during gui callbacks
            case 1
                set(h.origin(1),'String',mstruct.origin(1))
            case 2
                set(h.origin(1),'String',mstruct.origin(1))
                set(h.origin(2),'String',mstruct.origin(2))
            case 3
                set(h.origin(1),'String',mstruct.origin(1))    %  Map origin
                set(h.origin(2),'String',mstruct.origin(2))    %  Orientation is editable
                set(h.origin(3),'String',mstruct.origin(3))    %  only if not fixed
        end
        if isempty(mstruct.fixedorient)
            set(h.origin(3),'Enable','on')
        else
            set(h.origin(3),'Enable','off')
        end

        switch mstruct.nparallels     %  Enable edit if parallels can be modified
            case 0   %  Show defaults even if they can't be edited
                switch length(mstruct.mapparallels)
                    case 0,  set(h.parallel(1),'String','None','Enable','off')
                        set(h.parallel(2),'String','','Visible','off')
                    case 1,  set(h.parallel(1),'String',mstruct.mapparallels(1),'Enable','off')
                        set(h.parallel(2),'String','','Visible','off')
                    case 2,  set(h.parallel(1),'String',mstruct.mapparallels(1),'Enable','off')
                        set(h.parallel(2),'String',mstruct.mapparallels(2),...
                            'Enable','off','Visible','on')
                end
            case 1,   set(h.parallel(1),'String',mstruct.mapparallels(1),'Enable','on')
                set(h.parallel(2),'String','','Visible','off')
            case 2,   set(h.parallel(1),'String',mstruct.mapparallels(1),'Enable','on')
                if length(mstruct.mapparallels) == 2
                    set(h.parallel(2),'String',mstruct.mapparallels(2),...
                        'Enable','on','Visible','on')
                end
        end

        %  new code: added properties

        if strcmp(mstruct.mapprojection,'utm') || strcmp(mstruct.mapprojection,'ups')
            swtch1 = 'on';   swtch2 = 'off';
        else
            swtch1 = 'off';  swtch2 = 'on';
        end
        if strcmp(mstruct.mapprojection,'utm')
            if ~isLocalClient
                % Turn off clickability of Zone button when client is
                % remote (such as when running in MATLAB Online).
                swtch3 = 'off';
            else
                swtch3 = 'on';
            end
        else
            swtch3 = 'off';
        end

        set(h.zone,'String',mstruct.zone,'Enable',swtch1)
        set(h.zonebtn,'Enable',swtch3)
        set(h.falseE,'String',mstruct.falseeasting,'Enable',swtch2)
        set(h.falseN,'String',mstruct.falsenorthing,'Enable',swtch2)
        set(h.sf,'String',mstruct.scalefactor,'Enable',swtch2)
        set(h.origin(1),'Enable',swtch2)
        set(h.origin(2),'Enable',swtch2)
        set(h.origin(3),'Enable',swtch2)

        %  new code: geoid

        % If the axes 'geoid' field contains a spheroid object, convert it
        % to an ellipsoid vector.
        spheroid = mstruct.geoid;
        if isobject(spheroid)
            spheroid = [spheroid.SemimajorAxis spheroid.Eccentricity];
        end
        
        set(h.geoid(1),'String',num2str(spheroid(1),7))
        set(h.geoid(2),'String',num2str(spheroid(2),7))

        set(h.geoid(1),'Userdata',spheroid)

        [list,ptr] = axesmuiSpheroid(spheroid,mstruct.zone);
        set(h.geoidpop,'String',list,'Value',ptr)

    case 'AxesUpdate'      %  Update the properties associated with the main dialog

        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        listdata = get(h.projection,'UserData');    %  Map projection
        indx = get(h.projection,'Value');
        mstruct.mapprojection = deblank(listdata.idstr(indx,:));

        angleunits = get(h.angleunits,'String');   %  Angle units
        indx = get(h.angleunits,'Value');
        mstruct.angleunits = deblank(angleunits(indx,:));

        aspectstr = get(h.aspect,'String');   %  Aspect String
        indx = get(h.aspect,'Value');
        mstruct.aspect = deblank(aspectstr(indx,:));

        origin1 = str2double(get(h.origin(1),'String'));   %  Allow for blank origin
        origin2 = str2double(get(h.origin(2),'String'));   %  entries
        origin3 = str2double(get(h.origin(3),'String'));
        if length(origin1) >  1;   origin1 = origin1(1);   end
        if isempty(origin2);       origin2 = 0;            end
        if length(origin2) >  1;   origin2 = origin2(1);   end
        if length(origin3) >  1;   origin3 = origin3(1);   end
        mstruct.origin = [origin1  origin2  origin3];

        limit1 = str2double(get(h.maplat(1),'String'));   %  Allow for blank limit
        limit2 = str2double(get(h.maplat(2),'String'));   %  entries
        if length(limit1) > 1;  limit1 = limit1(1);   end
        if length(limit2) > 1;  limit2 = limit2(1);   end
        mstruct.maplatlimit = [limit1 limit2];

        limit1 = str2double(get(h.maplon(1),'String'));   %  Allow for blank limit
        limit2 = str2double(get(h.maplon(2),'String'));   %  entries
        if length(limit1) > 1;  limit1 = limit1(1);   end
        if length(limit2) > 1;  limit2 = limit2(1);   end
        mstruct.maplonlimit = [limit1 limit2];

        limit1 = str2double(get(h.frmlat(1),'String'));   %  Allow for blank limit
        limit2 = str2double(get(h.frmlat(2),'String'));   %  entries
        if length(limit1) > 1;  limit1 = limit1(1);   end
        if length(limit2) > 1;  limit2 = limit2(1);   end
        mstruct.flatlimit = [limit1 limit2];

        limit1 = str2double(get(h.frmlon(1),'String'));   %  Allow for blank limit
        limit2 = str2double(get(h.frmlon(2),'String'));   %  entries
        if length(limit1) > 1;  limit1 = limit1(1);   end
        if length(limit2) > 1;  limit2 = limit2(1);   end
        mstruct.flonlimit = [limit1 limit2];

        if mstruct.nparallels > 0
            parallel = [];
            for i = 1:mstruct.nparallels
                pnum = str2double(get(h.parallel(i),'String'));
                if length(pnum) > 1;  pnum = pnum(1);  end
                parallel = [parallel pnum];
            end
            mstruct.mapparallels = parallel;
        end

        %  new code: added properties

        mstruct.zone = get(h.zone,'String');

        falseE = str2double(get(h.falseE,'String'));   %  Allow for blank limit
        falseN = str2double(get(h.falseN,'String'));   %  entries
        sf = str2double(get(h.sf,'String'));
        if length(falseE) > 1;  falseE = falseE(1);   end
        if length(falseN) > 1;  falseN = falseN(1);   end
        if length(sf) > 1;  sf = sf(1);   end
        mstruct.falseeasting = falseE;
        mstruct.falsenorthing = falseN;
        mstruct.scalefactor = sf;

        %  new code: geoid

        mstruct.geoid = get(h.geoid(1),'UserData');

        set(h.hiddenaxes,'UserData',mstruct)      %  Update working map structure

    case 'Projection'    %  Callback to set defaults when moving between projections
        axesmui('MainDialog','AxesUpdate')    %  Update the working map
        %  structure before setting
        %  any remaining defaults
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        listdata = get(h.projection,'UserData');    %  Map projection
        indx = get(h.projection,'Value');

        mstruct.mapprojection = deblank(listdata.idstr(indx,:));

        mstruct.zone = [];
        mstruct.geoid = [];

        mstruct = feval(mstruct.mapprojection,mstruct);
        mstruct = defaultm(mstruct);

        set(h.hiddenaxes,'UserData',mstruct)      %  Update working map structure
        axesmui('MainDialog','AxesEntries');

        % update fields for default frame latitude and longitude limits 06272002
        minlat = num2str(mstruct.trimlat(1));
        maxlat = num2str(mstruct.trimlat(2));
        minlon = num2str(mstruct.trimlon(1));
        maxlon = num2str(mstruct.trimlon(2));
        set(findobj(gcf,'Tag','frminlat'),'String',minlat)
        set(findobj(gcf,'Tag','frmaxlat'),'String',maxlat)
        set(findobj(gcf,'Tag','frminlon'),'String',minlon)
        set(findobj(gcf,'Tag','frmaxlon'),'String',maxlon)

    case 'Zone'   %  new code: Callback for the zone edit box on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure
        drawnow;
        oldzone = mstruct.zone;

        if strcmp(mstruct.mapprojection,'utm')
            mstruct.zone = upper(get(h.zone,'String'));
        elseif strcmp(mstruct.mapprojection,'ups')
            mstruct.zone = lower(get(h.zone,'String'));
        end

        try
            mstruct = zoneupdate(mstruct);
            if strcmp(mstruct.mapprojection,'utm')
                geoid = utmgeoid(mstruct.zone);
                mstruct.geoid = geoid(1,:);
            end
            mstruct.mlabelparallel = [];   %  Ensures that these are set to the
            mstruct.plabelmeridian = [];   %  appropriate defaults
            set(h.geoid(1),'UserData',mstruct.geoid)
            
            set(h.hiddenaxes,'UserData',mstruct)
            set(h.zone,'String',mstruct.zone)
            axesmui('MainDialog','AxesEntries');   %  Update working map structure

        catch e
            notifyuser(e.message,'Zone')

            set(h.zone,'String',oldzone)         %  Set the zone back to the default
            axesmui('MainDialog','AxesUpdate')   %  Update the working map

        end

    case 'Zonebtn'   %  new code: Callback for the zone push button on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        if strcmp(mstruct.mapprojection,'utm')
            oldzone = upper(get(h.zone,'String'));
        elseif strcmp(mstruct.mapprojection,'ups')
            oldzone = lower(get(h.zone,'String'));
        end

        try
            mstruct.zone = utmzoneui(oldzone);
            mstruct = zoneupdate(mstruct);
            geoid = utmgeoid(mstruct.zone);
            mstruct.geoid = geoid(1,:);
            mstruct.mlabelparallel = [];   %  Ensures that these are set to the
            mstruct.plabelmeridian = [];   %  appropriate defaults
            set(h.geoid(1),'UserData',mstruct.geoid)
            
            set(h.hiddenaxes,'UserData',mstruct)
            set(h.zone,'String',mstruct.zone)
            axesmui('MainDialog','AxesEntries');   %  Update working map structure

        catch e
            notifyuser(e.message,'Zone')
            
            set(h.zone,'String',oldzone)         %  Set the zone back to the default
            axesmui('MainDialog','AxesUpdate')   %  Update the working map

        end

    case 'Geoid'  % new code: Callback for geoid edit boxes on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        oldgeoid = mstruct.geoid;
        geoid(1) = str2double(get(h.geoid(1),'String'));
        geoid(2) = str2double(get(h.geoid(2),'String'));

        txtmsg = [];
        if geoid(1)<=0 || geoid(2)<0 || geoid(2)>=1
            txtmsg = 'Invalid geoid definition';
        end

        if isempty(txtmsg)
            mstruct.geoid = geoid;
            set(h.geoid(1),'UserData',geoid)
            set(h.hiddenaxes,'UserData',mstruct)
            axesmui('MainDialog','AxesEntries');   %  Update working map structure
        else
            notifyuser(txtmsg,'Geoid')

            set(h.geoid(1),'String',num2str(oldgeoid(1),7))      %  Set the zone back to the default
            set(h.geoid(2),'String',num2str(oldgeoid(2),7))      %  Set the zone back to the default
            axesmui('MainDialog','AxesUpdate')   %  Update the working map
        end

    case 'Geoidpop'  % new code: Callback for geoid popup on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure        
        [a, ecc] = axesmuiSpheroid(get(h.geoidpop,'Value'));
        geoid = [a ecc];
        if strcmp(mstruct.mapprojection,'utm') || strcmp(mstruct.mapprojection,'ups')
            geoid(1) = geoid(1)*1e3;
        end
        mstruct.geoid = geoid;
        set(h.geoid(1),'UserData',geoid)
        set(h.hiddenaxes,'UserData',mstruct)
        axesmui('MainDialog','AxesEntries');   %  Update working map structure

    case 'AngleUnits'   %  Callback for the angle units popup on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        oldunits = mstruct.angleunits;

        axesmui('MainDialog','AxesUpdate')         %  Update the working map
        mstruct = get(h.hiddenaxes,'UserData');    %  structure before changing
        %  angle units

        try
            mstruct = mapangles(mstruct,oldunits);
            set(h.hiddenaxes,'UserData',mstruct)      %  Update working map structure
            axesmui('MainDialog','AxesEntries');

        catch e
            notifyuser(e.message,'Angle Units')
            
            indx = strmatch(oldunits,get(h.angleunits,'String'),'exact');
            set(h.angleunits,'Value',indx)       %  Set the angle units value
            axesmui('MainDialog','AxesUpdate')         %  Update the working map

        end
        
    case 'Reset'   %  Callback for the reset button on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        prompt = strvcat('Changes Can Not Be Undone.',' ','Reset Map Settings?');
        ButtonName = questdlg(prompt,'Confirm Reset','Yes','No','No');

        if strcmp(ButtonName,'Yes')
            set(0,'CurrentFigure',get(h.axes,'Parent'));
            newstruct = defaultm;
            newstruct.mapprojection = mstruct.mapprojection;
            newstruct = feval(mstruct.mapprojection,newstruct);
            newstruct = defaultm(newstruct);

            set(0,'CurrentFigure',get(h.hiddenaxes,'Parent'));
            set(h.hiddenaxes,'UserData',newstruct)   %  Update working map structure
            axesmui('MainDialog','AxesEntries');
        end

    case 'Default'   %  Callback for the default button on main window
        axesmui('MainDialog','AxesUpdate')    %  Update the working map
        %  structure before setting
        %  any remaining defaults
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure
        mstruct = defaultm(mstruct);

        set(h.hiddenaxes,'UserData',mstruct)   %  Update working map structure
        axesmui('MainDialog','AxesEntries')

    case 'Frame'    %  Callback for the frame button on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        copystruct = mstruct;
        if strcmp(copystruct.fedgecolor,'default')
            copystruct.fedgecolor = h.hiddenaxes.XColor;
        end
        while 1  %  Loop until valid entries or cancel pushed
            hmodal = FrameBox(copystruct);      uiwait(hmodal.fig);  %  Display modal dialog
            if ~ishghandle(hmodal.fig)
                return;
            end

            btn = get(hmodal.fig,'CurrentObject');        %  Get needed items before
            frameon = get(hmodal.frameon,'Value');        %  destroying window
            faceclr = get(hmodal.facecolor,'UserData');
            edgeclr = get(hmodal.edgecolor,'UserData');

            linesizestr = get(hmodal.widthedit,'String');
            fillstr = get(hmodal.filledit,'String');
            linesize = str2num(linesizestr);
            fillpts = str2num(fillstr);

            delete(hmodal.fig)

            %  Update the copied map structure.  Use the string form of the
            %  edit entries in case they're needed during the error looping.

            if frameon
                copystruct.frame = 'on';    %  Save entries in the
            else
                copystruct.frame = 'off';   %  copied structure array
            end

            copystruct.ffacecolor = faceclr.val;    copystruct.fedgecolor = edgeclr.val;
            copystruct.flinewidth  = linesizestr;   copystruct.ffill = fillstr;

            if btn == hmodal.apply     %  If apply, check for valid data
                msg = [];
                if isempty(linesize) && ~isempty(linesizestr) || ...
                        length(linesize) > 1 || linesize <= 0
                    msg = 'Frame edge width must be a single number greater than 0.';
                elseif isempty(fillpts) && ~isempty(fillstr) || ...
                        length(fillpts) > 1 || fillpts <= 0
                    msg = 'Frame points per edge must be a single number greater than 0.';
                end

                if ~isempty(msg)   %  Error condition
                    notifyuser(msg,'Invalid Frame Parameter')
                else
                    copystruct.flinewidth  = linesize;  %  Replace text with
                    copystruct.ffill = fillpts;         %  valid numerical entries
                    set(h.hiddenaxes,'UserData',copystruct)
                    break         %  Valid frame parameters
                end
            else
                break      %  Cancel button pushed
            end
        end

    case 'Grid'     %  Callback for the grid button on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        copystruct = mstruct;
        if strcmp(copystruct.gcolor,'default')
            copystruct.gcolor = h.hiddenaxes.XColor;
        end
        while 1  %  Loop until valid entries or cancel pushed
            hmodal = GridBox(copystruct);      uiwait(hmodal.fig);  %  Display modal dialog
            if ~ishghandle(hmodal.fig)
                return;
            end

            btn = get(hmodal.fig,'CurrentObject');        %  Get needed items before
            gridon = get(hmodal.gridon,'Value');          %  destroying window
            gridclr = get(hmodal.color,'UserData');
            styles  = get(hmodal.style,'UserData');
            styleindx = get(hmodal.style,'Value');
            linesizestr = get(hmodal.widthedit,'String');
            altstr = lower(get(hmodal.altedit,'String'));
            linesize = str2num(linesizestr);
            altitude = str2num(altstr);

            %  Get an updated copy of the map structure.  The parallel and meridian
            %  settings may have been altered while waiting on the grid dialog.

            copystruct = get(hmodal.hiddenaxes,'UserData');

            delete(hmodal.fig)

            %  Update the copied map structure.  Use the string form of the
            %  edit entries in case they're needed during the error looping.

            if gridon
                copystruct.grid = 'on';    %  Save entries in the
            else
                copystruct.grid = 'off';   %  copied structure array
            end

            copystruct.gcolor     = gridclr.val;
            copystruct.glinestyle = deblank(styles(styleindx,:));
            copystruct.glinewidth = linesizestr;
            copystruct.galtitude  = altstr;

            if btn == hmodal.apply     %  If apply, check for valid data
                msg = [];
                if isempty(linesize) && ~isempty(linesizestr) || ...
                        length(linesize) > 1 || linesize <= 0
                    msg = 'Grid line width must be a single number greater than 0.';

                    %  The following line is commented out and substituted with the one that follows.
                    %  This works around a unix uicontrol bug in which the implicit num2str conversion
                    %  produces garbage, which then causes an error. This workaround should go
                    %  away with the bug.

                    %           elseif isempty(altitude) & ~isempty(altstr) | length(altitude) > 1

                elseif length(altitude) > 1
                    msg = 'Grid altitude must be a single number or INF.';
                end

                if ~isempty(msg)
                    notifyuser(msg,'Invalid Grid Parameter')
                else
                    copystruct.glinewidth = linesize;    %  Replace text with
                    copystruct.galtitude = altitude;     %  valid numerical entries
                    set(h.hiddenaxes,'UserData',copystruct)
                    break         %  Valid frame parameters
                end
            else
                break      %  Cancel button pushed
            end
        end

    case 'Meridian&Parallel'   %  Callback for the Meridian&Parallel settings from Grid dialog
        hgrid = get(get(0,'CurrentFigure'),'UserData');   %  Grid Dialog object handles
        mstruct = get(hgrid.hiddenaxes,'UserData');       %  Working map structure

        copystruct = mstruct;
        while 1  %  Loop until valid entries or cancel pushed
            hmodal = GridPropBox(copystruct);      uiwait(hmodal.fig);  %  Display modal dialog
            if ~ishghandle(hmodal.fig)
                return;
            end

            btn = get(hmodal.fig,'CurrentObject');
            meridianon = get(hmodal.meridianon,'Value');   %  Get needed meridian items
            mlocatestr = get(hmodal.longedit,'String');
            mlimitstr = get(hmodal.mlimitedit,'String');
            mexcptstr = get(hmodal.longexcedit,'String');
            mfillstr  = get(hmodal.mfilledit,'String');

            parallelon = get(hmodal.parallelon,'Value');   %  Get needed parallel items
            plocatestr = get(hmodal.latedit,'String');
            plimitstr = get(hmodal.plimitedit,'String');
            pexcptstr = get(hmodal.latexcedit,'String');
            pfillstr  = get(hmodal.pfilledit,'String');

            delete(hmodal.fig)      %  Delete the modal dialog

            %  Make potential multi-line entries into a single row vector

            mlocatestr = mlocatestr';                mexcptstr = mexcptstr';
            mlocatestr = mlocatestr(:)';             mexcptstr = mexcptstr(:)';
            mlocatestr(mlocatestr==0) = [];          mexcptstr(mexcptstr ==0) = [];

            plocatestr = plocatestr';                pexcptstr = pexcptstr';
            plocatestr = plocatestr(:)';             pexcptstr = pexcptstr(:)';
            plocatestr(plocatestr==0) = [];          pexcptstr(pexcptstr ==0) = [];

            %  Convert strings to numbers.

            mlocate = str2num(mlocatestr);     mlimit = str2num(mlimitstr);
            mexcpt = str2num(mexcptstr);       mfill = str2num(mfillstr);

            plocate = str2num(plocatestr);     plimit = str2num(plimitstr);
            pexcpt = str2num(pexcptstr);       pfill = str2num(pfillstr);

            %  Update the copied map structure.  Use the string form of the
            %  edit entries in case they're needed during the error looping.

            if meridianon
                copystruct.mlinevisible = 'on';
            else
                copystruct.mlinevisible = 'off';
            end

            if parallelon
                copystruct.plinevisible = 'on';
            else
                copystruct.plinevisible = 'off';
            end

            copystruct.mlinelocation = mlocatestr;
            copystruct.mlinelimit = mlimitstr;
            copystruct.mlineexception = mexcptstr;
            copystruct.mlinefill  = mfillstr;

            copystruct.plinelocation = plocatestr;
            copystruct.plinelimit = plimitstr;
            copystruct.plineexception = pexcptstr;
            copystruct.plinefill  = pfillstr;

            if btn == hmodal.apply     %  If apply, check for valid data
                msg = [];
                if isempty(mlocate) && ~isempty(mlocatestr)
                    msg = 'Meridian locations must be a valid number or vector.';
                elseif isempty(mlimit) && ~isempty(mlimitstr) || ...
                        (~isempty(mlimit) && length(mlimit) ~= 2)
                    msg = 'Meridian limits must be empty or a two element vector.';
                elseif isempty(mexcpt) && ~isempty(mexcptstr)
                    msg = 'Meridian exceptions must be a valid number or vector.';
                elseif isempty(mfill) && ~isempty(mfillstr) || ...
                        length(mfill) > 1 || mfill <= 0
                    msg = 'Meridian fill points must be a single number greater than 0.';
                elseif isempty(plocate) && ~isempty(plocatestr)
                    msg = 'Parallel locations must be a valid number or vector.';
                elseif isempty(plimit) && ~isempty(plimitstr) || ...
                        (~isempty(plimit) && length(plimit) ~= 2)
                    msg = 'Parallel limits must be empty or a two element vector.';
                elseif isempty(pexcpt) && ~isempty(pexcptstr)
                    msg = 'Parallel exceptions must be a valid number or vector.';
                elseif isempty(pfill) && ~isempty(pfillstr) || ...
                        length(pfill) > 1 || pfill <= 0
                    msg = 'Parallel fill points must be a single number greater than 0.';
                end

                if ~isempty(msg)
                    notifyuser(msg,'Invalid Grid Parameter')
                else
                    copystruct.mlinelocation = mlocate;    %  Replace text with
                    copystruct.mlinelimit = mlimit;        %  valid numerical entries
                    copystruct.mlineexception = mexcpt;
                    copystruct.mlinefill  = mfill;
                    copystruct.plinelocation = plocate;
                    copystruct.plinelimit = plimit;
                    copystruct.plineexception = pexcpt;
                    copystruct.plinefill  = pfill;

                    set(hgrid.hiddenaxes,'UserData',copystruct)
                    break         %  Valid frame parameters
                end
            else
                break      %  Cancel button pushed
            end
        end

    case 'Labels'    %  Callback for the labels button on main window
        h = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        mstruct = get(h.hiddenaxes,'UserData');       %  Working map structure

        copystruct = mstruct;
        if strcmp(copystruct.fontcolor,'default')
            copystruct.fontcolor = h.hiddenaxes.XColor;
        end
        while 1  %  Loop until valid entries or cancel pushed
            hmodal = LabelBox(copystruct);      uiwait(hmodal.fig);  %  Display modal dialog
            if ~ishghandle(hmodal.fig)
                return;
            end

            btn = get(hmodal.fig,'CurrentObject');        %  Get needed items before
            meridianon = get(hmodal.meridianon,'Value');  %  destroying window
            parallelon = get(hmodal.parallelon,'Value');
            labelformat = get(hmodal.format,'String');
            labelindx   = get(hmodal.format,'Value');

            labelunit = get(hmodal.units,'String');
            unitindx = get(hmodal.units,'Value');

            fontname = get(hmodal.fontedit,'String');
            fontsizestr = get(hmodal.sizeedit,'String');
            fontsize = str2num(fontsizestr);
            fontclr = get(hmodal.fontclr,'UserData');

            fontunit = get(hmodal.fontunits,'String');
            fontindx = get(hmodal.fontunits,'Value');

            fontweights = get(hmodal.fontwt,'String');
            weightindx = get(hmodal.fontwt,'Value');

            fontangle = get(hmodal.fontangle,'String');
            angleindx = get(hmodal.fontangle,'Value');

            %  Get an updated copy of the map structure.  The parallel and meridian
            %  settings may have been altered while waiting on the font dialog.

            copystruct = get(hmodal.hiddenaxes,'UserData');

            delete(hmodal.fig)

            %  Update the copied map structure.  Use the string form of the
            %  edit entries in case they're needed during the error looping.

            if meridianon
                copystruct.meridianlabel = 'on';    %  Save entries in the
            else
                copystruct.meridianlabel = 'off';   %  copied structure array
            end

            if parallelon
                copystruct.parallellabel = 'on';
            else
                copystruct.parallellabel = 'off';
            end

            copystruct.fontname    = fontname;
            copystruct.fontsize    = fontsizestr;
            copystruct.fontangle   = deblank(fontangle(angleindx,:));
            copystruct.fontunits   = deblank(fontunit(fontindx,:));
            copystruct.fontweight  = deblank(fontweights(weightindx,:));
            copystruct.labelformat = deblank(labelformat(labelindx,:));
            copystruct.labelunits  = deblank(labelunit(unitindx,:));

            if btn == hmodal.apply     %  If apply, check for valid data
                msg = [];
                if isempty(fontsize) && ~isempty(fontsizestr) || ...
                        length(fontsize) > 1 || fontsize <= 0
                    msg = 'Font size must be a single number greater than 0.';
                end

                if ~isempty(msg)
                    notifyuser(msg,'Invalid Font or Label Parameter')
                else
                    copystruct.fontsize  = fontsize;
                    copystruct.fontcolor = fontclr.val;
                    set(h.hiddenaxes,'UserData',copystruct)
                    break         %  Valid frame parameters
                end
            else
                break      %  Cancel button pushed
            end
        end

    case 'LabelSettings'    %  Callback for the Parallel and Meridian Label settings
        hfont = get(get(0,'CurrentFigure'),'UserData');   %  Grid Dialog object handles
        mstruct = get(hfont.hiddenaxes,'UserData');       %  Working map structure

        copystruct = mstruct;
        while 1  %  Loop until valid entries or cancel pushed
            hmodal = LabelPropBox(copystruct);      uiwait(hmodal.fig);  %  Display modal dialog
            if ~ishghandle(hmodal.fig)
                return;
            end

            btn = get(hmodal.fig,'CurrentObject');
            mlocatestr = get(hmodal.mlocateedit,'String');   %  Get needed meridian items
            mroundstr  = get(hmodal.mroundedit,'String');

            mparallelstr = get(hmodal.mparalleledit,'String');
            mparalleloptions = get(hmodal.mparallelpopup,'String');
            mindx = get(hmodal.mparallelpopup,'Value');

            plocatestr = get(hmodal.plocateedit,'String');   %  Get needed parallel items
            proundstr  = get(hmodal.proundedit,'String');

            pmeridianstr = get(hmodal.pmeridianedit,'String');
            pmeridianoptions = get(hmodal.pmeridianpopup,'String');
            pindx = get(hmodal.pmeridianpopup,'Value');

            delete(hmodal.fig)      %  Delete the modal dialog

            %  Make potential multi-line entries into a single row vector

            mlocatestr = mlocatestr';                plocatestr = plocatestr';
            mlocatestr = mlocatestr(:)';             plocatestr = plocatestr(:)';
            mlocatestr(find(mlocatestr==0)) = [];    plocatestr(find(plocatestr==0)) = [];

            %  Convert strings to numbers.

            mlocate = str2num(mlocatestr);     mround = str2num(mroundstr);
            if ~isempty(mparallelstr)
                mparallel = str2num(mparallelstr);
            else
                mparallel = deblank(mparalleloptions(mindx,:));
            end

            plocate = str2num(plocatestr);     pround = str2num(proundstr);
            if ~isempty(pmeridianstr)
                pmeridian = str2num(pmeridianstr);
            else
                pmeridian = deblank(pmeridianoptions(pindx,:));
            end

            %  Update the copied map structure.  Use the string form of the
            %  edit entries in case they're needed during the error looping.

            copystruct.mlabellocation = mlocatestr;
            copystruct.mlabelparallel = mparallelstr;
            copystruct.mlabelround  = mroundstr;

            copystruct.plabellocation = plocatestr;
            copystruct.plabelmeridian = pmeridianstr;
            copystruct.plabelround  = proundstr;

            if btn == hmodal.apply     %  If apply, check for valid data
                msg = [];
                if isempty(mlocate) && ~isempty(mlocatestr)
                    msg = 'Meridian label locations must be a valid number or vector.';
                elseif isempty(mround) && ~isempty(mroundstr) || length(mround) > 1
                    msg = 'Meridian round value must be a single number.';
                elseif isempty(mparallel) && ~isempty(mparallelstr) || ...
                        (~ischar(mparallel) && length(mparallel) > 1)
                    msg = 'Display parallel must be a single number.';
                elseif isempty(plocate) && ~isempty(plocatestr)
                    msg = 'Parallel label locations must be a valid number or vector.';
                elseif isempty(pround) && ~isempty(proundstr) || length(pround) > 1
                    msg = 'Parallel round value must be a single number.';
                elseif isempty(pmeridian) && ~isempty(pmeridianstr) || ...
                        (~ischar(pmeridian) && length(pmeridian) > 1)
                    msg = 'Display meridian must be a single number.';
                end

                if ~isempty(msg)
                    notifyuser(msg,'Invalid Grid Parameter')
                else
                    copystruct.mlabellocation = mlocate;     %  Replace text with
                    copystruct.mlabelparallel = mparallel;   %  valid numerical entries
                    copystruct.mlabelround = mround;

                    copystruct.plabellocation = plocate;
                    copystruct.plabelmeridian = pmeridian;
                    copystruct.plabelround = pround;

                    set(hfont.hiddenaxes,'UserData',copystruct)
                    break         %  Valid frame parameters
                end
            else
                break      %  Cancel button pushed
            end
        end

    case 'FontPreview'   %  Callback to preview the selected font (Label Dialog)
        hmodal = get(get(0,'CurrentFigure'),'UserData');   %  Dialog object handles
        fontname = get(hmodal.fontedit,'String');
        fontsize = str2num(get(hmodal.sizeedit,'String'));
        if isempty(fontsize);  fontsize = 10;  end

        fontweights = get(hmodal.fontwt,'String');
        weightindx = get(hmodal.fontwt,'Value');

        fontangle = get(hmodal.fontangle,'String');
        angleindx = get(hmodal.fontangle,'Value');

        fighndl = dialog('Units','points',  'Position',72*[2 2 3 1.5],...
            'Name',[fontname,'  Preview'],'MenuBar','none',...
            'Visible','on');

        texthndl = uicontrol(fighndl,'Style','text', 'String','Aa Bb Cc Dd Ee Ff',...
            'Units','normalized', 'Position',[0.05 0.3 0.90 0.60],...
            'FontSize',10,    'FontWeight','bold', ...
            'HorizontalAlignment','left', ...
            'FontName', fontname, 'FontSize',fontsize, ...
            'FontWeight',deblank(fontweights(weightindx,:)),...
            'FontAngle', deblank(fontangle(angleindx,:)));

        okbtn = uicontrol(fighndl,'Style','push', 'String','OK',...
            'Units','normalized', 'Position',[0.40 0.03 0.20 0.20],...
            'FontSize',10,    'FontWeight','bold', ...
            'HorizontalAlignment','left', ...
            'CallBack','delete(get(0,''CurrentFigure''))');

        set(fighndl,'Visible','on')
        uiwait(fighndl)
end

%-----------------------------------------------------------------------

function h = AxesmuiDialog(hndl)

%  AXESMUIDIALOG produces the main dialog box for the axesmui
%  function.  A rough cut of this code was generated using TOOLPAL
%  of the UITOOLS, and then the code was edited to produce the
%  desired interface.


%  Determine and insert page breaks into the name and idstring list.
%  Use key words of "Page Up" and "Page Down" to shift the popup
%  menu list.  This is necessary because X-Windows popup lists will
%  not scroll if the list exceeds the monitor window length

namestr = maps('namelist');    idstr   = maps('idlist');
classcodes = maps('classcodes');
colonstr = char(58*ones(size(classcodes,1),1));
blankstr = blanks(size(classcodes,1))';
namestr = [classcodes colonstr blankstr namestr];

newnames = namestr;
newids   = idstr;

%  Save the needed data as a structure to be placed in the popup
%  menu UserData slot.

listdata.idstr = newids;              listdata.namestr = newnames;

%  Save the associated axes handle and the current map data structure

h.axes = hndl;

%  Create the dialog window

h.fig = figure('Units','points',  'Position',[50 265 530 325], ...
    'Name','Projection Control', 'NumberTitle','off',...
    'Resize','off',...
    'WindowStyle','modal',...
    'MenuBar','none',...
    'Visible','off');

%
%adjust window position if corners are off screen
%
shiftwin(h.fig)

h.hiddenaxes = axes('Visible','off');

%  Projection Definition

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[10 290 340 30], ...
    'FontSize',10,  'FontWeight','bold');

h.projectionlabel = uicontrol(h.fig, 'Style','text', 'String','Map Projection', ...
    'Units','points',  'Position',[15 298 95 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.projection = uicontrol(h.fig, 'Style','popupmenu', ...
    'String',namestr, 'Value',1, ...
    'Units','points',  'Position',[115 295 225 20], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'UserData',listdata, ...
    'CallBack','axesmui(''MainDialog'',''Projection'')');

%  new code: Zone Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[360 290 165 30], ...
    'FontSize',10,  'FontWeight','bold');

h.zonebtn = uicontrol(h.fig, 'Style','push', 'String','Zone', 'Units','points', ...
    'Position',[380 295 60 20], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Zonebtn'')');

h.zone = uicontrol(h.fig, 'Style','edit', 'Units','points', ...
    'Position',[460 295 45 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','center', ...
    'CallBack','axesmui(''MainDialog'',''Zone'')');

%  new code: Geoid Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[10 250 340 30], ...
    'FontSize',10,  'FontWeight','bold');

h.geoidlabel = uicontrol(h.fig, 'Style','text', 'String','Geoid', ...
    'Units','points',  'Position',[15 258 40 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.geoid(1) = uicontrol(h.fig, 'Style','edit',  'Units','points', ...
    'Position',[60 255 65 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck''); axesmui(''MainDialog'',''Geoid'')');

h.geoid(2) = uicontrol(h.fig, 'Style','edit',  'Units','points', ...
    'Position',[135 255 65 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck''); axesmui(''MainDialog'',''Geoid'')');

h.geoidpop = uicontrol(h.fig, 'Style','popupmenu', 'String','place holder', ...
    'Units','points',  'Position',[210 255 130 20], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on',...
    'CallBack','axesmui(''MainDialog'',''Geoidpop'')');

%  Angle Units Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[360 250 165 30], ...
    'FontSize',10,  'FontWeight','bold');

h.anglelabel = uicontrol(h.fig, 'Style','text', 'String','Angle Units', ...
    'Units','points',  'Position',[365 258 74 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.angleunits = uicontrol(h.fig, 'Style','popupmenu', ...
    'String','degrees|radians', ...
    'Units','points',  'Position',[440 255 75 20], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on',...
    'CallBack','axesmui(''MainDialog'',''AngleUnits'')');

%  Map Limits Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[10 170 250 70], ...
    'FontSize',10,  'FontWeight','bold');

h.mlimitlabel = uicontrol(h.fig, 'Style','text', 'String','Map Limits', ...
    'Units','points',  'Position',[15 221 95 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.maplatlabel = uicontrol(h.fig, 'Style','text', 'String','Latitude', ...
    'Units','points',  'Position',[15 200 60 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.maplat(1) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[80 200 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.maplat(2) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[170 200 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.maplonlabel = uicontrol(h.fig, 'Style','text', 'String','Longitude', ...
    'Units','points',  'Position',[15 175 60 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.maplon(1) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[80 175 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.maplon(2) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[170 175 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

%  Frame Limits Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[275 170 250 70], ...
    'FontSize',10,  'FontWeight','bold');

h.flimitlabel = uicontrol(h.fig, 'Style','text', 'String','Frame Limits', ...
    'Units','points',  'Position',[280 221 95 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.frmlatlabel = uicontrol(h.fig, 'Style','text', 'String','Latitude', ...
    'Units','points',  'Position',[280 200 60 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.frmlat(1) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[345 200 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Tag','frminlat', ...
    'CallBack','axesmui(''numbercheck'')');

h.frmlat(2) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[435 200 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Tag','frmaxlat', ...
    'CallBack','axesmui(''numbercheck'')');

h.frmlonlabel = uicontrol(h.fig, 'Style','text', 'String','Longitude', ...
    'Units','points',  'Position',[280 175 60 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.frmlon(1) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[345 175 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Tag','frminlon', ...
    'CallBack','axesmui(''numbercheck'')');

h.frmlon(2) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[435 175 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Tag','frmaxlon', ...
    'CallBack','axesmui(''numbercheck'')');

%  Map Origin Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[10 90 250 70], ...
    'FontSize',10,  'FontWeight','bold');

h.originlabel = uicontrol(h.fig, 'Style','text', 'String','Map Origin', ...
    'Units','points',  'Position',[15 141 120 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.originlatlon = uicontrol(h.fig, 'Style','text', 'String','Lat and Long', ...
    'Units','points',  'Position',[15 120 80 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.origin(1) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[100 120 70 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.origin(2) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[180 120 70 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.orientation = uicontrol(h.fig, 'Style','text', 'String','Orientation', ...
    'Units','points',  'Position',[15 95 80 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.origin(3) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[100 95 70 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

%  new code: Cartesian Origin Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[275 90 250 70], ...
    'FontSize',10,  'FontWeight','bold');

h.paramlabel = uicontrol(h.fig, 'Style','text', 'String','Cartesian Origin', ...
    'Units','points',  'Position',[280 141 180 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.falseENlabel = uicontrol(h.fig, 'Style','text', 'String','False E and N', ...
    'Units','points',  'Position',[280 120 80 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.falseE = uicontrol(h.fig, 'Style','edit',  'Units','points', ...
    'Position',[365 120 70 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.falseN = uicontrol(h.fig, 'Style','edit',  'Units','points', ...
    'Units','points',  'Position',[445 120 70 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.sflabel = uicontrol(h.fig, 'Style','text', 'String','Scalefactor', ...
    'Units','points',  'Position',[280 95 80 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.sf = uicontrol(h.fig, 'Style','edit',  'Units','points', ...
    'Position',[365 95 70 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

%  Parallels Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[10 50 250 30], ...
    'FontSize',10,  'FontWeight','bold');

h.parallellabel = uicontrol(h.fig, 'Style','text', 'String','Parallels', ...
    'Units','points',  'Position',[15 57 60 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.parallel(1) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[80 55 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

h.parallel(2) = uicontrol(h.fig, 'Style','edit', 'String',' ', ...
    'Units','points',  'Position',[170 55 80 20], ...
    'FontSize',9,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','axesmui(''numbercheck'')');

%  Aspect Control

uicontrol(h.fig, 'Style','frame', ...
    'Units','points',  'Position',[275 50 250 30], ...
    'FontSize',10,  'FontWeight','bold');

h.aspectlbl = uicontrol(h.fig, 'Style','text', 'String','Aspect', ...
    'Units','points',  'Position',[280 55 60 15], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

h.aspect = uicontrol(h.fig, 'Style','popup', 'String','normal|transverse', ...
    'Units','points',  'Position',[345 55 120 20], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left');

%  Button Bar

h.framebtn = uicontrol(h.fig, 'Style','push', 'String','Frame', ...
    'Units','points',  'Position',[10 05 50 30], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Frame'')');

h.gridbtn = uicontrol(h.fig, 'Style','push', 'String','Grid', ...
    'Units','points',  'Position',[60 05 50 30], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Grid'')');

h.labelbtn = uicontrol(h.fig, 'Style','push', 'String','Labels', ...
    'Units','points',  'Position',[110 05 50 30], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Labels'')');

h.defaultbtn = uicontrol(h.fig, 'Style','push', 'String','Fill in', ...
    'Units','points',  'Position',[190 05 50 30], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Default'')');

h.resetbtn = uicontrol(h.fig, 'Style','push', 'String','Reset', ...
    'Units','points',  'Position',[240 05 50 30], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','left', 'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Reset'')');

%  Apply, Help and Cancel Buttons

h.apply = uicontrol(h.fig, 'Style','push', 'String','Apply', ...
    'Units','points',  'Position',[330 05 60 30], ...
    'FontSize',12,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','uiresume');

h.help = uicontrol(h.fig, 'Style','push', 'String','Help', ...
    'Units','points',  'Position',[395 05 60 30], ...
    'FontSize',12,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'Callback', @(~,~) helpdlg(tooltipHelpStrings('Help'), ...
        'axesmui Help'));

h.cancel = uicontrol(h.fig, 'Style','push', 'String','Cancel', ...
    'Units','points',  'Position',[460 05 60 30], ...
    'FontSize',12,  'FontWeight','bold', ...
    'HorizontalAlignment','left', ...
    'CallBack','uiresume');

%  Set up linked edit field user data for the numbercheck callback

set(h.maplat,'UserData',h.maplat)
set(h.maplon,'UserData',h.maplon)
set(h.frmlat,'UserData',h.frmlat)
set(h.frmlon,'UserData',h.frmlon)

% Set TooltipString values to provide help for certain UI elements

h = setMapAxesUITooltipStrings(h);

%  Save the GUI handles

set(h.fig,'Visible','on','UserData',h)

%-----------------------------------------------------------------------

function h = setMapAxesUITooltipStrings(h)
% Set TooltipString values to provide help for certain UI elements.

set(h.projectionlabel,'TooltipString', tooltipHelpStrings('Projection'))
set(h.geoidlabel,     'TooltipString', tooltipHelpStrings('Geoid'))
set(h.anglelabel,     'TooltipString', tooltipHelpStrings('ProjectionAngleUnits'))
set(h.maplatlabel,    'TooltipString', tooltipHelpStrings('MapLatLimits'))
set(h.maplonlabel,    'TooltipString', tooltipHelpStrings('MapLonLimits'))
set(h.frmlatlabel,    'TooltipString', tooltipHelpStrings('FrameLatLimits'))
set(h.frmlonlabel,    'TooltipString', tooltipHelpStrings('FrameLonLimits'))
set(h.originlatlon,   'TooltipString', tooltipHelpStrings('MapOrigin'))
set(h.orientation,    'TooltipString', tooltipHelpStrings('MapOrientation'))
set(h.falseENlabel,   'TooltipString', tooltipHelpStrings('MapFalseEandN'))
set(h.sflabel,        'TooltipString', tooltipHelpStrings('MapScalefactor'))
set(h.parallellabel,  'TooltipString', tooltipHelpStrings('MapParallel'))
set(h.aspectlbl,      'TooltipString', tooltipHelpStrings('MapAspect'))
set(h.zonebtn,        'TooltipString', tooltipHelpStrings('ZoneButton'))
set(h.framebtn,       'TooltipString', tooltipHelpStrings('FrameButton'))
set(h.gridbtn,        'TooltipString', tooltipHelpStrings('GridButton'))
set(h.labelbtn,       'TooltipString', tooltipHelpStrings('LabelButton'))
set(h.defaultbtn,     'TooltipString', tooltipHelpStrings('DefaultButton'))
set(h.resetbtn,       'TooltipString', tooltipHelpStrings('ResetButton'))
set(h.cancel,         'TooltipString', tooltipHelpStrings('CancelMain'))
set(h.apply,          'TooltipString', tooltipHelpStrings('Apply'))
set(h.help,           'TooltipString', tooltipHelpStrings('Help'))

%-----------------------------------------------------------------------

function h = FrameBox(mstruct)

%  FRAMEBOX will create the dialog box for editting Map Frame properties


%  Initialize the frame radio buttons

if strcmpi(mstruct.frame,'on')
    frameINIT = [1 0];
else
    frameINIT = [0 1];
end

%  Construct the color rgb values and popup menu items and
%  determine the edge or face colors

LineColors  = strvcat('custom','black','white','red','cyan','green',...
    'yellow','blue','magenta','none');
edgeclr.rgb = [NaN NaN NaN; 0 0 0; 1 1 1; 1 0 0; 0 1 1;
    0 1 0; 1 1 0; 0 0 1; 1 0 1;
    2 0 0];   % '2' signals  or 'none'
edgeclr.val = mstruct.fedgecolor;
faceclr.rgb = edgeclr.rgb;
faceclr.val = mstruct.ffacecolor;

%  Determine the initial value for the edge and face color popup menu

if ~ischar(edgeclr.val)
    edgepopup = find(edgeclr.rgb(:,1) == edgeclr.val(1) & ...
        edgeclr.rgb(:,2) == edgeclr.val(2) & ...
        edgeclr.rgb(:,3) == edgeclr.val(3) );
    if isempty(edgepopup); edgepopup = 1;  end      %  Initial custom color
else
    edgepopup = strmatch(edgeclr.val,LineColors);
    if all(edgeclr.rgb(edgepopup,:)>=0 & edgeclr.rgb(edgepopup,:)<=1)
        edgeclr.val = edgeclr.rgb(edgepopup,:);
    end
end

if ~ischar(faceclr.val)
    facepopup = find(faceclr.rgb(:,1) == faceclr.val(1) & ...
        faceclr.rgb(:,2) == faceclr.val(2) & ...
        faceclr.rgb(:,3) == faceclr.val(3) );
    if isempty(facepopup); facepopup = 1;  end      %  Initial custom color
else
    facepopup = strmatch(faceclr.val,LineColors);
    if all(faceclr.rgb(facepopup,:)>=0 & faceclr.rgb(facepopup,:)<=1)
        faceclr.val = faceclr.rgb(facepopup,:);
    end
end

%  Create the figure window.  Make window visible only after
%  all objects are drawn

h.fig = dialog('NumberTitle','off',   'Name','Map Frame Properties', ...
    'Units','points', 'Position',72*[2 3 4 3], ...
    'Resize','off',        'Visible','off');
%
%adjust window position if corners are off screen
%
shiftwin(h.fig)

%  Frame On/Off frame, title and radio buttons

h.frame = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.82 0.90 0.14]);

h.frametitle = uicontrol(h.fig, 'Style','text', 'String', 'Frame:', ...
    'Units','normalized', 'Position',[0.10 0.86 0.30 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

h.frameon = uicontrol(h.fig, 'Style','radio', 'String', 'On', ...
    'Units','normalized', 'Position',[0.45 0.85 0.20 0.08], ...
    'Value',frameINIT(1), ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

h.frameoff = uicontrol(h.fig, 'Style','radio', 'String', 'Off', ...
    'Units','normalized', 'Position',[0.70 0.85 0.20 0.08], ...
    'Value',frameINIT(2), ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

set(h.frameon,'UserData',h.frameoff)     %  Set userdata for callback operation
set(h.frameoff,'UserData',h.frameon)

%  Face and Edge Color Frame, Text and Popups

h.colorframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.52 0.90 0.25]);

h.facetext = uicontrol(h.fig,'Style','Text', 'String','Face Color:', ...
    'Units','Normalized', 'Position',[0.10  0.67  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.facecolor = uicontrol(h.fig,'Style','Popup', 'String',LineColors, ...
    'Units','Normalized', 'Position',[0.45  0.66  0.40  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','center', 'Value',facepopup, ...
    'UserData',faceclr, ...
    'Interruptible','on', 'CallBack','clrpopup');

h.edgetext = uicontrol(h.fig,'Style','Text', 'String','Edge Color:', ...
    'Units','Normalized', 'Position',[0.10  0.56  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.edgecolor = uicontrol(h.fig,'Style','Popup', 'String',LineColors, ...
    'Units','Normalized', 'Position',[0.45  0.55  0.40  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','center', 'Value',edgepopup, ...
    'UserData',edgeclr, ...
    'Interruptible','on', 'CallBack','clrpopup');

%  Edge Width & Fill Points frame, text and edit boxes

h.colorframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.22 0.90 0.25]);

h.widthtext = uicontrol(h.fig,'Style','Text', 'String','Edge Width (pts):', ...
    'Units','Normalized', 'Position',[0.10  0.37  0.40  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.widthedit = uicontrol(h.fig,'Style','edit', 'String',mstruct.flinewidth, ...
    'Units','Normalized', 'Position',[0.55  0.36  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',9, ...
    'HorizontalAlignment','left', 'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

h.filltext = uicontrol(h.fig,'Style','Text', 'String','Points per Edge:', ...
    'Units','Normalized', 'Position',[0.10  0.26  0.40  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.filledit = uicontrol(h.fig,'Style','edit', 'String',mstruct.ffill, ...
    'Units','Normalized', 'Position',[0.55  0.25  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',9, ...
    'HorizontalAlignment','left', 'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

%  Buttons to exit the modal dialog box

h.apply = uicontrol(h.fig, 'Style','push', 'String','Accept', ...
    'Units','normalized', 'Position',[0.10  0.02 0.24  0.15], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

h.cancel = uicontrol(h.fig, 'Style','push', 'String','Cancel', ...
    'Units','normalized', 'Position',[0.66  0.02 0.24  0.15], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

% Set TooltipString values to provide help for certain UI elements

h = setFrameDialogTooltipStrings(h);

%  Save the object handles and turn window on

set(h.fig,'Visible','on','UserData',h)

%-----------------------------------------------------------------------

function h = setFrameDialogTooltipStrings(h)
% Set TooltipString values to provide help for certain UI elements.

set(h.frametitle,  'TooltipString', tooltipHelpStrings('Frame'))
set(h.facetext,    'TooltipString', tooltipHelpStrings('FFaceColor'))
set(h.edgetext,    'TooltipString', tooltipHelpStrings('FEdgeColor'))
set(h.widthtext,   'TooltipString', tooltipHelpStrings('FWidth'))
set(h.filltext,    'TooltipString', tooltipHelpStrings('FFill'))
set(h.cancel,      'TooltipString', tooltipHelpStrings('Cancel'))
set(h.apply,       'TooltipString', tooltipHelpStrings('Accept'))

%-----------------------------------------------------------------------

function h = GridBox(mstruct)

%  GRIDBOX will create the dialog box for editting Map Grid properties


%  Initialize the grid radio buttons

if strcmp(mstruct.grid,'on')
    gridINIT = [1 0];
else
    gridINIT = [0 1];
end

%  Construct the line style property strings and popup menu items

LineStyleChar = strvcat('-','--',':','-.','none');
gridstyle     = strvcat('Solid','Dashed','Dotted','Dash-Dot','None');
gridval       = strmatch(mstruct.glinestyle,LineStyleChar,'exact');
if isempty(gridval);  gridval = 5;   end

%  Construct the color rgb values and popup menu items and
%  determine the line colors

LineColors  = strvcat('custom','black','white','red','cyan','green',...
    'yellow','blue','magenta');
gridclr.rgb = [NaN NaN NaN; 0 0 0; 1 1 1; 1 0 0; 0 1 1;
    0 1 0; 1 1 0; 0 0 1; 1 0 1];
gridclr.val = mstruct.gcolor;

%  Determine the initial value for the edge and face color popup menu

if ~ischar(gridclr.val)
    gridpopup = find(gridclr.rgb(:,1) == gridclr.val(1) & ...
        gridclr.rgb(:,2) == gridclr.val(2) & ...
        gridclr.rgb(:,3) == gridclr.val(3) );
    if isempty(gridpopup); gridpopup = 1;  end      %  Initial custom color
else
    gridpopup = strmatch(gridclr.val,LineColors);
end

%  Create the figure window.  Make window visible only after
%  all objects are drawn

h.fig = dialog('NumberTitle','off',   'Name','Map Grid Properties', ...
    'Units','points', 'Position',72*[2 3 4 3], ...
    'Resize','off',        'Visible','off');

%
%adjust window position if corners are offscreen
%
shiftwin(h.fig)

%  Create a hidden axes to store the current map structure.  This is
%  necessary since the meridians and parallels button may alter
%  the properties while waiting on this dialog label.

h.hiddenaxes = axes('Visible','off','UserData',mstruct);

%  Grid On/Off frame, title and radio buttons

h.gridframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.82 0.90 0.14]);

h.gridtitle = uicontrol(h.fig, 'Style','text', 'String', 'Grid:', ...
    'Units','normalized', 'Position',[0.10 0.86 0.30 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

h.gridon = uicontrol(h.fig, 'Style','radio', 'String', 'On', ...
    'Units','normalized', 'Position',[0.45 0.85 0.20 0.08], ...
    'Value',gridINIT(1), ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

h.gridoff = uicontrol(h.fig, 'Style','radio', 'String', 'Off', ...
    'Units','normalized', 'Position',[0.70 0.85 0.20 0.08], ...
    'Value',gridINIT(2), ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

set(h.gridon,'UserData',h.gridoff)     %  Set userdata for callback operation
set(h.gridoff,'UserData',h.gridon)

%  Grid Properties, Text and Popups

h.propframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.30 0.90 0.47]);

h.colortext = uicontrol(gcf,'Style','Text', 'String','Color:', ...
    'Units','Normalized', 'Position',[0.10  0.67  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.color = uicontrol(h.fig,'Style','Popup', 'String',LineColors, ...
    'Units','Normalized', 'Position',[0.45  0.66  0.40  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','center', 'Value',gridpopup, ...
    'UserData',gridclr, ...
    'Interruptible','on', 'CallBack','clrpopup');

h.styletext = uicontrol(h.fig,'Style','Text', 'String','Style:', ...
    'Units','Normalized', 'Position',[0.10  0.56  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.style = uicontrol(h.fig,'Style','Popup', 'String',gridstyle, ...
    'Units','Normalized', 'Position',[0.45  0.55  0.40  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','center', 'Value',gridval, ...
    'UserData',LineStyleChar);

h.widthtext = uicontrol(h.fig,'Style','Text', 'String','Line Width (pts):', ...
    'Units','Normalized', 'Position',[0.10  0.45  0.40  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.widthedit = uicontrol(h.fig,'Style','edit', 'String',mstruct.glinewidth, ...
    'Units','Normalized', 'Position',[0.55  0.44  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',9, ...
    'HorizontalAlignment','left', 'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

h.alttext = uicontrol(h.fig,'Style','Text', 'String','Grid Altitude:', ...
    'Units','Normalized', 'Position',[0.10  0.34  0.40  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.altedit = uicontrol(h.fig,'Style','edit', 'String',mstruct.galtitude, ...
    'Units','Normalized', 'Position',[0.55  0.33  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',9, ...
    'HorizontalAlignment','left', 'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

%  Parallels and Meridians Button

h.settings = uicontrol(h.fig, 'Style','push', ...
    'String','Meridian and Parallel Settings', ...
    'Units','normalized', 'Position',[0.10  0.16 0.80  0.11], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''Meridian&Parallel'')');

%  Buttons to exit the modal dialog box

h.apply = uicontrol(h.fig, 'Style','push', 'String','Accept', ...
    'Units','normalized', 'Position',[0.10  0.01 0.24  0.12], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

h.cancel = uicontrol(h.fig, 'Style','push', 'String','Cancel', ...
    'Units','normalized', 'Position',[0.66  0.01 0.24  0.12], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

% Set TooltipString values to provide help for certain UI elements

h = setGridDialogTooltipStrings(h);

%  Save the object handles and turn window on

set(h.fig,'Visible','on', 'UserData',h)  %  UserData needed for settings callback

%-----------------------------------------------------------------------

function h = setGridDialogTooltipStrings(h)

set(h.gridtitle, 'TooltipString', tooltipHelpStrings('Grid'))
set(h.colortext, 'TooltipString', tooltipHelpStrings('GridColor'))
set(h.styletext, 'TooltipString', tooltipHelpStrings('GridStyle'))
set(h.widthtext, 'TooltipString', tooltipHelpStrings('GWidth'))
set(h.alttext,   'TooltipString', tooltipHelpStrings('GAltitude'))
set(h.settings,  'TooltipString', tooltipHelpStrings('GridSettings'))
set(h.cancel,    'TooltipString', tooltipHelpStrings('Cancel'))
set(h.apply,     'TooltipString', tooltipHelpStrings('Accept'))

%-----------------------------------------------------------------------

function h = GridPropBox(mstruct)

%  GRIDPROPBOX will create the dialog box for editting Meridian and
%  Parallel properties


%  Initialize the meridian and parallel radio buttons

if strcmp(mstruct.mlinevisible,'on')
    meridianINIT = [1 0];
else
    meridianINIT = [0 1];
end
if strcmp(mstruct.plinevisible,'on')
    parallelINIT = [1 0];
else
    parallelINIT = [0 1];
end

%  Create the figure window.  Make window visible only after
%  all objects are drawn

h.fig = dialog('NumberTitle','off',   'Name','Meridian and Parallel Properties', ...
    'Units','points', 'Position',72*[1 2 7 4], ...
    'Resize','off',        'Visible','off');

%
%adjust window position if corners are offscreen
%
shiftwin(h.fig)

%  Meridians frame and title

h.mframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.02 0.17 0.47 0.79]);

h.mtitle = uicontrol(h.fig, 'Style','text', 'String', 'Meridians:', ...
    'Units','normalized', 'Position',[0.05 0.87 0.20 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

h.meridianon = uicontrol(h.fig, 'Style','radio', 'String', 'On', ...
    'Units','normalized', 'Position',[0.26 0.87 0.1 0.08], ...
    'Value',meridianINIT(1), ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

h.meridianoff = uicontrol(h.fig, 'Style','radio', 'String', 'Off', ...
    'Units','normalized', 'Position',[0.35 0.87 0.1 0.08], ...
    'Value',meridianINIT(2), ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

set(h.meridianon,'UserData',h.meridianoff)     %  Set userdata for callback operation
set(h.meridianoff,'UserData',h.meridianon)

%  Longitude location text and edit

h.longtext = uicontrol(h.fig,'Style','text', 'String','Longitude Location(s):', ...
    'Units','Normalized', 'Position',[0.05  0.79  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.longedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.mlinelocation(:)'), ...
    'Units','Normalized', 'Position',[0.05  0.66  0.41  0.12], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',2, ...
    'CallBack','axesmui(''numbercheck'')');

%  Limits text, labels and edits

h.mlimits = uicontrol(h.fig, 'Style','text', 'String', 'Latitude Limits:', ...
    'Units','normalized', 'Position',[0.05 0.58 0.30 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

h.mlimitedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.mlinelimit), ...
    'Units','Normalized', 'Position',[0.05  0.50  0.41  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left', 'Max',1,...
    'CallBack','axesmui(''numbercheck'')');

%  Longitude exceptions text and edits

h.longexctext = uicontrol(h.fig,'Style','text', 'String','Longitude Exceptions:', ...
    'Units','Normalized', 'Position',[0.05  0.41  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.longexcedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.mlineexception), ...
    'Units','Normalized', 'Position',[0.05  0.28  0.41  0.12], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',2, ...
    'CallBack','axesmui(''numbercheck'')');

%  Points per meridian text and edit

h.mfilltext = uicontrol(h.fig,'Style','text', 'String','Points per Line:', ...
    'Units','Normalized', 'Position',[0.05  0.19  0.21  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.mfilledit = uicontrol(h.fig,'Style','edit', 'String',mstruct.mlinefill, ...
    'Units','Normalized', 'Position',[0.27  0.20  0.19  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left', 'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

%  Parallels frame and title

h.pframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.51 0.17 0.47 0.79]);

h.ptitle = uicontrol(h.fig, 'Style','text', 'String', 'Parallels:', ...
    'Units','normalized', 'Position',[0.54 0.87 0.20 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

h.parallelon = uicontrol(h.fig, 'Style','radio', 'String', 'On', ...
    'Units','normalized', 'Position',[0.75 0.87 0.10 0.08], ...
    'Value',parallelINIT(1), ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

h.paralleloff = uicontrol(h.fig, 'Style','radio', 'String', 'Off', ...
    'Units','normalized', 'Position',[0.84 0.87 0.10 0.08], ...
    'Value',parallelINIT(2), ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

set(h.parallelon,'UserData',h.paralleloff)     %  Set userdata for callback operation
set(h.paralleloff,'UserData',h.parallelon)

%  Latitude location text and edit

h.lattext = uicontrol(h.fig,'Style','text', 'String','Latitude Location(s):', ...
    'Units','Normalized', 'Position',[0.54  0.79  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.latedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.plinelocation), ...
    'Units','Normalized', 'Position',[0.54  0.66  0.41  0.12], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',2, ...
    'CallBack','axesmui(''numbercheck'')');

%  Limits text, labels and edits

h.plimits = uicontrol(h.fig, 'Style','text', 'String', 'Longitude Limits:', ...
    'Units','normalized', 'Position',[0.54 0.58 0.30 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

h.plimitedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.plinelimit), ...
    'Units','Normalized', 'Position',[0.54  0.50  0.41  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left', 'Max',1,...
    'CallBack','axesmui(''numbercheck'')');

%  Latitude exceptions text and edits

h.latexctext = uicontrol(h.fig,'Style','text', 'String','Latitude Exceptions:', ...
    'Units','Normalized', 'Position',[0.54  0.41  0.30  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.latexcedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.plineexception), ...
    'Units','Normalized', 'Position',[0.54  0.28  0.41  0.12], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',2, ...
    'CallBack','axesmui(''numbercheck'')');

%  Points per parallel text and edit

h.pfilltext = uicontrol(h.fig,'Style','text', 'String','Points per Line:', ...
    'Units','Normalized', 'Position',[0.54  0.19  0.21  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.pfilledit = uicontrol(h.fig,'Style','edit', 'String',mstruct.plinefill, ...
    'Units','Normalized', 'Position',[0.76  0.20  0.19  0.07], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left', 'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

%  Buttons to exit the modal dialog box

h.apply = uicontrol(h.fig, 'Style','push', 'String','Accept', ...
    'Units','normalized', 'Position',[0.28  0.03 0.12  0.10], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

h.cancel = uicontrol(h.fig, 'Style','push', 'String','Cancel', ...
    'Units','normalized', 'Position',[0.60  0.03 0.12  0.10], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

% Set TooltipString values to provide help for certain UI elements

h = setGridSettingsDialogTooltipStrings(h);

%  Turn window on

set(h.fig,'Visible','on','UserData',h)

%-----------------------------------------------------------------------

function h = setGridSettingsDialogTooltipStrings(h)

set(h.mtitle,      'TooltipString', tooltipHelpStrings('MeridianGrids'))
set(h.longtext,    'TooltipString', tooltipHelpStrings('MLocationGrids'))
set(h.mlimits,     'TooltipString', tooltipHelpStrings('MeridianLimits'))
set(h.longexctext, 'TooltipString', tooltipHelpStrings('MeridianExceptions'))
set(h.mfilltext,   'TooltipString', tooltipHelpStrings('MeridianFill'))
set(h.ptitle,      'TooltipString', tooltipHelpStrings('ParallelGrids'))
set(h.lattext,     'TooltipString', tooltipHelpStrings('PLocationGrids'))
set(h.plimits,     'TooltipString', tooltipHelpStrings('ParallelLimits'))
set(h.latexctext,  'TooltipString', tooltipHelpStrings('ParallelExceptions'))
set(h.pfilltext,   'TooltipString', tooltipHelpStrings('ParallelFill'))
set(h.cancel,      'TooltipString', tooltipHelpStrings('Cancel'))
set(h.apply,       'TooltipString', tooltipHelpStrings('Accept'))

%-----------------------------------------------------------------------

function h = LabelBox(mstruct)

%  LABELBOX will create the dialog box for editing Map Label properties


%  Initialize the meridian and parallel radio buttons

if strcmp(mstruct.meridianlabel,'on')
    meridianINIT = [1 0];
else
    meridianINIT = [0 1];
end
if strcmp(mstruct.parallellabel,'on')
    parallelINIT = [1 0];
else
    parallelINIT = [0 1];
end

%  Initialize the label format popup menu

labelformats = strvcat('compass','signed','none');
formatindx = strmatch(mstruct.labelformat,labelformats);

%  Initialize the label format popup menu

labelunits = strvcat('degrees','radians');
unitindx = strmatch(mstruct.labelunits,labelunits,'exact');

%  Construct the color rgb values and popup menu items and
%  determine the line colors

FontColors  = strvcat('custom','black','white','red','cyan','green',...
    'yellow','blue','magenta');
fontclr.rgb = [NaN NaN NaN; 0 0 0; 1 1 1; 1 0 0; 0 1 1;
    0 1 0; 1 1 0; 0 0 1; 1 0 1];
fontclr.val = mstruct.fontcolor;

%  Determine the initial value for the edge and face color popup menu

if ~ischar(fontclr.val)
    fontpopup = find(fontclr.rgb(:,1) == fontclr.val(1) & ...
        fontclr.rgb(:,2) == fontclr.val(2) & ...
        fontclr.rgb(:,3) == fontclr.val(3) );
    if isempty(fontpopup); fontpopup = 1;  end      %  Initial custom color
else
    fontpopup = strmatch(fontclr.val,FontColors);
end

%  Initialize the font unit popup menu

fontunits = strvcat('inches','centimeters','normalized','points','pixels');
fontunitsindx = strmatch(mstruct.fontunits,fontunits);

%  Determine the font weight popup menu value

weights = strvcat('normal','bold','demi','light');
wtindx = strmatch(mstruct.fontweight,weights);

%  Determine the font angle popup menu value

angles = strvcat('normal','italic','oblique');
anglindx = strmatch(mstruct.fontangle,angles);


%  Create the figure window.  Make window visible only after
%  all objects are drawn

h.fig = dialog('NumberTitle','off',   'Name','Map Label Properties', ...
    'Units','points', 'Position',72*[2 2.5 5 3.5], ...
    'Resize','off',        'Visible','on');

%
%adjust window position if corners are off screen
%
shiftwin(h.fig)

%  Create a hidden axes to store the current map structure.  This is
%  necessary since the meridians and parallels button may alter
%  the properties while waiting on this dialog window.

h.hiddenaxes = axes('Visible','off','UserData',mstruct);

%  Label frame

h.labelframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.75 0.90 0.21]);

%  Meridian label title and radio buttons

h.meridiantitle = uicontrol(h.fig, 'Style','text', 'String', 'Meridian:', ...
    'Units','normalized', 'Position',[0.07 0.87 0.17 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.meridianon = uicontrol(h.fig, 'Style','radio', 'String', 'On', ...
    'Units','normalized', 'Position',[0.25 0.87 0.12 0.08], ...
    'Value',meridianINIT(1), ...
    'FontSize',9,  'FontWeight', 'bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

h.meridianoff = uicontrol(h.fig, 'Style','radio', 'String', 'Off', ...
    'Units','normalized', 'Position',[0.37 0.87 0.12 0.08], ...
    'Value',meridianINIT(2), ...
    'FontSize',9,  'FontWeight','bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

set(h.meridianon,'UserData',h.meridianoff)     %  Set userdata for callback operation
set(h.meridianoff,'UserData',h.meridianon)

%  Parallel label title and radio buttons

h.paralleltitle = uicontrol(h.fig, 'Style','text', 'String', 'Parallel:', ...
    'Units','normalized', 'Position',[0.52 0.87 0.17 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.parallelon = uicontrol(h.fig, 'Style','radio', 'String', 'On', ...
    'Units','normalized', 'Position',[0.70 0.87 0.12 0.08], ...
    'Value',parallelINIT(1), ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

h.paralleloff = uicontrol(h.fig, 'Style','radio', 'String', 'Off', ...
    'Units','normalized', 'Position',[0.82 0.87 0.12 0.08], ...
    'Value',parallelINIT(2), ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left', ...
    'CallBack',...
    'set(gco,''Value'',1);set(get(gco,''UserData''),''Value'',0)');

set(h.parallelon,'UserData',h.paralleloff)     %  Set userdata for callback operation
set(h.paralleloff,'UserData',h.parallelon)

%  Label format title and popup

h.formattitle = uicontrol(h.fig, 'Style','text', 'String', 'Format:', ...
    'Units','normalized', 'Position',[0.07 0.77 0.17 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.format = uicontrol(h.fig, 'Style','popup', 'String', labelformats, ...
    'Units','normalized', 'Position',[0.25 0.77 0.24 0.08], ...
    'Value',formatindx, ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left');

%  Label units title and popup

h.unitstitle = uicontrol(h.fig, 'Style','text', 'String', 'Units:', ...
    'Units','normalized', 'Position',[0.52 0.77 0.17 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.units = uicontrol(h.fig, 'Style','popup', 'String', labelunits, ...
    'Units','normalized', 'Position',[0.70 0.77 0.23 0.08], ...
    'Value',unitindx, ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left');

%  Font frame

h.labelframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.05 0.38 0.90 0.32]);

%  Font Name Edit Box

h.fonttitle = uicontrol(h.fig, 'Style','push', 'String', 'Font:', ...
    'Units','normalized', 'Position',[0.07 0.60 0.12 0.08], ...
    'FontSize',10,  'FontWeight','bold', ...
    'HorizontalAlignment','center', 'Interruptible','on',...
    'CallBack','axesmui(''MainDialog'',''FontPreview'')');

h.fontedit = uicontrol(h.fig, 'Style','edit', 'String', mstruct.fontname, ...
    'Units','normalized', 'Position',[0.20 0.60 0.34 0.08], ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left');

%  Font Size Edit Box

h.sizetitle = uicontrol(h.fig, 'Style','text', 'String', 'Size:', ...
    'Units','normalized', 'Position',[0.59 0.60 0.10 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.sizeedit = uicontrol(h.fig, 'Style','edit', 'String', mstruct.fontsize, ...
    'Units','normalized', 'Position',[0.71 0.60 0.15 0.08], ...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left',...
    'CallBack','axesmui(''numbercheck'')');

%  Font Color title and popup menu

h.fontclrtitle = uicontrol(h.fig, 'Style','text', 'String', 'Color:', ...
    'Units','normalized', 'Position',[0.07 0.50 0.14 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.fontclr = uicontrol(h.fig, 'Style','popup', 'String', FontColors, ...
    'Units','normalized', 'Position',[0.22 0.50 0.25 0.08], ...
    'Value',fontpopup,...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left',...
    'UserData',fontclr, 'CallBack','clrpopup');

%  Font units title and popup menu

h.fontunitstitle = uicontrol(h.fig, 'Style','text', 'String', 'Units:', ...
    'Units','normalized', 'Position',[0.50 0.50 0.12 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.fontunits = uicontrol(h.fig, 'Style','popup', 'String', fontunits, ...
    'Units','normalized', 'Position',[0.63 0.50 0.30 0.08], ...
    'Value',fontunitsindx,...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left');

%  Font Weight title and popup menu

h.fontwttitle = uicontrol(h.fig, 'Style','text', 'String', 'Weight:', ...
    'Units','normalized', 'Position',[0.07 0.40 0.14 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.fontwt = uicontrol(h.fig, 'Style','popup', 'String', weights, ...
    'Units','normalized', 'Position',[0.22 0.40 0.25 0.08], ...
    'Value',wtindx,...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left');

%  Font angle title and popup menu

h.fontangtitle = uicontrol(h.fig, 'Style','text', 'String', 'Angle:', ...
    'Units','normalized', 'Position',[0.50 0.40 0.12 0.07], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','right');

h.fontangle = uicontrol(h.fig, 'Style','popup', 'String', angles, ...
    'Units','normalized', 'Position',[0.63 0.40 0.30 0.08], ...
    'Value',anglindx,...
    'FontSize',10,  'FontWeight', 'bold', 'HorizontalAlignment','left');

%  Parallels and Meridians Button

h.settings = uicontrol(h.fig, 'Style','push', ...
    'String','Meridian and Parallel Settings', ...
    'Units','normalized', 'Position',[0.10  0.20 0.80  0.11], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'Interruptible','on', ...
    'CallBack','axesmui(''MainDialog'',''LabelSettings'')');

%  Buttons to exit the modal dialog box

h.apply = uicontrol(h.fig, 'Style','push', 'String','Accept', ...
    'Units','normalized', 'Position',[0.10  0.03 0.24  0.12], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

h.cancel = uicontrol(h.fig, 'Style','push', 'String','Cancel', ...
    'Units','normalized', 'Position',[0.66  0.03 0.24  0.12], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

% Set TooltipString values to provide help for certain UI elements

h = setLabelDialogTooltipStrings(h);

%  Save the object handles and turn window on

set(h.fig,'Visible','on', 'UserData',h)  %  UserData needed for settings callback

%-----------------------------------------------------------------------

function h = setLabelDialogTooltipStrings(h)

set(h.meridiantitle,  'TooltipString', tooltipHelpStrings('MeridianLabels'))
set(h.paralleltitle,  'TooltipString', tooltipHelpStrings('ParallelLabels'))
set(h.formattitle,    'TooltipString', tooltipHelpStrings('LabelFormat'))
set(h.unitstitle,     'TooltipString', tooltipHelpStrings('LabelUnits'))
set(h.fonttitle,      'TooltipString', tooltipHelpStrings('LabelFont'))
set(h.sizetitle,      'TooltipString', tooltipHelpStrings('LabelSize'))
set(h.fontunitstitle, 'TooltipString', tooltipHelpStrings('LabelFontUnits'))
set(h.fontclrtitle,   'TooltipString', tooltipHelpStrings('LabelColor'))
set(h.fontwttitle,    'TooltipString', tooltipHelpStrings('LabelWeight'))
set(h.fontangtitle,   'TooltipString', tooltipHelpStrings('LabelAngle'))
set(h.settings,       'TooltipString', tooltipHelpStrings('LabelSettings'))
set(h.cancel,         'TooltipString', tooltipHelpStrings('Cancel'))
set(h.apply,          'TooltipString', tooltipHelpStrings('Accept'))

%-----------------------------------------------------------------------

function h = LabelPropBox(mstruct)

%  LABELPROPBOX will create the dialog box for editting Meridian and
%  Parallel label properties


%  Create the figure window.  Make window visible only after
%  all objects are drawn

h.fig = dialog('NumberTitle','off',   'Name','Meridian and Parallel Label Properties', ...
    'Units','points', 'Position',72*[1 3 7 3], ...
    'Resize','off',        'Visible','on');

%
%adjust window position if corners are off screen
%
shiftwin(h.fig)

%  Meridian labels frame and title

h.mframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.02 0.27 0.47 0.69]);

h.mtitle = uicontrol(h.fig, 'Style','text', 'String', 'Meridians Labels:', ...
    'Units','normalized', 'Position',[0.05 0.86 0.25 0.08], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

%  Longitude location text and edit

h.mlocatetext = uicontrol(h.fig,'Style','text', 'String','Longitude Location(s):', ...
    'Units','Normalized', 'Position',[0.05  0.76  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.mlocateedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.mlabellocation(:)'), ...
    'Units','Normalized', 'Position',[0.05  0.63  0.41  0.12], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',2, ...
    'CallBack','axesmui(''numbercheck'')');

%  Display latitude title, popup and edit

h.mparalleltext = uicontrol(h.fig,'Style','text', 'String','Display Parallel:', ...
    'Units','Normalized', 'Position',[0.05  0.53  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.mparallelpopup = uicontrol(h.fig,'Style','popup', 'String','north|south|equator', ...
    'Units','Normalized', 'Position',[0.05  0.42  0.20  0.09], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Value',1, ...
    'CallBack','set(get(gco,''UserData''),''String'','''')');

h.mparalleledit = uicontrol(h.fig,'Style','edit', ...
    'String',mstruct.mlabelparallel, ...
    'Units','Normalized', 'Position',[0.27  0.42  0.18  0.09], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',1, ...
    'UserData',h.mparallelpopup,...
    'CallBack',['if isempty(get(gco,''String''));',...
    'set(get(gco,''UserData''),''Enable'',''on'');',...
    'else;set(get(gco,''UserData''),''Enable'',''off'');end']);
set(h.mparallelpopup,'UserData',h.mparalleledit)

%  Meridian rounding title and edit

h.mroundtext = uicontrol(h.fig,'Style','text', 'String','Decimal Round:', ...
    'Units','Normalized', 'Position',[0.05  0.29  0.20  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.mroundedit = uicontrol(h.fig,'Style','edit', 'String',mstruct.mlabelround, ...
    'Units','Normalized', 'Position',[0.27  0.29  0.10  0.09], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

%  Parallel labels frame and title

h.pframe = uicontrol(h.fig, 'Style','frame', ...
    'Units','normalized', 'Position',[0.51 0.27 0.47 0.69]);

h.ptitle = uicontrol(h.fig, 'Style','text', 'String', 'Parallel Labels:', ...
    'Units','normalized', 'Position',[0.54 0.86 0.25 0.08], ...
    'FontSize',10,  'FontWeight','bold', 'HorizontalAlignment','left');

%  Longitude location text and edit

h.plocatetext = uicontrol(h.fig,'Style','text', 'String','Latitude Location(s):', ...
    'Units','Normalized', 'Position',[0.54  0.76  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.plocateedit = uicontrol(h.fig,'Style','edit', 'String',num2str(mstruct.plabellocation(:)'), ...
    'Units','Normalized', 'Position',[0.54  0.63  0.41  0.12], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',2, ...
    'CallBack','axesmui(''numbercheck'')');

%  Display longitude title, popup and edit

h.pmeridiantext = uicontrol(h.fig,'Style','text', 'String','Display Meridian:', ...
    'Units','Normalized', 'Position',[0.54  0.53  0.30  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.pmeridianpopup = uicontrol(h.fig,'Style','popup', 'String','east|west|prime', ...
    'Units','Normalized', 'Position',[0.54  0.42  0.20  0.09], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Value',1, ...
    'CallBack','set(get(gco,''UserData''),''String'','''')');

h.pmeridianedit = uicontrol(h.fig,'Style','edit', ...
    'String',mstruct.plabelmeridian, ...
    'Units','Normalized', 'Position',[0.76  0.42  0.18  0.09], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',1, ...
    'UserData',h.pmeridianpopup,...
    'CallBack',['if isempty(get(gco,''String''));',...
    'set(get(gco,''UserData''),''Enable'',''on'');',...
    'else;set(get(gco,''UserData''),''Enable'',''off'');end']);
set(h.pmeridianpopup,'UserData',h.pmeridianedit)

%  Parallel rounding title and edit

h.proundtext = uicontrol(h.fig,'Style','text', 'String','Decimal Round:', ...
    'Units','Normalized', 'Position',[0.54  0.29  0.20  0.08], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left');

h.proundedit = uicontrol(h.fig,'Style','edit', 'String',mstruct.plabelround, ...
    'Units','Normalized', 'Position',[0.76  0.29  0.10  0.09], ...
    'FontWeight','bold',  'FontSize',10, ...
    'HorizontalAlignment','left',  'Max',1, ...
    'CallBack','axesmui(''numbercheck'')');

%  Buttons to exit the modal dialog box

h.apply = uicontrol(h.fig, 'Style','push', 'String','Accept', ...
    'Units','normalized', 'Position',[0.28  0.06 0.12  0.15], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

h.cancel = uicontrol(h.fig, 'Style','push', 'String','Cancel', ...
    'Units','normalized', 'Position',[0.60  0.06 0.12  0.15], ...
    'FontName','Helvetica', 'FontSize',10, 'FontWeight','bold', ...
    'CallBack','uiresume');

% Set TooltipString values to provide help for certain UI elements

h = setLabelSettingsDialogTooltipStrings(h);

set(h.fig,'Visible','on','UserData',h)

%-----------------------------------------------------------------------

function h = setLabelSettingsDialogTooltipStrings(h)

set(h.mlocatetext,   'TooltipString', tooltipHelpStrings('MeridianLocation'))
set(h.mparalleltext, 'TooltipString', tooltipHelpStrings('MParallel'))
set(h.mroundtext,    'TooltipString', tooltipHelpStrings('Round'))
set(h.plocatetext,   'TooltipString', tooltipHelpStrings('ParallelLocation'))
set(h.pmeridiantext, 'TooltipString', tooltipHelpStrings('PMeridian'))
set(h.proundtext,    'TooltipString', tooltipHelpStrings('Round'))
set(h.cancel,        'TooltipString', tooltipHelpStrings('Cancel'))
set(h.apply,         'TooltipString', tooltipHelpStrings('Accept'))

%-----------------------------------------------------------------------

function mstruct = mapangles(mstruct,oldunits)

% Restore the old units, then use private/setAngleUnits.
newunits = mstruct.angleunits;
mstruct.angleunits = oldunits;
mstruct = setAngleUnits(mstruct,newunits);

%-----------------------------------------------------------------------

function str = tooltipHelpStrings(uiControlName)
% Return help strings

str2 = '';
str3 = '';
switch(uiControlName)
    
case 'Projection'              %  Help for map projection popup menu
	str1 = ['This popup displays the available map projections.  Specifying ',...
            'the projection determines the transformation calculations and ',...
            'the resulting properties of the displayed map.  This list contains ',...
            'all the projections contained in the Mapping Toolbox. Projections ',...
            'are listed by type: Cyln=Cylindrical, Pycl=Pseudocylindrical, ',...
            'Coni=Conic, Poly=Polyconic, Pcon=Pseudoconic, ',...
            'Azim=Azimuthal, Pazi=Pseudoazimuthal, Mazi=Modified Azimuthal.'];

case 'ZoneButton'              %  Help for zone pick interface
	str1 = ['The Zone property defines the geographic zone coverage for ',...
			'UTM and UPS projections.'];
	str2 = ['Pressing the zone push button will bring up an interface for ',...
			'choosing a UTM zone on a world map display.  The zone edit ',...
			'box can be used to enter valid UTM or UPS zone designations.  ',...
			'Recognized UTM zones are integers from 1 to 60 or numbers followed ',...
			'by letters from C to X.  There are two UPS zones: north and south.'];

case 'Geoid'              %  Help for geoid edit boxes and popup menu
	str1 = ['The Geoid parameter defines the ellipsoidal model of the Earth used in ',...
			'the projection calculations. The Geoid parameter is of the form ',...
			'[semimajor-axis eccentricity]. Projected coordinates are in the units ',...
			'of the semi-major axis. '];
	str2 = ['The Geoid parameter can be specified in the edit boxes or using the popup menu. ',...
			'For UTM and UPS projections, the default units are in meters.  All other ',...
	        'projections default to kilometers.'];
	str3 = ['For UTM projections, asterisks are shown next to the geoid ',...
	        'definitions that are recommended for a particular zone.'];


case 'ProjectionAngleUnits'    %  Help for projection angle units popup menu
	str1 = ['Use this popup to define the angle units used in the ',...
	        'map projection.  All angles entered in the Projection ',...
			  'Control dialog boxes must be supplied in the specified units.'];
	str2 = ['If the angle units are changed, this has no effect on the ',...
	        'current map display, although the dialog entries will be ',...
			  'updated to reflect the new units.  However, all subsequent ',...
			  'data projected on the map must be supplied in the specified ',...
			  'units.'];

case 'MapAspect'    %  Help for Map Aspect popup menu
	str1 = ['This property controls the orientation of the base projection ',...
	        'on a page.  When aspect is normal, "north" (on the base projection) ',...
			  'is up.  In transverse aspect, "north" (in the base projection) ',...
			  'is to the right.'];
	str2 = ['A cylindrical projection of the whole ',...
	        'world looks like a "landscape" display under normal aspect, and ',...
			  'like a "portrait" under a transverse aspect.'];
	str3 = ['Use a Map Origin Orientation of -90 degrees with a transverse aspect ',...
			'to create a standard transverse projection.' ];

case 'MapLatLimits'    %  Help for Map Latitude Limits
	str1 = ['The Map Latitude Limit property controls the north and south ',...
	        'latitude of the map display.  The north and south latitudes ',...
			  'establish the extent of meridian lines, regardless of the ',...
			  'Meridian Limit Property (See Grid Settings). They also ',...
			  'specify the default coverage of matrix maps and default parallels.'];
	str2 = ['The extent of the map data is always measured in Greenwich ',...
	        'coordinates, regardless of the origin and orientation setting.'];
	str3 = ['In the normal aspect, the map display is trimmed to the minimum ',...
			'of the Map and Frame Limits.'];

case 'MapLonLimits'    %  Help for Map Longitude Limits
	str1 = ['The Map Longitude Limit property controls the east and west ',...
	        'longitude of the map display.  The east and west longitudes ',...
			  'establish the extent of parallel lines, regardless of the ',...
			  'Parallel Limit Property (See Grid Settings). They also ',...
			  'specify the default coverage of matrix maps.'];
	str2 = ['The extent of the map data is always measured in Greenwich ',...
	        'coordinates, regardless of the origin and orientation setting.'];
	str3 = ['In the normal aspect, the map display is trimmed to the minimum ',...
			'of the Map and Frame Limits.'];

case 'FrameLatLimits'    %  Help for Frame Latitude Limits
	str1 = ['The Frame Latitude Limit property controls the north and south ',...
	        'extent of the frame display.  All map data will be trimmed ',...
			  'at the specified frame limits.  For azimuthal projections, the ',...
			  'latitude limits should be set to -inf and the desired trim distance ',...
			  'from the map origin.'];
	str2 = ['The Frame Limits are always measured in the base projection ',...
	        'system.  Angles are from the ',...
	        'Map Origin at the center of the frame.'];
	str3 = ['In the normal aspect, the map display is trimmed to the minimum ',...
			'of the Map and Frame Limits.'];

case 'FrameLonLimits'    %  Help for Frame Longitude Limits
	str1 = ['The Frame Longitude Limit property controls the east and west ',...
	        'extent of the frame display.  All map data will be trimmed ',...
			  'at the specified frame limits.'];
	str2 = ['The Frame Limits are always measured in the base projection ',...
	        'system.  Angles are from the ',...
	        'Map Origin at the center of the frame.'];
	str3 = ['In the normal aspect, the map display is trimmed to the minimum ',...
			'of the Map and Frame Limits.'];

case 'MapOrigin'    %  Help for Map Origin edit boxes
	str1 = ['The Map Origin specifies the Greenwich point which is placed ',...
	        'in the center of the base projection.  The latitude entry ',...
			  'determines if the projection is normal aspect (0 degrees) or ',...
			  'a simple oblique (latitude not 0 degrees).  The longitude ',...
			  'entry will set the central meridian of the projection.'];
	str2 = 'If either entry is left blank, then 0 degrees is used.';

case 'MapOrientation'    %  Help for Map Orientation edit boxes
	str1 = ['The Map Orientation specifies the azimuth angle of the ',...
	        'north pole relative to the map origin.  Azimuth is ',...
			  'measured clockwise from the top of the projection.  If the ',...
			  'orientation is 0, then the north pole lies at the top of ',...
			  'the display.  If the orientation is -90 degrees, then a ',...
			  'transverse aspect map results.  If orientation is ',...
			  'any other number, then a skew oblique projection results.'];
	str2 = ['If the orientation edit box is disabled, then the current ',...
	        'projection has a fixed orientation by definition.'];

case 'MapFalseEandN'    %  Help for False Easting and Northing edit boxes
	str1 = ['The Map False Easting and Northing parameters specify a ',...
	        'coordinate shift for projection calculations.'];
	str2 = ['The FalseEasting and FalseNorthing is in the same units as ',...
	        'the projected coordinates, i.e., units of the first element of ',...
			'the Geoid axesm-based map property.'];
	str3 = ['False eastings and northings are sometimes used to ensure ',...
	        'non-negative values of the projected coordinates. For example, ',...
			'the Universal Transverse Mercator uses a false easting of ',...
			'500,000 meters and a false northing of 10,000,000 meters in ',...
			'the southern hemisphere.'];

case 'MapScalefactor'    %  Help for Map Scalefactor edit boxes
	str1 = ['The Map Scale Factor modifies the size of the map in the ',...
	        'projected coordinates.  The geographic coordinates are ',...
			'transformed to Cartesian coordinates by the map projection ',...
			'equations, and then multiplied by the scale factor.'];
	str2 = ['Scale factors are used to minimize the scale distortion ',...
	        'in a map projection. For example, the Universal Transverse ',...
			'Mercator uses a scale factor of 0.996 to shift the line ',...
			'of zero scale distortion to two lines on either side of ',...
			'the central meridian.'];

case 'MapParallel'    %  Help for Map Parallel edit boxes
	str1 = ['The Map Parallels specify the standard parallels of the ',...
	        'selected projection.'];
	str2 = ['The default settings are points 1/6 from the top and bottom ',...
	        'of the map latitude limits.  If only one box is displayed, ',...
			  'then this projection has only one standard parallel.  If two ',...
			  'boxes are displayed then the projection can have one or two ',...
			  'standard parallels.  If the parallels edit box is disabled, ',...
			  'then the current projection has no standard parallels or has fixed standard parallels.'];

case 'FrameButton'              %  Help for Frame push buttons
	str1 = ['Pressing this button will bring up an additional dialog ',...
	        'window allowing the map frame settings to be specified.'];

case 'GridButton'              %  Help for Grid push buttons
	str1 = ['Pressing this button will bring up an additional dialog ',...
	        'window allowing the map grid settings to be specified.'];

case 'LabelButton'              %  Help for Label push buttons
	str1 = ['Pressing this button will bring up an additional dialog ',...
	        'window allowing the map parallel and meridian label ',...
			  'settings to be specified.'];

case 'DefaultButton'                    %  Help for the default button
	str1 = ['Pressing this button will update and compute the default ',...
	        'settings given the currently specified map parameters.  ',...
			  'Only blank map parameters will be affected by this action.'];
	str2 = ['The Fill in button is particularly useful to reset the ',...
	        'Map Frame limits when switching projections.  Simply clear ',...
			  'the Map Frame entries and then press the Fill in button to ',...
			  'update the frame to the largest possible size for the ',...
			  'specified projection.'];

case 'ResetButton'                    %  Help for the reset button
	str1 = ['Pressing this button will reset the default settings for the ',...
	        'listed map projection, regardless of the current entries ',...
			  'in the map structure.'];
	str2 = ['For example, if the Reset button is pushed and confirmed, ',...
	        'the map grid and frame will be reset to their default ',...
			  'colors and display state (off).'];

case 'Frame'              %  Help for Frame on/off Radio Buttons
	str1 = 'This determines if the Map Frame is visible.';

case 'FFaceColor'         %  Help for Frame Face Color popup
	str1 = ['This determines the color used for the background of the Map Frame.  ',...
	        'On a map with only land patches displayed, setting the ',...
			  'frame background color is a convenient way to fill oceans and ',...
			  'other bodies of water.  Selecting "none" will make the frame ',...
			  'background transparent (ie:  same as the axes color).'];
	str2 = ['If "Custom" is selected, then any RGB triple can be previewed ',...
	        'and selected.'];

case 'FEdgeColor'         %  Help for Frame Edge Color popup
	str1 = ['This determines the color used for the edge of the Map Frame.  ',...
	        'Selecting "none" will hide the frame edge.  ',...
			  'If "Custom" is selected, then any RGB triple can be previewed ',...
	        'and selected.'];

case 'FWidth'         %  Help for Frame Width edit box
	str1 = ['This entry determines the width of the Map Frame edge, measured ',...
	        'in points.'];

case 'FFill'         %  Help for Frame Points/edge edit box
	str1 = ['This entry determines the number of points used to display ',...
	        'each edge of the Map Frame.  An entry of 100 results in a ',...
			  'total of 400 points used to display the frame.'];

case 'Grid'              %  Help for Grid on/off Radio Buttons
	str1 = 'This determines if the Map Grid is visible.';

case 'GridColor'         %  Help for Grid Color popup
	str1 = ['This determines the color used for the grid lines.  ',...
           'If "Custom" is selected, then any RGB triple can be previewed ',...
	        'and selected.'];

case 'GridStyle'         %  Help for Grid Style popup
	str1 = 'This determines the line style used to display a map grid.';

case 'GWidth'         %  Help for Grid Width edit box
	str1 = ['This entry determines the width of the grid lines, measured ',...
	        'in points.'];

case 'GAltitude'         %  Help for Grid Altitude edit box
	str1 = ['This entry determines the plane in which the map grid is drawn.  ',...
	        'With this property, the grid lines can be placed in front of or ',...
			  'behind displayed map objects.  The default plane for map objects ',...
			  'is z = 0.  If this property is set to INF, then the map grid ',...
			  'is drawn just outside the current upper limit of the z axis, ',...
			  'which places the grid on top of all displayed objects.'];

case 'GridSettings'         %  Help for Grid Settings push button
	str1 = ['Pressing this button will bring up an additional dialog ',...
	        'window allowing properties specific to the parallel or ',...
			  'meridian grid to be modified.'];

case 'MeridianLabels'              %  Help for Meridian Labels on/off Radio Buttons
	str1 = 'This determines if the meridian labels are visible.';

case 'ParallelLabels'              %  Help for Parallel Labels on/off Radio Buttons
	str1 = 'This determines if the parallel labels are visible.';

case 'LabelColor'         %  Help for Label Color popup
	str1 = ['This determines the color used for the parallel and meridian labels.  ',...
           'If "Custom" is selected, then any RGB triple can be previewed ',...
	        'and selected.'];

case 'LabelAngle'         %  Help for Label Angle popup
	str1 = ['This determines the character slant on displayed parallel and ',...
	        'meridian labels.  "Normal" specifies non-italic font, while ',...
			  '"Italic" and "Oblique" specify an italic font.'];

case 'LabelFont'         %  Help for Label Font edit box
	str1 = ['This determines the character font used to display parallel and ',...
	        'meridian labels.  The entered name must be a font existing ',...
			  'on the computer.  If the specified font does not exist, then ',...
			  'a default of "Helvetica" is used.'];
	str2 = 'Pressing this button provides a preview of the specified font.';

case 'LabelFormat'         %  Help for Label Format popup
	str1 = ['This determines the format used to display parallel and ',...
	        'meridian labels.  If "compass" is selected, labels ',...
			  'are suffixed with an "E,W,N,S" for east, west, north or ',...
			  'south respectively.  If "signed" is used, then labels are ',...
			  'prefixed with a "+" for east and north, and "-" for west and ',...
			  'south.  If "none" is selected, then labels are prefixed with ',...
			  '"-" for west and south, but no prefix is used for east and north.'];

case 'LabelUnits'         %  Help for Label Units popup
	str1 = ['This determines the angle units used to display parallel and ',...
	        'meridian labels.  The labels are displayed in these units, ',...
			  'regardless of the Map Angle Units setting.'];

case 'LabelSize'         %  Help for Label Size edits
	str1 = ['This is a scalar entry specifying the size of the meridian ',...
	        'and parallel labels, in the units specified ',...
			  'by the Font Units entry.'];

case 'LabelFontUnits'         %  Help for LabelFontUnits popup
	str1 = ['This specifies the units of the Font Size entry.  ',...
	        'If it is set to "normalized", then the font size is a ',...
			  'fraction (between 0 and 1) of the figure window.'];

case 'LabelWeight'         %  Help for Label Weight popup
	str1 = ['This determines the character weight used to display parallel and ',...
	        'meridian labels.'];

case 'LabelSettings'         %  Help for Label Settings push button
	str1 = ['Pressing this button will bring up an additional dialog ',...
	        'window allowing properties specific to the parallel or ',...
			  'meridian labels to be modified.'];

case 'MeridianLocation'         %  Help for Meridian Label Location popup
	str1 = ['This entry specifies the meridians to be labeled.  ',...
	        'The label locations need not correspond to displayed meridian ',...
			  'lines.  A scalar entry results in evenly spaced meridian labels, ',...
			  'starting at the Prime Meridian and proceeding east ',...
			  'and west.  If a vector of longitudes is entered (enclosed in square brackets), ',...
			  'meridian labels will be displayed at the locations given by ',...
			  'elements of the vector. Entries must be provided in the angle ',...
			  'units of the current axesm-based map.'];

case 'MParallel'         %  Help for M Parallel popup and edit
	str1 = ['This entry specifies the latitude at which the meridian labels ',...
	        'will be drawn.  A scalar latitude may be entered in the edit box.'];
	str2 = ['If the edit box is empty, then the specification chosen from the ',...
	        'popup menu is used.  "north" refers to the maximum ',...
			  'and "south" to the minimum of Map Latitude Limits.'];

case 'ParallelLocation'         %  Help for Parallel Label Location popup
	str1 = ['This entry specifies the parallels to be labeled.  ',...
	        'The label locations need not correspond to displayed parallel ',...
			  'lines.  A scalar entry results in evenly spaced parallel labels, ',...
			  'starting at the Equator and proceeding north ',...
			  'and south.  If a vector of latitudes is entered (enclosed in square brackets), ',...
			  'parallel labels will be displayed at the locations given by ',...
			  'elements of the vector. Entries must be provided in the angle ',...
			  'units of the current axesm-based map.'];

case 'PMeridian'         %  Help for P Meridian popup and edit
    str1 = ['This entry specifies the longitude at which the parallel labels ',...
	        'will be drawn.  A scalar longitude may be entered in the edit box.'];
	str2 = ['If the edit box is empty, then the specification chosen from the ',...
	        'popup menu is used.  "east" refers to the maximum ',...
			  'and "west" to the minimum of Map Longitude Limits.'];

case 'Round'         %  Help for Meridian and Parallel Round edit
	str1 = ['This entry specifies to which power of ten the corresponding labels ',...
	        'will be rounded.  For example, if the entry is -1, the labels ',...
			  'are rounded to the tenths position.'];

case 'MeridianGrids'              %  Help for MeridianGrids on/off Radio Buttons
	str1 = ['This determines if the meridians will be visible when the grid ',...
	        'is turned on.'];

case 'MLocationGrids'              %  Help for MLocationGrids
	str1 = ['This entry specifies the meridians that will be displayed.  ',...
	        'A scalar entry results in evenly spaced meridian lines, ',...
			  'starting at the Prime Meridian and proceeding east ',...
			  'and west.  If a vector of longitudes is entered (enclosed in square brackets), ',...
			  'meridian lines will be displayed at the locations given by ',...
			  'elements of the vector. Entries must be provided in the angle ',...
			  'units of the current axesm-based map.'];

case 'MeridianLimits'              %  Help for MeridianLimits
	str1 = ['This entry specifies the parallels beyond which the meridian ',...
	        'grids do not extend.  By default, this property is empty, which ',...
			  'allows the meridian lines to extend to the Map Latitude Limits.  ',...
			  'If an entry is provided, it must be a two-element vector, ',...
			  'enclosed in square brackets.'];

case 'MeridianExceptions'              %  Help for MeridianExceptions
	str1 = ['This entry specifies the meridians which are exceptions to the ',...
			  'Meridian Latitude Limits. Unlike the other meridians, these exceptions extend beyond the ',...
	        'parallel given by the Meridian Latitude Limits.  This entry ',...
			  'is a vector containing the longitudes of the meridians to extend.  This property, ',...
			  'in conjunction with the Meridian Latitude Limits, is especially ',...
			  'useful for controlling of the grid lines near the poles.'];

case 'MeridianFill'              %  Help for MeridianFill
	str1 = ['This scalar entry specifies the number of points to be used to ',...
	        'construct each meridian line.  The default is 100 points.'];

case 'ParallelGrids'              %  Help for ParallelGrids on/off Radio Buttons
	str1 = ['This determines if the parallels will be visible when the grid ',...
	        'is turned on.'];

case 'PLocationGrids'              %  Help for PLocationGrids
	str1 = ['This entry specifies the parallels which will be displayed.  ',...
	        'A scalar entry results in evenly spaced parallel lines, ',...
			  'starting at the Equator and proceeding north ',...
			  'and south.  If a vector of latitudes is entered (enclosed in square brackets), ',...
			  'parallel lines will be displayed at the locations given by ',...
			  'elements of the vector. Entries must be provided in the angle ',...
			  'units of the current axesm-based map.'];

case 'ParallelLimits'              %  Help for ParallelLimits
	str1 = ['This entry specifies the meridians beyond which the parallel ',...
	        'grids do not extend.  By default, this property is empty, which ',...
			  'allows the parallel lines to extend to the Map Longitude Limits.  ',...
			  'If an entry is provided, it must be a two-element vector, ',...
			  'enclosed in square brackets.'];

case 'ParallelExceptions'              %  Help for ParallelExceptions
	str1 = ['This entry specifies the parallels which are exceptions to the ',...
			  'Parallel Longitude Limits. Unlike the other parallels, these exceptions extend beyond the ',...
	        'meridian given by the Parallel Longitude Limits.  This entry ',...
			  'is a vector containing the latitudes of the parallel to extend.  This property, ',...
			  'in conjunction with the Parallel Longitude Limits, is especially ',...
			  'useful for controlling of the grid lines near the edges of a map.'];

case 'ParallelFill'              %  Help for ParallelFill
	str1 = ['This scalar entry specifies the number of points to be used to ',...
	        'construct each parallel line.  The default is 100 points.'];

case 'Apply'                    %  Help for the apply button
	str1 = ['Pressing the Apply button will apply the specified settings ',...
	       'to the current map.  This will cause the current map to be ',...
			 'reprojected.'];

case 'Accept'                    %  Help for the accept button
	str1 = ['Pressing the Accept button will update the map projection structure with ',...
	        'the current properties.'];
	str2 = ['The Apply button on the Projection Control Dialog must still ',...
	        'be pressed for these changes to be applied to the current map.'];

case 'CancelMain'                    %  Help for the Projection Control cancel button
	str1 = 'Pressing the Cancel button will abort the current operation.';
	str2 = ['If an error condition has been encountered, the current map ',...
	        'will be updated to its original settings.'];

case 'Cancel'                    %  Help for other cancel button
	str1  = 'Pressing the Cancel button will abort the current operation.';

case 'Help'
    str1 = 'Hover over any button or edit box label to view tooltip help.';
	str2 = ['Or, close the window with the Apply or Cancel button, then ' ...
           'enter "doc axesmui" at the command line to view the ' ...
           'axesmui reference page in the MATLAB Help Browser.'];
end

maxlen = 60;
str1 = wrapstr(str1,maxlen);
if isempty(str2) && isempty(str3)
    str = str1;
elseif isempty(str3)
    % The space between the new lines is needed to ensure that a blank line
    % separates str1 and str2.
    str = sprintf('%s\n \n%s',str1,wrapstr(str2,maxlen));
else
    % The space between the new lines is needed to ensure that a blank line
    % separates str1, str2, and str3
    str = sprintf('%s\n \n%s\n \n%s', ...
        str1,wrapstr(str2,maxlen),wrapstr(str3,maxlen));
end

%--------------------------------------------------------------------------

function wrapped = wrapstr(str,maxlen)

w = cell(ceil(1.2*length(str)/maxlen),1);
last = 1;
spaces = [find(str == ' ') numel(str)];
k = 1;
while(last < numel(str))
    t = spaces(spaces < (maxlen + last-1));
    w{k} = str(last:t(end));
    last = t(end) + 1;
    k = k + 1;
end
w(k+1:end) = [];
wrapped = sprintf('%s\n',w{:});
wrapped(end) = [];

%--------------------------------------------------------------------------

function notifyuser(msg,tag)
% Notify user about problem via command line or a modal error dialog,
% depending on whether or not we're using a local client.

if ~isLocalClient
    % Using a remote client such as MATLAB Online.
    maxlen = 60;
    fprintf('%s\n\n',wrapstr(msg,maxlen))
else
    uiwait(errordlg(msg,tag,'modal'))
end

%--------------------------------------------------------------------------

function tf = isLocalClient
% If true, we are using MATLAB from a local client such as MATLAB Desktop.

tf = matlab.internal.capability.Capability.isSupported('LocalClient');

