function varargout = redAnTS(varargin)
% redAnTS - finite element analysis program for 2-D linear elasticity
% (Analysis of Two dimensional Solids)
%
% This program allows you to solve linear elasticity boundary value
% problems on 2D domains. There are options to create meshes, define
% boundary conditions on edges or points, define material properties,
% assume plane stress or plane strain deformations, apply body forces and
% temperature changes to the body. The program allows plotting of original
% and deformed meshes, and various stress and strain components.
%
% NOTES BEFORE RUNNING:
%
% redAnTS has been developed specifically for M&AE 325. It was written 
% for Matlab 7.0, and may not work on previous versions.
% No special toolboxes should be required. Before running the
% program, you must "add with subfolders" the folder redAnTS_Toolbox to 
% your path. It is recommended that you use the subfolder InputOutputFiles 
% as your working directory.
%
% For help with using the program, choose the help option from each
% pulldown menu. In general, the menus should be used in the order in which
% they appear (i.e. Mesh, then Input Data, then Solver, etc.).
%
% All data is stored in a structure called handles.
% The structure can be accessed by using the command:
% handles=guidata(FIGHANDLE);
% where FIGHANDLE is the handle to the main GUI figure window. That handle
% is stored in handles.mainguifig and can be passed as an input argument to
% functions. 
%
% The data fields of interest in the handles structure are as follows:
% 
%     handles.mesh        : contains all mesh information including the fields
%         handles.mesh.size   : [number of elements , 
%                                number of global nodes , 
%                                number of nodes per element , 
%                                global number of degrees of freedom , 
%                                number of degrees of freedom per element] 
%         handles.mesh.xcoords: [1 x (number of nodes)] : X coordinate of each node
%         handles.mesh.ycoords: [1 x (number of nodes)] : Y coordinate of each node
%         handles.mesh.connect: [(number of elements) x 3] : connectivity
%         array
%         handles.mesh.edges  : [7 x (number of edge elements)] : information about mesh boundaries
%                               row 1: first node number
%                               row 2: second node number
%                               row 3: not used
%                               row 4: not used
%                               row 5: boundary number
%                               row 6: not used 
%                               row 7: not used
%         handles.mesh results from a choice on the Mesh menu.
% 
%     handles.prop        : contains all material properties and problem options including the fields
%         handles.prop.twoDflag     : indicates plane strain or plane stress problem
%         handles.prop.youngmodulus : Young's modulus of the material
%         handles.prop.anisomods    : [1 x 9] : anisotropic material stiffnesses
%         handles.prop.poissonratio : Poisson's ratio of the material
%         handles.prop.bodyforce    : [2 x 1] : body force in X and Y directions
%         handles.prop.thermalcoeff : coefficient of thermal expansion
%         handles.prop.deltatemp    : temperature change to which the body is subjected
%         handles.prop results from choices on the Input Data menu.
%         
%     handles.bcsi        : contains boundary condition information including the fields
%         handles.bcsi.bccodes   : [1 x (number of nodal points)] : code indicating type of BC on node
%         handles.bcsi.bcnangles : [1 x (number of nodal points)] : angle in radians between X-Y and Norm-Tang coord. systems
%         handles.bcsi.bcboundts : [1 x (number of nodal points)] : magnitude of tangential BC
%         handles.bcsi.bcboundns : [1 x (number of nodal points)] : magnitude of normal BC
%         handles.bcsi.codes     : [1 x (number of boundaries)]   : code indicating type of BC on edge
%         handles.bcsi.normbcs   : [1 x (number of boundaries)]   : magnitude of normal BC
%         handles.bcsi.tangbcs   : [1 x (number of boundaries)]   : magnitude of tangential BC
%         handles.bcsi.pointbcs  : [(number of point BCs) x 6]    : info about point BCS
%                                  col 1: X coordinate of desired BC
%                                  col 2: Y coordinate of desired BC
%                                  col 3: code indicating type of BC
%                                  col 4: magnitude of local x component of BC
%                                  col 5: magnitude of local y component of BC
%                                  col 6: angle between local and global coordinate systems
%         handles.bcsi results from choices on the Input Data menu.
% 
%     handles.displ       : contains nodal point displacements including the field
%         handles.displ.displ : [1 x (global number of degrees of freedom)]
%         : X and Y displacement of each node (U1 V1 U2 V2 ...)
%         handles.displ results from a choice on the Solver menu.
%             
%     handles.sigeps      : contains stress and strain including the fields
%         handles.sigeps.eps      : [(number of elements) x 3] : strain (col 1 is XX, col 2 is YY, col 3 is XY)
%         handles.sigeps.sig      : [(number of elements) x 3] : stress (col 1 is XX, col 2 is YY, col 3 is XY)
%         handles.sigeps.sigrange : single number with largest absolute value of stress
%         handles.sigeps.epsrange : single number with largest absolute value of strain
%         handles.sigeps results from running CalcStrainStress.
%         
%     handles.principals  : contains in-plane principal stresses and strains including fields
%         handles.principals.princstress : [(number of elements x 2)] : 1st and 2nd principal stress of each element
%         handles.principals.princstrain : [(number of elements x 2)] : 1st and 2nd principal strain of each element
%         handles.principals.sigrange    : single number with largest absolute value of stress
%         handles.principals.epsrange    : single number with largest absolute value of strain
%         handles.principals results from running CalcPrincipals.
%         
%     handles.effstress   : [(number of elements) x 1] : contains octahedral shear stress
%         handles.effstress results from running CalcEffectiveStress.
%         
%     handles.fringes     : contains information for plotting fringe patterns including the fields
%         handles.fringes.prinval : [2 x (number of nodes)] : average principal stress values (1st and 2nd) at each node
%         handles.fringes.prindir : [2 x (number of nodes)] : principal direction at each node
%         handles.fringes.prindif : [1 x (number of nodes)] : max in-plane shear at each node
%         handles.fringes.frinvec : [1 x (number of nodes)] : fringe value at each node
%         handles.fringes.frinsha : [1 x (number of nodes)] : indicates color of node for shading fringe pattern
%         handles.fringes results from running CalcFringes.

