function pdetool_changemode(flag)
% case: changemode

%   Copyright 1994-2023 The MathWorks, Inc.

    pde_fig=findobj(allchild(0),'flat','Tag','PDETool');

    pde_kids = allchild(pde_fig);
    flg_hndl=findobj(pde_kids,'flat','Tag','PDEFileMenu');
    flags=get(flg_hndl,'UserData');

    mode_flag=flags(2);

    % case: draw mode --> draw mode. Do nothing.
    if flag==1 && mode_flag==0
        return;
    end

    pdegd=get(findobj(pde_kids,'flat',...
        'Tag','PDEMeshMenu'),'UserData');

    % if no geometry, alert user and return:
    if isempty(pdegd), pdetool('error','  No geometry data.'), return, end

    zstate=findobj(get(pde_fig,'Children'),'Tag','zoomBtn');
    if (zstate.UserData==1)
        pdezoom(pde_fig,'off')
        zstate.UserData = 0;
        pde_kids=get(pde_fig,'Children');
        opthndl=findobj(pde_kids,'flat','Tag','PDEOptMenu');
        set(findobj(get(opthndl,'Children'),'flat','Tag','PDEZoom'),...
            'Checked','off')
    end

    pde_kids=get(pde_fig,'Children');
    ax=findobj(pde_kids,'flat','Tag','PDEAxes');
    axKids=get(ax,'Children');
    set(pde_fig,'Currentaxes',ax)

    if ~mode_flag
        % transition: draw mode -> boundary mode

        flg_hndl=findobj(pde_kids,'flat','Tag','PDEFileMenu');
        flags=get(flg_hndl,'UserData');

        mode_flag=1;
        flag1=flags(3);

        if abs(flag1)
            % delete mesh lines, decomposition lines, and subdomains:
            hndl=[findobj(axKids,'flat','Tag','PDEBorderLine')'...
                findobj(axKids,'flat','Tag','PDEBoundLine')'...
                findobj(axKids,'flat','Tag','PDEMeshLine')'...
                findobj(axKids,'flat','Tag','PDESubDom')'...
                findobj(axKids,'flat','Tag','PDESelRegion')'];
            delete(hndl)
        end

        ns=getappdata(pde_fig,'objnames');

        pdetool formchk

        evalhndl=findobj(pde_kids,'flat','Tag','PDEEval');
        evalstring=get(evalhndl,'String');

        set(pde_fig,'Pointer','watch');
        drawnow

        % first call DECSG to decompose geometry;
        % reject if evaluation string is bad
        try
            [dl1,bt1,dl,~,msb] = decsg(pdegd,evalstring,ns);
            setappdata(pde_fig,'msb',msb)
            if isempty(dl)
                set(pde_fig,'Pointer','arrow')
                drawnow
                pdetool('error','  Set formula results in empty geometry')
                failed = true;
            else
                failed = false;
            end
        catch ME
            failed = true;
            setappdata(pde_fig,'msb',NaN)
            set(pde_fig,'Pointer','arrow')
            drawnow
            switch ME.identifier
                case 'pdelib:decsg:EmptySF'
                    pdetool('error','  Set formula is empty')
                case 'pdelib:decsg:ParenthesesMismatch'
                    pdetool('error','  Set formula has mismatched parentheses')
                case 'pdelib:decsg:IncorrectParenthesesNesting'
                    pdetool('error','  Set formula has incorrectly nested parentheses')
                case 'pdelib:decsg:InvalidSF'
                    pdetool('error','  Set formula contains invalid text')
                case 'pdelib:decsg:FailedSF'
                    pdetool('error','  Unable to evaluate set formula')
            end
        end
        if failed
            pdetool('changemode',1)
            flags = get(flg_hndl,'UserData');
            flags(3) = -1;
            set(flg_hndl,'UserData',flags)
            return
        end
        set(findobj(get(pde_fig,'Children'),'flat','Tag','PDEBoundMenu'), ...
            'UserData',dl);

        setappdata(pde_fig,'dl1',dl1)
        setappdata(pde_fig,'bt1',bt1)

        % compute new coarse initmesh for labeling purposes
        [pinit2,~,tinit2]=initmesh(dl1,'hmax',Inf,'init','on');
        setappdata(pde_fig,'pinit2',pinit2)
        setappdata(pde_fig,'tinit2',tinit2)

        pdetool('cleanup')

        pdeinfo('Click to select boundaries. Double-click to open boundary condition dialog box.');

        pdetool('drawbounds')

        bndhndl=findobj(pde_kids,'flat','Tag','PDEBoundMenu');
        set(findobj(get(bndhndl,'Children'),'flat','Tag','PDEExpBound'),...
            'Enable','on');

        % Reset PDE coefficients:
        currcoeff=getappdata(pde_fig,'currparam');
        newcoeff=strtok(currcoeff(1,:),'!');
        for j=2:size(currcoeff,1)
            newcoeff=char(newcoeff,strtok(currcoeff(j,:),'!'));
        end
        setappdata(pde_fig,'currparam',newcoeff);
        appl=getappdata(pde_fig,'application');
        stdparam=pdetrans(newcoeff,appl);
        coeffh=findobj(pde_kids,'flat','Tag','PDEPDEMenu');
        set(coeffh,'UserData',stdparam)

        set(pde_fig,'WindowButtonDownFcn','',...
            'WindowButtonMotionFcn','pdemtncb(0)',...
            'WindowButtonUpFcn','',...
            'Pointer','arrow');
        drawnow

        % enable removal of interior subdomain boundaries
        menuhndl=findobj(get(pde_fig,'Children'),'flat','Tag','PDEBoundMenu');
        hbound(1)=findobj(get(menuhndl,'Children'),'flat','Tag','PDERemBord');
        hbound(2)=findobj(get(menuhndl,'Children'),'flat','Tag','PDERemAllBord');
        set(hbound,'Enable','on')

        if abs(flag1)
            flag1=0; flag2=1; flag4=0;
            flags=[flags(1) mode_flag flag1 flag2 flags(5) flag4 flags(7)]';
        else
            flags=[flags(1) mode_flag flag1 flags(4:7)']';
        end
        set(flg_hndl,'UserData',flags)

    elseif mode_flag
        % transition: 'solve modes' -> draw mode

        mode_flag=0;

        set(pde_fig,'Pointer','watch')
        drawnow
        pdeinfo('Continue drawing or edit set formula.');

        hndl=findobj(get(pde_fig,'Children'),'flat','Tag','PDEEval');
        set(hndl,'Enable','on');

        % hide mesh lines, decomposition lines, subdomains, and labels:
        hndl=[findobj(axKids,'flat','Tag','PDEBorderLine')'...
            findobj(axKids,'flat','Tag','PDEBoundLine')'...
            findobj(axKids,'flat','Tag','PDEMeshLine')'...
            findobj(axKids,'flat','Tag','PDESubDom')'...
            findobj(axKids,'flat','Tag','PDESubLabel')'...
            findobj(axKids,'flat','Tag','PDEEdgeLabel')'...
            findobj(axKids,'flat','Tag','PDEENodeLabel')'...
            findobj(axKids,'flat','Tag','PDEETriLabel')'...
            findobj(axKids,'flat','Tag','PDESelRegion')'];
        set(hndl,'Visible','off')

        set(pde_fig,'WindowButtonDownFcn','pdeselect select');

        delete(getappdata(pde_fig,'trihandles'))
        delete(getappdata(pde_fig,'nodehandles'))
        setappdata(pde_fig,'trihandles',[])
        setappdata(pde_fig,'nodehandles',[])

        delete(findobj(get(pde_fig,'Children'),'flat','Tag','Colorbar'))

        h=get(ax,'UserData');
        if ~isempty(h)
            delete(h)
            set(ax,'UserData',[]);
        end

        set(get(ax,'Title'),'String','');

        set(ax,'Position',getappdata(ax,'axstdpos'));

        set(pde_fig,'Colormap',get(get(ax,'Xlabel'),'UserData'));

        % turn the geometry objects back on
        axKids=get(ax,'Children');
        hndl=findobj(axKids,'flat','Tag','PDEMinReg');
        set(hndl,'Visible','on')
        hndl=[findobj(axKids,'flat','Tag','PDELine')'...
            findobj(axKids,'flat','Tag','PDESelFrame')'...
            findobj(axKids,'flat','Tag','PDELabel')'...
            findobj(axKids,'flat','Tag','PDELblSel')'];
        set(hndl,'Visible','on')

        edithndl=findobj(get(pde_fig,'Children'),'flat','Tag','PDEEditMenu');
        set(edithndl,'Enable','on')
        set(findobj(get(edithndl,'Children'),'flat','Tag','PDESelall'),...
            'Enable','on','CallBack','pdeselect(''select'',1)')
        bndhndl=findobj(get(pde_fig,'Children'),'flat','Tag','PDEBoundMenu');
        set(findobj(get(bndhndl,'Children'),'flat','Tag','PDEBoundSpec'),...
            'UserData',[]);

        % enable edit menu items:
        editkids=get(edithndl,'Children');
        hndls=[findobj(editkids,'flat','Tag','PDECut')...
            findobj(editkids,'flat','Tag','PDECopy')...
            findobj(editkids,'flat','Tag','PDEClear')];
        set(hndls,'Enable','on')

        % enable 'Rotate...':
        drawhndl=findobj(get(pde_fig,'Children'),'flat','Tag','PDEDrawMenu');
        set(findobj(get(drawhndl,'Children'),'flat','Tag','PDERotate'),...
            'Enable','on')

        clipboard=get(findobj(editkids,'flat','Tag','PDECut'),'UserData');
        if ~isempty(clipboard)
            set(findobj(editkids,'flat','Tag','PDEPaste'),'Enable','on')
        end

        flags=[flags(1) mode_flag flags(3:7)']';
        set(flg_hndl,'UserData',flags)

        pdetool refresh

        set(pde_fig,'Pointer','arrow')
        drawnow

    else
        pdetool('error',' No 2-D geometry available');
    end
end
