classdef app1 < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                      matlab.ui.Figure
        TabGroup                      matlab.ui.container.TabGroup
        DataimportTab                 matlab.ui.container.Tab
        InputdatalocationEditFieldLabel  matlab.ui.control.Label
        InputdatalocationEditField    matlab.ui.control.EditField
        ResultdatalocationEditFieldLabel  matlab.ui.control.Label
        ResultdatalocationEditField   matlab.ui.control.EditField
        LoaddataButton                matlab.ui.control.Button
        ConstraintsTab                matlab.ui.container.Tab
        UITable2                      matlab.ui.control.Table
        LinkandsolutionlistsTab       matlab.ui.container.Tab
        UITable3                      matlab.ui.control.Table
        UITable                       matlab.ui.control.Table
        SolutionsinselectedlistTab    matlab.ui.container.Tab
        UITable4                      matlab.ui.control.Table
        PlotTab                       matlab.ui.container.Tab
        AzimuthSliderLabel            matlab.ui.control.Label
        AzimuthSlider                 matlab.ui.control.Slider
        ElevationSliderLabel          matlab.ui.control.Label
        ElevationSlider               matlab.ui.control.Slider
        UIAxes                        matlab.ui.control.UIAxes
        ShapenameDropDownLabel        matlab.ui.control.Label
        ShapenameDropDown             matlab.ui.control.DropDown
        ConstraintsDropDownLabel      matlab.ui.control.Label
        ConstraintsDropDown           matlab.ui.control.DropDown
        NumberofstrutscellindexEditFieldLabel  matlab.ui.control.Label
        NumberofstrutscellindexEditField  matlab.ui.control.NumericEditField
        SolutionnumberEditFieldLabel  matlab.ui.control.Label
        SolutionnumberEditField       matlab.ui.control.NumericEditField
        EditField                     matlab.ui.control.EditField
        EditField_2                   matlab.ui.control.EditField
        CustomstrutsetCheckBox        matlab.ui.control.CheckBox
        SearchforsolutionCheckBox     matlab.ui.control.CheckBox
    end

    
    properties (Access = private)
        PossibleShapes % Set of shapes we can display
        InputTable % Table of input shapes
        ResultTable % Table of constraints and resulting data
        NeighborMatrix % Neighbor matrix
        NodePositions % Node positions
        PossibleResults % Set of results with the selected shapes
        ConstraintSets % Set of constraints for the given results
        SelectedSet
        TotalSolutions
        ChosenMechanism
        LinkList
    end
    
    methods (Access = private)
        
        function tensegrityGraphPlot(app)
            overallGraph = graph(app.NeighborMatrix,'omitselfloops');
            colormat = [0 0.4470 0.7410; 1 0 0];
            sizemat = [1 3];
            if ~isempty(app.ChosenMechanism)
                list_edges = app.LinkList(app.ChosenMechanism,:);
                k = addedge(overallGraph,list_edges(:,1),list_edges(:,2),2);
                
                plot(k,'EdgeColor',colormat(k.Edges.Weight,:),...
                    'XData',app.NodePositions(:,1),'YData',app.NodePositions(:,2),'ZData',app.NodePositions(:,3),...
                    'LineWidth',sizemat(k.Edges.Weight),'EdgeAlpha',1,'NodeLabel',{},'Parent',app.UIAxes)
                app.UIAxes.Color = 'none';
                app.UIAxes.DataAspectRatio = [1 1 1];
                axis(app.UIAxes,'off')
            else
                k = overallGraph;
                plot(k,'EdgeColor',colormat(k.Edges.Weight,:),...
                'XData',app.NodePositions(:,1),'YData',app.NodePositions(:,2),'ZData',app.NodePositions(:,3),...
                'LineWidth',sizemat(k.Edges.Weight),'EdgeAlpha',1,'NodeFontSize',14,'Parent',app.UIAxes)
                app.UIAxes.Color = 'none';
                app.UIAxes.DataAspectRatio = [1 1 1];
                axis(app.UIAxes,'off')
            end
            [tempAz,tempEl] = view(app.UIAxes);
            app.AzimuthSlider.Value = mod(tempAz,360);
            app.ElevationSlider.Value = mod(tempEl,360);
        end
    end

    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            app.ShapenameDropDown.Visible = 'off';
            app.ConstraintsDropDown.Visible = 'off';
            app.NumberofstrutscellindexEditField.Visible = 'off';
            app.SolutionnumberEditField.Visible = 'off';
            app.SearchforsolutionCheckBox.Visible = 'off';
            app.CustomstrutsetCheckBox.Visible = 'off';
            app.ShapenameDropDownLabel.Visible = 'off';
            app.ConstraintsDropDownLabel.Visible = 'off';
            app.NumberofstrutscellindexEditFieldLabel.Visible = 'off';
            app.SolutionnumberEditFieldLabel.Visible = 'off';
            app.EditField.Visible = 'off';
            app.EditField_2.Visible = 'off';
        end

        % Button pushed function: LoaddataButton
        function LoaddataButtonPushed(app, event)
            load(app.InputdatalocationEditField.Value)
            load(app.ResultdatalocationEditField.Value)
            app.InputTable = inputTable;
            app.ResultTable = resultData;
            app.PossibleShapes = app.InputTable{:,1};
            app.ShapenameDropDown.Items = app.PossibleShapes;
            app.ShapenameDropDown.Visible = 'on';
            app.ShapenameDropDownLabel.Visible = 'on';
        end

        % Value changed function: ShapenameDropDown
        function ShapenameDropDownValueChanged(app, event)
            value = app.ShapenameDropDown.Value;
            rowOfInterest = app.InputTable(app.InputTable.Name==value,:);
            app.NeighborMatrix = rowOfInterest.Neighbor_matrix{:};
            app.NodePositions = rowOfInterest.Node_positions{:};
            app.PossibleResults = app.ResultTable(app.ResultTable.Name == value,:);
            tempConstraintSets = app.ResultTable(app.ResultTable.Name == value,2:9);
            app.ConstraintSets = join(erase(string(tempConstraintSets{:, :}), "'"), '', 2);
            totalRows = string(num2str((1:size(app.ConstraintSets,1)).'));
            app.ConstraintsDropDown.Items = strcat("Data row ",totalRows);
            app.UITable2.ColumnName = tempConstraintSets.Properties.VariableNames;
            app.UITable2.Data = tempConstraintSets;
            app.ConstraintsDropDown.Visible = 'on';
            app.ConstraintsDropDownLabel.Visible = 'on';
        end

        % Value changed function: ConstraintsDropDown
        function ConstraintsDropDownValueChanged(app, event)
            value = app.ConstraintsDropDown.Value;
            numberValue = sscanf(value,"Data row %d");
            app.SelectedSet = app.PossibleResults(numberValue,:);
            app.UITable.Data = app.SelectedSet.Link_list{:};
            app.LinkList = app.SelectedSet.Link_list{:};
            strutSizeData = cellfun(@(x) size(x,1),app.SelectedSet.Solution_set{:});
            app.UITable3.Data = [(1:size(strutSizeData,2)).' strutSizeData.'];
            app.NumberofstrutscellindexEditField.Visible = 'on';
            app.SolutionnumberEditField.Visible = 'on';
            app.SearchforsolutionCheckBox.Visible = 'on';
            app.CustomstrutsetCheckBox.Visible = 'on';
            app.NumberofstrutscellindexEditFieldLabel.Visible = 'on';
            app.SolutionnumberEditFieldLabel.Visible = 'on'; 
            app.TotalSolutions= app.SelectedSet.Solution_set{:};
        end

        % Value changed function: NumberofstrutscellindexEditField
        function NumberofstrutscellindexEditFieldValueChanged(app, event)
            value = app.NumberofstrutscellindexEditField.Value;
            app.UITable4.Data = app.TotalSolutions{value};
            app.SolutionnumberEditField.Value = 0;
            app.ChosenMechanism = [];
            tensegrityGraphPlot(app);
            
        end

        % Value changed function: SolutionnumberEditField
        function SolutionnumberEditFieldValueChanged(app, event)
            value = app.SolutionnumberEditField.Value;
            if ~app.SearchforsolutionCheckBox.Value && ~app.CustomstrutsetCheckBox.Value
                try
                    app.ChosenMechanism = app.TotalSolutions{app.NumberofstrutscellindexEditField.Value}(value,:);
                catch
                    warning('Selection out of range. Proceeding with no selection.')
                    app.ChosenMechanism = [];
                end
            end
            tensegrityGraphPlot(app)
        end

        % Value changed function: SearchforsolutionCheckBox
        function SearchforsolutionCheckBoxValueChanged(app, event)
            value = app.SearchforsolutionCheckBox.Value;
            if app.CustomstrutsetCheckBox.Value
                app.CustomstrutsetCheckBox.Value = false;
                app.EditField_2.Visible = 'off';
            end
            app.EditField.Visible = value;
            app.ChosenMechanism = [];
            tensegrityGraphPlot(app);
        end

        % Value changed function: CustomstrutsetCheckBox
        function CustomstrutsetCheckBoxValueChanged(app, event)
            value = app.CustomstrutsetCheckBox.Value;
            if app.SearchforsolutionCheckBox.Value
                app.SearchforsolutionCheckBox.Value = false;
                app.EditField.Visible = 'off';
            end
            app.EditField_2.Visible = value;
            app.ChosenMechanism = [];
            tensegrityGraphPlot(app);
        end

        % Value changed function: EditField
        function EditFieldValueChanged(app, event)
            value = app.EditField.Value;
            strutSet = split(value,' ');
            invStrut = sort(str2double(strutSet).',2);
            numStruts = size(invStrut,2);
            possibleSolutionSet = app.TotalSolutions{numStruts};
            if ismember(invStrut,possibleSolutionSet,'rows')
                app.ChosenMechanism = invStrut;
            else
                app.ChosenMechanism = [];
            end
            tensegrityGraphPlot(app)
        end

        % Value changed function: EditField_2
        function EditField_2ValueChanged(app, event)
            value = app.EditField_2.Value;
            strutSet = split(value,' ');
            app.ChosenMechanism = str2double(strutSet);
            tensegrityGraphPlot(app)
        end

        % Size changed function: PlotTab
        function PlotTabSizeChanged(app, event)
            position = app.PlotTab.Position;
            
        end

        % Value changed function: AzimuthSlider
        function AzimuthSliderValueChanged(app, event)
            view(app.UIAxes,app.AzimuthSlider.Value,app.ElevationSlider.Value)
        end

        % Value changed function: ElevationSlider
        function ElevationSliderValueChanged(app, event)
            view(app.UIAxes,app.AzimuthSlider.Value,app.ElevationSlider.Value)
        end

        % Value changing function: AzimuthSlider
        function AzimuthSliderValueChanging(app, event)
            changingValue = event.Value;
            view(app.UIAxes,changingValue,app.ElevationSlider.Value)
        end

        % Value changing function: ElevationSlider
        function ElevationSliderValueChanging(app, event)
            changingValue = event.Value;
            view(app.UIAxes,app.AzimuthSlider.Value,changingValue)
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.AutoResizeChildren = 'off';
            app.UIFigure.Position = [100 100 640 480];
            app.UIFigure.Name = 'MATLAB App';
            app.UIFigure.Resize = 'off';

            % Create TabGroup
            app.TabGroup = uitabgroup(app.UIFigure);
            app.TabGroup.AutoResizeChildren = 'off';
            app.TabGroup.Position = [210 32 406 419];

            % Create DataimportTab
            app.DataimportTab = uitab(app.TabGroup);
            app.DataimportTab.AutoResizeChildren = 'off';
            app.DataimportTab.Title = 'Data import';

            % Create InputdatalocationEditFieldLabel
            app.InputdatalocationEditFieldLabel = uilabel(app.DataimportTab);
            app.InputdatalocationEditFieldLabel.HorizontalAlignment = 'right';
            app.InputdatalocationEditFieldLabel.Position = [69 323 104 22];
            app.InputdatalocationEditFieldLabel.Text = 'Input data location';

            % Create InputdatalocationEditField
            app.InputdatalocationEditField = uieditfield(app.DataimportTab, 'text');
            app.InputdatalocationEditField.Position = [188 323 100 22];
            app.InputdatalocationEditField.Value = './inputTable.mat';

            % Create ResultdatalocationEditFieldLabel
            app.ResultdatalocationEditFieldLabel = uilabel(app.DataimportTab);
            app.ResultdatalocationEditFieldLabel.HorizontalAlignment = 'right';
            app.ResultdatalocationEditFieldLabel.Position = [62 302 111 22];
            app.ResultdatalocationEditFieldLabel.Text = 'Result data location';

            % Create ResultdatalocationEditField
            app.ResultdatalocationEditField = uieditfield(app.DataimportTab, 'text');
            app.ResultdatalocationEditField.Position = [188 302 100 22];
            app.ResultdatalocationEditField.Value = './ResultTable.mat';

            % Create LoaddataButton
            app.LoaddataButton = uibutton(app.DataimportTab, 'push');
            app.LoaddataButton.ButtonPushedFcn = createCallbackFcn(app, @LoaddataButtonPushed, true);
            app.LoaddataButton.Position = [129 245 100 22];
            app.LoaddataButton.Text = 'Load data';

            % Create ConstraintsTab
            app.ConstraintsTab = uitab(app.TabGroup);
            app.ConstraintsTab.AutoResizeChildren = 'off';
            app.ConstraintsTab.Title = 'Constraints';

            % Create UITable2
            app.UITable2 = uitable(app.ConstraintsTab);
            app.UITable2.ColumnName = {'Min_degree'; 'Max_degree'; 'Elim_iso'; 'No_ext'; 'No_cable'; 'Min_conn_comp'; 'Max_conn_comp'; 'Max_elements_connected'};
            app.UITable2.RowName = {};
            app.UITable2.Position = [1 0 405 394];

            % Create LinkandsolutionlistsTab
            app.LinkandsolutionlistsTab = uitab(app.TabGroup);
            app.LinkandsolutionlistsTab.AutoResizeChildren = 'off';
            app.LinkandsolutionlistsTab.Title = 'Link and solution lists';

            % Create UITable3
            app.UITable3 = uitable(app.LinkandsolutionlistsTab);
            app.UITable3.ColumnName = {'Strut count'; 'Number of solutions'};
            app.UITable3.RowName = {};
            app.UITable3.Position = [188 0 217 394];

            % Create UITable
            app.UITable = uitable(app.LinkandsolutionlistsTab);
            app.UITable.ColumnName = {'Node 1'; 'Node 2'};
            app.UITable.ColumnWidth = {100};
            app.UITable.RowName = {};
            app.UITable.Position = [0 0 189 394];

            % Create SolutionsinselectedlistTab
            app.SolutionsinselectedlistTab = uitab(app.TabGroup);
            app.SolutionsinselectedlistTab.AutoResizeChildren = 'off';
            app.SolutionsinselectedlistTab.Title = 'Solutions in selected list';

            % Create UITable4
            app.UITable4 = uitable(app.SolutionsinselectedlistTab);
            app.UITable4.ColumnName = {'Column 1'; 'Column 2'; 'Column 3'; 'Column 4'};
            app.UITable4.RowName = {};
            app.UITable4.Position = [1 1 404 393];

            % Create PlotTab
            app.PlotTab = uitab(app.TabGroup);
            app.PlotTab.AutoResizeChildren = 'off';
            app.PlotTab.SizeChangedFcn = createCallbackFcn(app, @PlotTabSizeChanged, true);
            app.PlotTab.Title = 'Plot';

            % Create AzimuthSliderLabel
            app.AzimuthSliderLabel = uilabel(app.PlotTab);
            app.AzimuthSliderLabel.HorizontalAlignment = 'right';
            app.AzimuthSliderLabel.Position = [88 94 49 22];
            app.AzimuthSliderLabel.Text = 'Azimuth';

            % Create AzimuthSlider
            app.AzimuthSlider = uislider(app.PlotTab);
            app.AzimuthSlider.Limits = [0 360];
            app.AzimuthSlider.MajorTicks = [0 120 240 360];
            app.AzimuthSlider.ValueChangedFcn = createCallbackFcn(app, @AzimuthSliderValueChanged, true);
            app.AzimuthSlider.ValueChangingFcn = createCallbackFcn(app, @AzimuthSliderValueChanging, true);
            app.AzimuthSlider.Position = [158 103 150 3];

            % Create ElevationSliderLabel
            app.ElevationSliderLabel = uilabel(app.PlotTab);
            app.ElevationSliderLabel.HorizontalAlignment = 'right';
            app.ElevationSliderLabel.Position = [82 52 55 22];
            app.ElevationSliderLabel.Text = 'Elevation';

            % Create ElevationSlider
            app.ElevationSlider = uislider(app.PlotTab);
            app.ElevationSlider.Limits = [0 360];
            app.ElevationSlider.MajorTicks = [0 120 240 360];
            app.ElevationSlider.ValueChangedFcn = createCallbackFcn(app, @ElevationSliderValueChanged, true);
            app.ElevationSlider.ValueChangingFcn = createCallbackFcn(app, @ElevationSliderValueChanging, true);
            app.ElevationSlider.Position = [158 61 150 3];

            % Create UIAxes
            app.UIAxes = uiaxes(app.PlotTab);
            app.UIAxes.Position = [0 123 406 271];

            % Create ShapenameDropDownLabel
            app.ShapenameDropDownLabel = uilabel(app.UIFigure);
            app.ShapenameDropDownLabel.HorizontalAlignment = 'right';
            app.ShapenameDropDownLabel.Position = [6 376 74 22];
            app.ShapenameDropDownLabel.Text = 'Shape name';

            % Create ShapenameDropDown
            app.ShapenameDropDown = uidropdown(app.UIFigure);
            app.ShapenameDropDown.ValueChangedFcn = createCallbackFcn(app, @ShapenameDropDownValueChanged, true);
            app.ShapenameDropDown.Position = [95 376 100 22];

            % Create ConstraintsDropDownLabel
            app.ConstraintsDropDownLabel = uilabel(app.UIFigure);
            app.ConstraintsDropDownLabel.HorizontalAlignment = 'right';
            app.ConstraintsDropDownLabel.Position = [14 334 66 22];
            app.ConstraintsDropDownLabel.Text = 'Constraints';

            % Create ConstraintsDropDown
            app.ConstraintsDropDown = uidropdown(app.UIFigure);
            app.ConstraintsDropDown.ValueChangedFcn = createCallbackFcn(app, @ConstraintsDropDownValueChanged, true);
            app.ConstraintsDropDown.Position = [95 334 100 22];

            % Create NumberofstrutscellindexEditFieldLabel
            app.NumberofstrutscellindexEditFieldLabel = uilabel(app.UIFigure);
            app.NumberofstrutscellindexEditFieldLabel.HorizontalAlignment = 'right';
            app.NumberofstrutscellindexEditFieldLabel.Position = [6 298 156 22];
            app.NumberofstrutscellindexEditFieldLabel.Text = 'Number of struts (cell index)';

            % Create NumberofstrutscellindexEditField
            app.NumberofstrutscellindexEditField = uieditfield(app.UIFigure, 'numeric');
            app.NumberofstrutscellindexEditField.ValueChangedFcn = createCallbackFcn(app, @NumberofstrutscellindexEditFieldValueChanged, true);
            app.NumberofstrutscellindexEditField.Position = [168 298 27 22];

            % Create SolutionnumberEditFieldLabel
            app.SolutionnumberEditFieldLabel = uilabel(app.UIFigure);
            app.SolutionnumberEditFieldLabel.HorizontalAlignment = 'right';
            app.SolutionnumberEditFieldLabel.Position = [14 277 93 22];
            app.SolutionnumberEditFieldLabel.Text = 'Solution number';

            % Create SolutionnumberEditField
            app.SolutionnumberEditField = uieditfield(app.UIFigure, 'numeric');
            app.SolutionnumberEditField.ValueChangedFcn = createCallbackFcn(app, @SolutionnumberEditFieldValueChanged, true);
            app.SolutionnumberEditField.Position = [126 277 69 22];

            % Create EditField
            app.EditField = uieditfield(app.UIFigure, 'text');
            app.EditField.ValueChangedFcn = createCallbackFcn(app, @EditFieldValueChanged, true);
            app.EditField.Position = [14 218 169 22];

            % Create EditField_2
            app.EditField_2 = uieditfield(app.UIFigure, 'text');
            app.EditField_2.ValueChangedFcn = createCallbackFcn(app, @EditField_2ValueChanged, true);
            app.EditField_2.Position = [13 155 169 22];

            % Create CustomstrutsetCheckBox
            app.CustomstrutsetCheckBox = uicheckbox(app.UIFigure);
            app.CustomstrutsetCheckBox.ValueChangedFcn = createCallbackFcn(app, @CustomstrutsetCheckBoxValueChanged, true);
            app.CustomstrutsetCheckBox.Text = 'Custom strut set:';
            app.CustomstrutsetCheckBox.Position = [14 176 113 22];

            % Create SearchforsolutionCheckBox
            app.SearchforsolutionCheckBox = uicheckbox(app.UIFigure);
            app.SearchforsolutionCheckBox.ValueChangedFcn = createCallbackFcn(app, @SearchforsolutionCheckBoxValueChanged, true);
            app.SearchforsolutionCheckBox.Text = 'Search for solution:';
            app.SearchforsolutionCheckBox.Position = [14 239 125 22];

            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = app1

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end