%%% redAnTS version 2.0              %%%
%%% Last Modified 2006-09-22 H. Ritz %%%
    
    
% Begin initialization code - DO NOT EDIT
gui_Singleton = 0;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @redAnTS_OpeningFcn, ...
    'gui_OutputFcn',  @redAnTS_OutputFcn, ...
    'gui_LayoutFcn',  [] , ...
    'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before redAnTS is made visible.
function redAnTS_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to redAnTS (see VARARGIN)

% setup toolbar for figure
fig=handles.mainguifig;
nf=figure('Visible','off');
gtb=uitoolbar(fig);
editplot  = copyobj(findall(nf, 'Tag', 'Standard.EditPlot'),gtb);
zoomin    = copyobj(findall(nf, 'Tag', 'Exploration.ZoomIn'),gtb);
zoomout   = copyobj(findall(nf, 'Tag', 'Exploration.ZoomOut'),gtb);
pan       = copyobj(findall(nf, 'Tag', 'Exploration.Pan'),gtb);
rotate    = copyobj(findall(nf, 'Tag', 'Exploration.Rotate'),gtb);
datacursor= copyobj(findall(nf, 'Tag', 'Exploration.DataCursor'),gtb);
close(nf);

% on windows machines, prevent loss of y-axis label
if ispc
    currpos=get(handles.axes1,'Position');
    newpos=[currpos(1)+0.02 currpos(2) currpos(3)-0.02 currpos(4)];
    set(handles.axes1,'Position',newpos);
end

% Choose default command line output for redAnTS
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% --- Outputs from this function are returned to the command line.
function varargout = redAnTS_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on selection change in exportpopupmenu.
function exportpopupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to exportpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns exportpopupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from exportpopupmenu

