classdef ExampleDirectoryApp < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                matlab.ui.Figure
        ChoosedatafromstructfieldsforeachnewfileCheckBox  matlab.ui.control.CheckBox
        min_ylim                matlab.ui.control.Spinner
        max_ylim                matlab.ui.control.Spinner
        UITable                 matlab.ui.control.Table
        DirectoryLocationLabel  matlab.ui.control.Label
        BrowseButton            matlab.ui.control.Button
        UIAxes                  matlab.ui.control.UIAxes
    end

    
    properties (Access = public)
        viewerdirectory
        psddata_struct_path = {}
        fs_struct_path = {}
    end
    
    methods (Access = public)
        
        function results = plot_s21_lab(app,data)
            plot(app.UIAxes,...
                data.f.*1e-9,...
                20*log10(abs(data.uFF)),...
                'DisplayName',['maxdB: ',num2str(i),' dB'],'LineWidth',0.5,'LineStyle','-','Marker','none','MarkerSize',5);
            legend(app.UIAxes);
            ylim(app.UIAxes, [app.min_ylim.Value,app.max_ylim.Value]);
            app.UIAxes.XMinorGrid ="on";
            app.UIAxes.YMinorGrid ="on";
            app.UIAxes.MinorGridAlpha = 0.5;
        end

        function plot_psd(app,data)
            
            [data_to_plot, app.psddata_struct_path] = app.get_field_from_struct(data,app.psddata_struct_path,"Select data for plot!");
            [fs_for_psd, app.fs_struct_path]        = app.get_field_from_struct(data,app.fs_struct_path,"Select Sampling requency!");

            spectrum_plot(data_to_plot,fs_for_psd)
        end

        function [data, struct_path] = get_field_from_struct(app,data,struct_path,promptstring)
        
                if isempty(struct_path) || app.ChoosedatafromstructfieldsforeachnewfileCheckBox.Value
                    %define, ask user
                    [data, struct_path]        = app.select_field_from_struct(data,promptstring);
                else
                    %load using known path in struct
                    [data]        = app.get_data_from_struct_using_structpath(data, struct_path);
                end

        end

        function [data] = get_data_from_struct_using_structpath(app,data, struct_path)

            for stage = 1:numel(struct_path)
                data = data.(struct_path{stage});
            end
        end

        function [data, struct_path] = select_field_from_struct(app,data,promptstring)
 
            fn = fieldnames(data);
            stage = 0;
            struct_path = {};
            while true
                stage = stage + 1;
                [indx,~] = listdlg('PromptString',{promptstring,...
                    'Only one file can be selected at a time.',''},...
                    'SelectionMode','single','ListString',fn);
                if isempty(indx)
                    break %user pressed cancel, there is no indy chosen
                end
                stage_idx(stage) = indx;
                struct_path{stage} = fn{indx};
                data = data.(fn{indx});

                if isstruct(data)
                    fn = fieldnames(data);
                else
                    break
                end

            end

            

        end
    end
    

    

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

        % Button pushed function: BrowseButton
        function BrowseButtonPushed(app, event)
            
            app.viewerdirectory=uigetdir;                   % Calls 'uigetdir' to obtain the directory location from the user
            app.UIFigure.Visible = 'off';     % Toggles figure visible.  These two lines of code work-around an issue whether the figure is sent to the background.
            app.UIFigure.Visible = 'on';      
            app.DirectoryLocationLabel.Text=app.viewerdirectory;  % Sets the label text to be the selected path

            a=dir(app.viewerdirectory);                         % Obtains the contents of the selected path.
            b={a(:).name}';                      % Gets the name of the files/folders of the contents and stores them appropriately in a cell array
            b(ismember(b,{'.','..'})) = [];      % Removes unnecessary '.' and '..' results from the display.
            b(~endsWith(b, '.mat')) = [];% Remove all files that are not .mat files

            
            app.UITable.Data=b;                  % Displays the directory information to the UITable.
        end

        % Callback function: UITable, max_ylim, min_ylim
        function UITableSelectionChanged(app, event)
            selection = app.UITable.Selection;
            for i = 1:size(selection,1)
                name = app.UITable.Data(selection(i,1));
                name = name{1};
                disp(['loading: ', name] );
                d = load([app.viewerdirectory,filesep,name]);

                app.plot_psd(d);


                % app.plot_s21_lab(d);
                
                
                hold(app.UIAxes, 'on');
            end
            hold(app.UIAxes, 'off');

        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.Color = [0.94 0.94 0.94];
            app.UIFigure.Position = [100 100 1030 564];
            app.UIFigure.Name = 'UI Figure';

            % Create UIAxes
            app.UIAxes = uiaxes(app.UIFigure);
            title(app.UIAxes, 'S 21 ; Frequency Response', 'Interpreter', 'latex')
            xlabel(app.UIAxes, 'Frequency in GHz', 'Interpreter', 'latex')
            ylabel(app.UIAxes, 'Amplitude in dB', 'Interpreter', 'latex')
            zlabel(app.UIAxes, 'Z', 'Interpreter', 'latex')
            app.UIAxes.TickLabelInterpreter = 'tex';
            app.UIAxes.XGrid = 'off';
            app.UIAxes.YGrid = 'off';
            app.UIAxes.ColorOrder = [0 0.447 0.741;0.85 0.325 0.098;0.929 0.694 0.125;0.494 0.184 0.556;0.466 0.674 0.188;0.301 0.745 0.933;0.635 0.078 0.184];
            colormap(app.UIAxes, 'parula')
            app.UIAxes.Position = [532 134 470 410];

            % Create BrowseButton
            app.BrowseButton = uibutton(app.UIFigure, 'push');
            app.BrowseButton.ButtonPushedFcn = createCallbackFcn(app, @BrowseButtonPushed, true);
            app.BrowseButton.Position = [22 498 100 46];
            app.BrowseButton.Text = 'Browse';

            % Create DirectoryLocationLabel
            app.DirectoryLocationLabel = uilabel(app.UIFigure);
            app.DirectoryLocationLabel.BackgroundColor = [1 1 1];
            app.DirectoryLocationLabel.Position = [135 498 361 46];
            app.DirectoryLocationLabel.Text = 'Directory Location';

            % Create UITable
            app.UITable = uitable(app.UIFigure);
            app.UITable.ColumnName = {'Directory Contents'};
            app.UITable.RowName = {};
            app.UITable.SelectionChangedFcn = createCallbackFcn(app, @UITableSelectionChanged, true);
            app.UITable.Position = [22 134 474 341];

            % Create max_ylim
            app.max_ylim = uispinner(app.UIFigure);
            app.max_ylim.ValueChangedFcn = createCallbackFcn(app, @UITableSelectionChanged, true);
            app.max_ylim.Position = [514 510 54 22];
            app.max_ylim.Value = 30;

            % Create min_ylim
            app.min_ylim = uispinner(app.UIFigure);
            app.min_ylim.ValueChangedFcn = createCallbackFcn(app, @UITableSelectionChanged, true);
            app.min_ylim.Position = [515 160 54 22];
            app.min_ylim.Value = -5;

            % Create ChoosedatafromstructfieldsforeachnewfileCheckBox
            app.ChoosedatafromstructfieldsforeachnewfileCheckBox = uicheckbox(app.UIFigure);
            app.ChoosedatafromstructfieldsforeachnewfileCheckBox.Text = 'Choose data from struct fields for each new file';
            app.ChoosedatafromstructfieldsforeachnewfileCheckBox.Position = [43 94 275 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 = ExampleDirectoryApp

            % Create UIFigure and components
            createComponents(app)

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

            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