val = get(hObject,'Value');
try
    set(handles.error_text,'String','');
    switch val
        case 1  % Export the handles structure to the workspace, then save
            filterspec = '*.mat';
            title = 'Save workspace:';
            dflt='fem_ws.mat';
            [fn,pn]=uiputfile(filterspec,title,dflt);
            ToggleStatus(1,handles.mainguifig);
            keepfields={'mesh' 'prop' 'bcsi' 'displ' 'sigeps' 'principals' 'effstress' 'fringes'};
            for i=1:length(keepfields)
                if isfield(handles,keepfields{i})
                    eval(['FEMdata.',keepfields{i},'=handles.',keepfields{i},';']);
                end
            end

            save([pn,fn],'-struct', 'FEMdata')
            ToggleStatus(0,handles.mainguifig);

        case 2  % save the current plot from axes1
            filterspec = '*.fig';
            title = 'Save plot:';
            dflt='plot.fig';
            [fn,pn]=uiputfile(filterspec,title,dflt);
            ToggleStatus(1,handles.mainguifig);
            cm=get(handles.mainguifig,'ColorMap');
            newfig=figure;
            newaxes=copyobj(handles.axes1,newfig);
            set(newfig,'ColorMap',cm);
            set(newaxes,'Units','default','Position','default');
            saveas(newfig,[pn,fn]);
            close(newfig);
            ToggleStatus(0,handles.mainguifig);

        case 3  % Help
            redAnTSHelp('ExportMenu');
            ToggleStatus(2,handles.mainguifig);
    end
catch
    set(handles.error_text,'String',sprintf([lasterr,'\nPressed Cancel? Wrong file type?']));
    ToggleStatus(2,handles.mainguifig);
end


% --- Executes during object creation, after setting all properties.
function exportpopupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to exportpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in meshpopupmenu.
function meshpopupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to meshpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns meshpopupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from meshpopupmenu

val = get(hObject,'Value');
try
    set(handles.error_text,'String',''); guidata(hObject,handles);
    switch val
        case 1 % Mapping method
            [handles.meshfile, handles.mesh] = MappingMethod(handles.mainguifig);

        case 2 % CSG method
            [handles.meshfile, handles.mesh] = CSGMethod(handles.mainguifig);

        case 3 % Create new mesh - Mapping method
%             ToggleStatus(1,handles.mainguifig);
            [handles.meshfile, handles.mesh] = MappingMeshTool(handles.mainguifig);

        case 4 % Create new mesh - CSG method
%             ToggleStatus(1,handles.mainguifig);
            CSGtool('redAnTS',handles.mainguifig); 
            waitfor(gcf); 
            handles=guidata(hObject);
            [NotNeeded, handles.mesh] = CSGMethod(handles.mainguifig,handles.fullmeshfile);

        case 5 % Help for meshing
            redAnTSHelp('MeshMenu');
            ToggleStatus(2,handles.mainguifig);
    end
    
    % new mesh exists: therefore, remove fields that are no longer valid
    if val~=5
        cla reset
        SETTINGSFILES={'inputtext','solutionexists','postprocfile','inputfile',...
            'prop','bcsi','sigeps','principals','effstress','fringes','displ'};
        for i=1:length(SETTINGSFILES)
            if isfield(handles,SETTINGSFILES{i})
                handles=rmfield(handles,SETTINGSFILES{i});
            end
        end
    end
    guidata(hObject,handles);
    UpdateSettings(handles.mainguifig);

catch
    set(handles.error_text,'String',sprintf([lasterr,'\nPressed Cancel? Wrong file? Closed meshing GUI?']));
    ToggleStatus(2,handles.mainguifig);
end

% --- Executes during object creation, after setting all properties.
function meshpopupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to meshpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in plotpopupmenu.
function plotpopupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to plotpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns plotpopupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from plotpopupmenu
val = get(hObject,'Value');

try
    set(handles.error_text,'String','');
    % initialize
    if val ~=17
        ToggleStatus(1,handles.mainguifig);
        meshstruct = handles.mesh;
        meshdata=meshstruct.size;
        numel = meshdata(1);
        numnp = meshdata(2);
        nnpe = meshdata(3);
        numeq = meshdata(4);
        ndof = meshdata(5);
        x=meshstruct.xcoords;
        y=meshstruct.ycoords;
        np=meshstruct.connect;
        edges=meshstruct.edges;

        npts = nnpe;
        cla reset
        colormap(jet)
    end


    switch val
        case 1 % Mesh
            a=x(np(:,[1 2 3 1])');
            b=y(np(:,[1 2 3 1])');
            plot(a,b,'b')
            axis equal
            title(['Original Mesh: ',num2str(numel),' elements, ',num2str(numnp),' nodes']);

        case 2 % Displacement
            displstruct = handles.displ;
            U=displstruct.displ;
            hold on
            
            % first draw the mesh
            a=x(np(:,[1 2 3 1])');
            b=y(np(:,[1 2 3 1])');
            plot(a,b,'b')
            % now draw the displacements
            darkgreen=[0 0.6 0];
            e=U(1:2:length(U));
            f=U(2:2:length(U));
            quiver(x,y,e,f,'Color',darkgreen)
            hold off
            axis equal
            title('Original mesh with nodal displacements');

        case 3 % deformed mesh
            displstruct = handles.displ;
            U=displstruct.displ;
            
            % prompt for magnification factor
            mymag=inputdlg('What magnification factor on the displacement?','Mag. factor');
            magfac=str2num(mymag{1});

            nodes=np(:,[1 2 3 1])';
            % draw original mesh
            a=x(nodes);
            b=y(nodes);
            % draw deformed mesh
            c=a+magfac*U(2*nodes-1);
            d=b+magfac*U(2*nodes);
            hold on
            plot(a(:,1),b(:,1),'b',c(:,1),d(:,1),'r');
            plot(a,b,'b'); plot(c,d,'r');
            hold off
            legend('Mesh',['Deformed mesh (',num2str(magfac),'x)'])
            axis equal
            title(['Original and deformed mesh (',num2str(magfac),'x mag.)']);

        case 4 % Normal stress in x direction
            gsig = handles.sigeps.sig;
            r=handles.sigeps.sigrange;
            MakePatchPlot(gsig(:,1),r,meshstruct);
            title('Stress (\sigma_{xx}) [force/area]');
        case 5 % Shear stress
            gsig = handles.sigeps.sig;
            r=handles.sigeps.sigrange;
            MakePatchPlot(gsig(:,3),r,meshstruct);
            title('Stress (\sigma_{xy}) [force/area]');
        case 6 % Normal stress in y direction
            gsig = handles.sigeps.sig;
            r=handles.sigeps.sigrange;
            MakePatchPlot(gsig(:,2),r,meshstruct);
            title('Stress (\sigma_{yy}) [force/area]');
        case 7 % First principal stress
            PS = handles.principals.princstress;
            r=handles.principals.sigrange;
            MakePatchPlot(PS(:,1),r,meshstruct);
            title('Principal Stress (\sigma_{11}) [force/area]');
        case 8 % Second principal stress
            PS = handles.principals.princstress;
            r=handles.principals.sigrange;
            MakePatchPlot(PS(:,2),r,meshstruct);
            title('Principal Stress (\sigma_{22}) [force/area]');
        case 9 % Effective stress
            sigeff = handles.effstress;
            r=handles.sigeps.sigrange;
            MakePatchPlot(sigeff(:,1),r,meshstruct);
            title('Octahedral Shear Stress (\tau_{oct}) [force/area]');
        case 10 % Normal strain in x direction
            geps = handles.sigeps.eps;
            r=handles.sigeps.epsrange;
            MakePatchPlot(geps(:,1),r,meshstruct);
            title('Strain (\epsilon_{xx}) [-]');
        case 11 % Shear strain
            geps = handles.sigeps.eps;
            r=handles.sigeps.epsrange;
            MakePatchPlot(geps(:,3),r,meshstruct);
            title('Strain (\epsilon_{xy}) [-]');
        case 12 % Normal strain in y direction
            geps = handles.sigeps.eps;
            r=handles.sigeps.epsrange;
            MakePatchPlot(geps(:,2),r,meshstruct);
            title('Strain (\epsilon_{yy}) [-]');
        case 13 % First principal strain
            PS = handles.principals.princstrain;
            r=handles.principals.epsrange;
            MakePatchPlot(PS(:,1),r,meshstruct);
            title('Principal Strain (\epsilon_{11}) [-]');
        case 14 % Second principal strain
            PS = handles.principals.princstrain;
            r=handles.principals.epsrange;
            MakePatchPlot(PS(:,2),r,meshstruct);
            title('Principal Strain (\epsilon_{22}) [-]');
        case 15 % Rotation
            rot = handles.sigeps.rotation;
            r=handles.sigeps.rotrange;
            MakePatchPlot(rot(:,3),r,meshstruct);
            title('Rotation [-]');
        case 16 % Fringes
            PlotFringes(handles.mainguifig);
            title('Isochromatic Fringe Pattern');

        case 17 % Help with plotting
            redAnTSHelp('PlotMenu');
            ToggleStatus(2,handles.mainguifig);
    end

    if val~=17
        % set labels
        xlabel('X position [length]');
        ylabel('Y position [length]');
        drawnow
        ToggleStatus(0,handles.mainguifig);
    end
catch
    set(handles.error_text,'String',lasterr);
    ToggleStatus(2,handles.mainguifig);
end


% --- Executes during object creation, after setting all properties.
function plotpopupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to plotpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in postprocpopupmenu.
function postprocpopupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to postprocpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns postprocpopupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from postprocpopupmenu

val = get(hObject,'Value');
try
    set(handles.error_text,'String','');
    ToggleStatus(1,handles.mainguifig);
    switch val
        case 1  % Strain and stress
            handles.sigeps = CalcStrainStress(handles.mainguifig);

        case 2  % Principal Strain, principal stress
            handles.principals = CalcPrincipals(handles.mainguifig);

        case 3  % Effective stress
            handles.effstress = CalcEffectiveStress(handles.mainguifig);

        case 4  % Fringes
            handles.fringes = CalcFringes(handles.mainguifig);

        case 5  % Help
            redAnTSHelp('PostprocessMenu');
            ToggleStatus(2,handles.mainguifig);
    end
    guidata(hObject,handles);
    handles.postprocfile=MakePostProcSettings(handles.mainguifig);
    if val~=5
        ToggleStatus(0,handles.mainguifig);
    end
    guidata(hObject,handles);
    UpdateSettings(handles.mainguifig);
catch
    set(handles.error_text,'String',sprintf([lasterr,'\nNo solution yet? No stress/strain yet?']));
    ToggleStatus(2,handles.mainguifig);
end
% --- Executes during object creation, after setting all properties.
function postprocpopupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to postprocpopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in solvepopupmenu.
function solvepopupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to solvepopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns solvepopupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from solvepopupmenu

val = get(hObject,'Value');
try
    set(handles.error_text,'String','');
    ToggleStatus(1,handles.mainguifig);
    switch val

        case 1 % Static Elasticity
            StaticElast(handles.mainguifig)
            handles=guidata(handles.mainguifig);

        case 2 % Help
            redAnTSHelp('SolverMenu');
            ToggleStatus(2,handles.mainguifig);
    end
    % a new solution exists: remove fields that are no longer valid
    if val~=2
        SETTINGSFILES={'postprocfile','sigeps','principals','effstress','fringes'};
        for i=1:length(SETTINGSFILES)
            if isfield(handles,SETTINGSFILES{i})
                handles=rmfield(handles,SETTINGSFILES{i});
            end
        end
        ToggleStatus(0,handles.mainguifig);
    end
    guidata(hObject,handles);
    UpdateSettings(handles.mainguifig);
catch
    set(handles.error_text,'String',sprintf([lasterr,'\nMissing input data? Poorly formed mesh?']));
    ToggleStatus(2,handles.mainguifig);
end

% --- Executes during object creation, after setting all properties.
function solvepopupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to solvepopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in inputdatapopupmenu.
function inputdatapopupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to inputdatapopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns inputdatapopupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from inputdatapopupmenu

val = get(hObject,'Value');

try
    set(handles.error_text,'String','');
    switch val

        case 1 % Import existing input file
            [handles.inputfile, handles.prop, handles.bcsi,pBCinfo] = ImportInput(handles.mainguifig);
            guidata(hObject,handles);
            % apply point bcs where applicable
            for j=1:size(pBCinfo,1)
                ApplyPointBCs(handles.mainguifig, pBCinfo(j,:));
            end
            handles=guidata(hObject);

        case 2 % Opens a dialogue for properties
            if isfield(handles,'inputfile')
                handles=rmfield(handles,'inputfile');
            end
            prompt={'E [force/area]','\nu [-]','\alpha [1/temperature]'};
            name='Mat''l Prop''s';
            numlines=1;
            if isfield(handles,'prop') & isfield(handles.prop,'youngmodulus')
                da={num2str(handles.prop.youngmodulus),...
                    num2str(handles.prop.poissonratio),...
                    num2str(handles.prop.thermalcoeff)};
            else
                da={'200e9','0.30','0'};
            end
            options.Interpreter='tex';
            properties=inputdlg(prompt,name,numlines,da,options);
            if ~isempty(properties)
                handles.prop.youngmodulus=str2num(properties{1});
                handles.prop.poissonratio=str2num(properties{2});
                handles.prop.thermalcoeff=str2num(properties{3});
                if handles.prop.youngmodulus<0
                    if isfield(handles.prop,'anisomods')
                        dans={num2str(handles.prop.anisomods(1)),...
                            num2str(handles.prop.anisomods(2)),...
                            num2str(handles.prop.anisomods(3)),...
                            num2str(handles.prop.anisomods(4)),...
                            num2str(handles.prop.anisomods(5)),...
                            num2str(handles.prop.anisomods(6)),...
                            num2str(handles.prop.anisomods(7)),...
                            num2str(handles.prop.anisomods(8)),...
                            num2str(handles.prop.anisomods(9))};
                    else
                        dans={'168e9','168e9','168e9','121e9','121e9',...
                        '121e9','151e9','151e9','151e9'};
                    end
                    am=...
                        inputdlg({'c_{11}','c_{22}','c_{33}','c_{12}',...
                        'c_{13}','c_{23}','c_{44}','c_{55}','c_{66}'},...
                        'Moduli',1,dans,options);
                    handles.prop.anisomods=[...
                        str2num(am{1}) str2num(am{2}) str2num(am{3}) ...
                        str2num(am{4}) str2num(am{5}) str2num(am{6}) ...
                        str2num(am{7}) str2num(am{8}) str2num(am{9})];
                end
            end

        case 3 % Opens a dialogue for surface BCs
            if isfield(handles,'inputfile')
                handles=rmfield(handles,'inputfile');
            end
            handles.bcsi = GetSurfBCs(handles.mainguifig);

        case 4 % Opens a dialogue for point BCs
            if isfield(handles,'inputfile')
                handles=rmfield(handles,'inputfile');
            end
            GetPointBCs(handles.mainguifig);
            handles=guidata(handles.mainguifig);

        case 5 % Opens a dialogue for bodyforces
            if isfield(handles,'inputfile')
                handles=rmfield(handles,'inputfile');
            end
            prompt={'X-direction body force','Y-direction body force'};
            name='Body Forces';
            numlines=1;
            if isfield(handles,'prop') & isfield(handles.prop,'bodyforce')
                da={num2str(handles.prop.bodyforce(1)),...
                    num2str(handles.prop.bodyforce(2))};
            else
                da={'0','0'};
            end
            bfs=inputdlg(prompt,name,numlines,da);
            if ~isempty(bfs)
                handles.prop.bodyforce=[str2num(bfs{1});str2num(bfs{2})];

            end

        case 6 % Opens a dialogue for options
            if isfield(handles,'inputfile')
                handles=rmfield(handles,'inputfile');
            end
            prompt={'IPSOS (1 for plane strain, 2 for plane stress)','Temperature change'};
            name='Additional Options';
            numlines=1;
            if isfield(handles,'prop') & isfield(handles.prop,'twoDflag')
                da={num2str(handles.prop.twoDflag),...
                    num2str(handles.prop.deltatemp)};
            else
                da={'1','0'};
            end
            opts=inputdlg(prompt,name,numlines,da);
            if ~isempty(opts)
                handles.prop.twoDflag=str2num(opts{1});
                handles.prop.deltatemp=str2num(opts{2});
           end

        case 7 % Writes an input file for later use with case 1
            count=0;
            if isfield(handles,'prop')
                files={'twoDflag','bodyforce','youngmodulus','bcsi'};
                for i=1:3
                    if isfield(handles.prop,files{i})
                        count=count+1;
                    end
                end
                if isfield(handles,files{4})
                    count=count+1;
                end
            end

            if count==4
                handles.inputfile=WriteInput(handles.mainguifig);
            else
                set(handles.error_text,'String','All inputs must exist before writing input file.');
            end

        case 8 % Help
            helptext=redAnTSHelp('InputMenu');
            ToggleStatus(2,handles.mainguifig);
    end
    guidata(hObject,handles);
    if val~=8
        MakeInputSettings(handles.mainguifig);
        handles=guidata(handles.mainguifig);
    end
    if (val~=1) &&(val~=7) &&(val~=8)
        ToggleStatus(2,handles.mainguifig);
    end
    guidata(hObject,handles);
    UpdateSettings(handles.mainguifig);
catch
    set(handles.error_text,'String',sprintf([lasterr,'\nPressed Cancel? Wrong file? Closed dialogue? No mesh?']));
    ToggleStatus(2,handles.mainguifig);
end

%
% --- Executes during object creation, after setting all properties.
function inputdatapopupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to inputdatapopupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --------------------------------------------------------------------
function HelpMenu_Callback(hObject, eventdata, handles)
% --------------------------------------------------------------------
function rAtutorial_Callback(hObject, eventdata, handles)
web(['file:///' which('redAnTS_tutorial.htm')], '-helpbrowser');
% --------------------------------------------------------------------
function CSGPBCtutorial_Callback(hObject, eventdata, handles)
web(['file:///' which('pointBC_tut.htm')], '-helpbrowser');



function helptext=redAnTSHelp(whichmenu)
switch whichmenu
    case 'MeshMenu'
        helptext=['text://<html>',...
            '<p>There are four choices for mesh creation: <br>',...
            'You may import a mesh file created using the mapping method, <br>',...
            'you may import a mesh file created using the CSG Toolbox, <br>',...
            'you may create a new mesh using the mapping method or <br>you may ',...
            'create a new mesh using the CSG Toolbox. ',...
            '<p>If you choose the first option, ',...
            'the function MappingMethod will be called. You will be prompted for a ',...
            'text file, usually with a *.dat extension. This text file is the result of running ',...
            'the program mesh_3tri and it contains the mesh node locations, connectivity, and edge array.',...
            '<p>If you choose the second option, the function CSGMethod will be called. ',...
            'You will be prompted for a .mat file containing the variables ',...
            'p e and t, which are the results of running the CSG Toolbox.',...
            '<p>If you choose the third option, the MappingMeshMethod GUI will be called. You will create the domain, ',...
            'the program mesh_3tri will be run on the domain, and the function MappingMethod will ',...
            'be run on the results of that program.',...
            '<p>If you choose the fourth option, CSGtool will be called. You will create the mesh, ',...
            'and the function CSGMethod will be run on that mesh.',...
            '<p>Any of those four choices will result in the creation of the fields ',...
            'handles.mesh and handles.meshfile in the GUI handles structure. handles.mesh contains the fields ',...
            'size, xcoords, ycoords, connect, and edges.</html>'];

    case 'InputMenu'
        helptext=['text://<html>',...
            '<p>Before setting input data, there must be an active mesh file ',...
            '(resulting from a choice on the Mesh menu).',...
            '<p>There are two methods for inputting problem data. ',...
            'You may import a file that contains all of the relevant information, ',...
            'or you may use dialogues to define each type of input separately.',...
            '<p>Choosing "Import file" will bring up a prompt for the input data file, ',...
            'usually with the extension .in. This file contains material properties, ',...
            'boundary conditions, body forces, and option flags. It can be created by hand, ',...
            'or it can be generated automatically from the dialogues. See below for the format.',...
            '<p>Choosing "Set Properties" will bring up an input dialogue for material properties ',...
            '(Young''s modulus, Poisson''s ratio, and coefficient of thermal expansion). ',...
            '<p>Choosing "Set Surface BC''s" will draw and number the boundaries in the main GUI axes. ',...
            'It will then show an input dialogue for the type and value of the normal and tangential ',...
            'boundary conditions on each boundary segment (see help GetSurfBCs). ',...
            'Note that setting surface BC''s overwrites any point BC''s already set on the surface.',...
            '<p>Choosing "Set Point BC''s" will draw all the nodes in the main GUI axes. ',...
            'It will then show an input dialogue for entering boundary conditions at a point ',...
            '(see help GetPointBCs). ',...
            '<p>Choosing "Set BodyForces" will bring up an input dialogue for ',...
            'body forces in the x and y directions. ',...
            '<p>Choosing "Set Options" will bring up an input dialogue for ',...
            'options, such as a flag for plane stress or plane strain, and the temperature change. ',...
            '<p>Choosing "Write Input File" will allow you to save the values entered ',...
            'in the various dialogues into a file that can later be loaded using the ',...
            '"Import file" option. ',...
            '<p>Using either of the two methods (importing or dialogues) will result in ',...
            'the fields handles.inputfile, handles.prop, and handles.bcsi in the ',...
            'GUI handles structure.',...
            '<p>The format of the input file is as follows:<br>',...
            'Plane strain / plane stress flag<br>',...
            'E, Poisson''s ratio, thermal expansion coefficient<br>',...
            'X body force, Y body force<br>',...
            'Temperature change<br>',...
            'Number of boundaries<br>',...
            '(Then, for each boundary there is a line with three numbers, which are:)<br>',...
            'BC type, BC Normal component, BC Tangential component<br>',...
            'Number of point BCs<br>',...
            '(Then, for each point BC there is a line with six numbers, which are:)<br>',...
            'X coord, Y coord, BC type, BC Norm. comp., BC Tang. comp., Angle between global and local</html>'];

    case 'SolverMenu'
        helptext=['text://<html>',...
            '<p>This menu runs the finite element analysis. Before ',...
            'using the solver there must be an active mesh file ',...
            '(resulting from a selection on the mesh menu) and active input data ',...
            '(resulting from selections on the input data menu). ',...
            'The Static solver will run a static 2D plane stress or plane strain ',...
            'elasticity problem using the function StaticElast.',...
            '<p>The results of this menu are the fields handles.solutionexists ',...
            'and handles.displ in the GUI handles structure.'];

    case 'PostprocessMenu'
        helptext=['text://<html>',...
            '<p>After the problem has been solved, the field handles.displ will exist. ',...
            'In order to see stresses or strains in the body, it is necessary to ',...
            'perform post-processing calculations. Before making any choice on this ',...
            'menu, handles.displ must exist.',...
            '<p>The first option on this menu will call the function CalcStrainStress. ',...
            'The results will be saved to the field handles.sigeps. ',...
            '<p>The second option on this menu will call the function CalcPrincipals. ',...
            'The results will be saved to the field handles.principals. ',...
            '<p>The third option on this menu will call the function CalcEffectiveStress. ',...
            'The results will be saved to the field handles.effstress. ',...
            '<p>The fourth option on this menu will call the function CalcFringes. ',...
            'The results will be saved to the field handles.fringes. ',...
            '<p>To view any results, use the Plotting menu. To see the actual arrays, ',...
            'use the Export menu.'];

    case 'PlotMenu'
        helptext=['text://<html>',...
            '<p>Selections from this menu will create plots in the GUI axes. ',...
            'Before attempting to plot, the variable to be plotted must exist. <br>',...
            'Plotting the mesh requires the existance of the field handles.mesh. <br>',...
            'Plotting the displacements requires the existance of the field handles.displ ',...
            '(i.e. results from the Solver menu). <br>',...
            'Plotting any stresses, strains, or fringes requires some results from the Post-Processing menu.',...
            '<p>In order to save the resulting plot, use the Export menu.'];

    case 'ExportMenu'
        helptext=['text://<html>',...
            '<p>This menu allows you to export either the important variables ',...
            'or the current plot. ',...
            '<p>If you choose "Workspace," you will be prompted for a .mat filename. ',...
            'Any of the following variables that exist as fields in the GUI handles structure ',...
            'will be saved to that workspace:<br>',...
            'mesh <br>prop <br>bcsi <br>displ <br>sigeps <br>principals <br>effstress <br>fringes',...
            '<p>If you choose "Plot," you will be prompted for a .fig filename. ',...
            'The plot in the GUI axes will be saved to that file as a new figure.</html>'];
end

web(helptext,'-notoolbar');

