classdef set_slices < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                     matlab.ui.Figure
        rotationaroundxaxisLabel     matlab.ui.control.Label
        rotationaroundyaxisanglesindegreesLabel  matlab.ui.control.Label
        unequalintervalsCheckBox     matlab.ui.control.CheckBox
        CancelButton                 matlab.ui.control.Button
        replicateCheckBox            matlab.ui.control.CheckBox
        APPLYButton                  matlab.ui.control.Button
        UITable                      matlab.ui.control.Table
        lastangleEditField_2         matlab.ui.control.NumericEditField
        lastangleEditField_2Label    matlab.ui.control.Label
        firstangleEditField_2        matlab.ui.control.NumericEditField
        firstangleEditField_2Label   matlab.ui.control.Label
        yEditField                   matlab.ui.control.NumericEditField
        yEditFieldLabel              matlab.ui.control.Label
        axispositionxEditField       matlab.ui.control.NumericEditField
        axispositionxEditFieldLabel  matlab.ui.control.Label
        lastangleEditField           matlab.ui.control.NumericEditField
        lastangleEditFieldLabel      matlab.ui.control.Label
        firstangleEditField          matlab.ui.control.NumericEditField
        firstangleEditFieldLabel     matlab.ui.control.Label
        volumescanCheckBox           matlab.ui.control.CheckBox
        NbSliceEditField             matlab.ui.control.NumericEditField
        NbSliceEditFieldLabel        matlab.ui.control.Label
        indexEditField               matlab.ui.control.NumericEditField
        indexEditFieldLabel          matlab.ui.control.Label
        refractionCheckBox           matlab.ui.control.CheckBox
        surfaceEditField             matlab.ui.control.NumericEditField
        surfaceEditFieldLabel        matlab.ui.control.Label
        firstZEditField              matlab.ui.control.NumericEditField
        firstZEditFieldLabel         matlab.ui.control.Label
        lastZEditField               matlab.ui.control.NumericEditField
        lastZEditFieldLabel          matlab.ui.control.Label
    end

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

        % Value changed function: refractionCheckBox
        function refractionCheckBoxValueChanged(app, event)
            value = app.refractionCheckBox.Value;
            if value
                status='on';
            else
                status='off';
            end
            app.indexEditField.Visible=status;
            app.surfaceEditField.Visible=status;
            app.surfaceEditFieldLabel.Visible=status;
            app.indexEditFieldLabel.Visible=status;
        end

        % Value changed function: unequalintervalsCheckBox
        function unequalintervalsCheckBoxValueChanged(app, event)
            value = app.unequalintervalsCheckBox.Value;
            if value
                app.UITable.Visible='on';
                NbSlice=app.NbSliceEditField.Value;
                FirstZ=app.firstZEditField.Value;
                LastZ=app.lastZEditField.Value
                FirstAngle1=app.firstangleEditField.Value;
                LastAngle1=app.lastangleEditField.Value;
                FirstAngle2=app.firstangleEditField_2.Value;
                LastAngle2=app.lastangleEditField_2.Value;
                app.UITable.Data=zeros(NbSlice,3);
                app.UITable.Data(:,1)=linspace(FirstZ,LastZ,NbSlice);
                app.UITable.Data(:,2)=linspace(FirstAngle1,LastAngle1,NbSlice);
                app.UITable.Data(:,3)=linspace(FirstAngle2,LastAngle2,NbSlice);
                app.UITable.ColumnEditable=[true true true];
            else
                app.UITable.Visible='off';
            end
        end

        % Button pushed function: APPLYButton
        function APPLYButtonPushed(app, event)
            app.APPLYButton.BackgroundColor=[1 1 0];% paint button in yellow to indicate action
            drawnow

            %% get the uvmat GUI data and read the current xml file
            huvmat=findobj(allchild(0),'Tag','uvmat');
            hhuvmat=guidata(huvmat);
            [RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(hhuvmat);
            FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];%name of the current input file
            [RootPath,SubDir,RootFile,tild,tild,tild,tild,FileExt]=fileparts_uvmat(FileName);
            XmlFile=find_imadoc(RootPath,SubDir,RootFile,FileExt);%find name of the relevant xml file
            if isempty(XmlFile)
                msgbox_uvmat('ERROR','an xml file with calibration parameters must be first created, use Tools/geometric calibration');
                return
            end
            [s,RootTag,errormsg]=xml2struct(XmlFile);

            %% read the content of the GUI set_slice
%             hset_slice=get(hObject, 'parent');
            hset_slice=app.UIFigure;
            Slice.NbSlice=app.NbSliceEditField.Value;
            if app.unequalintervalsCheckBox.Value
               Z_plane=app.UITable.Data(:,1);
                Angle_1=app.UITable.Data(:,2);
                 Angle_2=app.UITable.Data(:,3);
            else
               Z_plane=linspace(app.firstZEditField.Value,app.lastZEditField.Value,Slice.NbSlice)';
               Angle_1=linspace(app.firstangleEditField.Value,app.lastangleEditField.Value,Slice.NbSlice);
            Angle_2=linspace(app.firstangleEditField_2.Value,app.lastangleEditField_2.Value,Slice.NbSlice);
            end
            Slice.CheckVolumeScan=app.volumescanCheckBox.Value;

            Slice.SliceCoord=Z_plane*[0 0 1];
            Slice.SliceCoord(:,1)=app.axispositionxEditField.Value;
            Slice.SliceCoord(:,2)=app.yEditField.Value;
            Slice.SliceAngle=zeros(Slice.NbSlice,3);
            Slice.SliceAngle(:,1)=Angle_1';%rotation angle around x axis
            Slice.SliceAngle(:,2)=Angle_2';%rotation angle around y axis
            Slice.SliceAngle(:,3)=0;
            if app.refractionCheckBox.Value
                Slice.InterfaceCoord=[0 0 app.surfaceEditField.Value];
                Slice.RefractionIndex=app.indexEditField.Value;
            elseif isfield(Slice,'RefractionIndex')
                Slice=rmfield(Slice,'RefractionIndex');
                Slice=rmfield(Slice,'InterfaceCoord');
            end

            if app.replicateCheckBox.Value
                %% open the GUI browse_data
                hbrowse=findobj(allchild(0),'Tag','browse_data');
                if ~isempty(hbrowse)% look for the GUI browse_data
                    BrowseData=guidata(hbrowse);
                    SourceDir=get(BrowseData.SourceDir,'String');
                    ListExp=get(BrowseData.ListExperiments,'String');
                    ExpIndices=get(BrowseData.ListExperiments,'Value');
                    ListExp=ListExp(ExpIndices);
                    ListDevices=get(BrowseData.ListDevices,'String');
                    DeviceIndices=get(BrowseData.ListDevices,'Value');
                    ListDevices=ListDevices(DeviceIndices);
                    ListDataSeries=get(BrowseData.DataSeries,'String');
                    DataSeriesIndices=get(BrowseData.DataSeries,'Value');
                    ListDataSeries=ListDataSeries(DataSeriesIndices);
                    NbExp=0; % counter of the number of experiments set by the GUI browse_data
                    for iexp=1:numel(ListExp)
                        if ~isempty(regexp(ListExp{iexp},'^\+/'))% if it is a folder
                            for idevice=1:numel(ListDevices)
                                if ~isempty(regexp(ListDevices{idevice},'^\+/'))% if it is a folder
                                    for isubdir=1:numel(ListDataSeries)
                                        if ~isempty(regexp(ListDataSeries{isubdir},'^\+/'))% if it is a folder
                                            lpath= fullfile(SourceDir,regexprep(ListExp{iexp},'^\+/',''),...
                                                regexprep(ListDevices{idevice},'^\+/',''));
                                            ldir= regexprep(ListDataSeries{isubdir},'^\+/','');
                                            if exist(fullfile(lpath,ldir),'dir')
                                                NbExp=NbExp+1;
                                                ListPath{NbExp}=lpath;
                                                ListSubdir{NbExp}=ldir;
                                                ExpIndex{NbExp}=iexp;
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                    for iexp=1:NbExp
                        XmlName=fullfile(ListPath{iexp},[ListSubdir{iexp} '.xml']);
                        if exist(XmlName,'file')
                            check_update=1;
                        else
                            check_update=0;
                        end
                        errormsg=update_imadoc(Slice,XmlName,'Slice');% introduce the calibration data in the xml file
                        if ~strcmp(errormsg,'')
                            msgbox_uvmat('ERROR',errormsg);
                        else
                            if check_update
                                display([XmlName ' updated with slice positions'])
                            else
                                display([XmlName ' created with slice positions'])
                            end
                        end
                    end
                end
                msgbox_uvmat('CONFIMATION',['slices replicated for ' num2str(NbExp) ' experiments']);
            else

                %% store the result in the xml file used for calibration
                errormsg=update_imadoc(Slice,XmlFile,'Slice');% introduce the calibration data in the xml file
                if strcmp(errormsg,'')
                    msgbox_uvmat('CONFIRMATION',['slice positions saved in ' XmlFile]);
                else
                    msgbox_uvmat('ERROR',errormsg);
                end

                %% display image with new calibration in the currently opened uvmat interface
                %set(hhuvmat.CheckFixLimits,'Value',0)% put FixedLimits option to 'off' to plot the whole image
                uvmat('InputFileREFRESH_Callback',huvmat,[],hhuvmat); %file input with xml reading  in uvmat, show the image in phys coordinates
                %set(hObject,'BackgroundColor',[1 0 0]);% paint button back to red
                app.APPLYButton.BackgroundColor=[1 0 0];% paint button in yellow to indicate action
            end

            delete(hset_slice)
        end

        % Value changed function: replicateCheckBox
        function replicateCheckBoxValueChanged(app, event)
            if app.replicateCheckBox.Value   %open the GUI browse_data
                % look for the GUI uvmat and check for an image as input
                huvmat=findobj(allchild(0),'Name','uvmat');
                hhuvmat=guidata(huvmat);%handles of elements in the GUI uvmat
                RootPath=get(hhuvmat.RootPath,'String');
                SubDir=get(hhuvmat.SubDir,'String');
                browse_data(fullfile(RootPath,SubDir))
            else
                hbrowse=findobj(allchild(0),'Tag','browse_data');
                if ~isempty(hbrowse)
                    delete(hbrowse)
                end
            end
        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.Position = [100 100 640 480];
            app.UIFigure.Name = 'MATLAB App';

            % Create lastZEditFieldLabel
            app.lastZEditFieldLabel = uilabel(app.UIFigure);
            app.lastZEditFieldLabel.BackgroundColor = [1 1 1];
            app.lastZEditFieldLabel.HorizontalAlignment = 'right';
            app.lastZEditFieldLabel.Position = [65 384 35 22];
            app.lastZEditFieldLabel.Text = 'last Z';

            % Create lastZEditField
            app.lastZEditField = uieditfield(app.UIFigure, 'numeric');
            app.lastZEditField.Position = [115 384 100 22];

            % Create firstZEditFieldLabel
            app.firstZEditFieldLabel = uilabel(app.UIFigure);
            app.firstZEditFieldLabel.BackgroundColor = [1 1 1];
            app.firstZEditFieldLabel.HorizontalAlignment = 'right';
            app.firstZEditFieldLabel.Position = [66 411 35 22];
            app.firstZEditFieldLabel.Text = 'first Z';

            % Create firstZEditField
            app.firstZEditField = uieditfield(app.UIFigure, 'numeric');
            app.firstZEditField.Position = [116 411 100 22];
            app.firstZEditField.Value = 53;

            % Create surfaceEditFieldLabel
            app.surfaceEditFieldLabel = uilabel(app.UIFigure);
            app.surfaceEditFieldLabel.HorizontalAlignment = 'right';
            app.surfaceEditFieldLabel.Visible = 'off';
            app.surfaceEditFieldLabel.Position = [102 355 45 22];
            app.surfaceEditFieldLabel.Text = 'surface';

            % Create surfaceEditField
            app.surfaceEditField = uieditfield(app.UIFigure, 'numeric');
            app.surfaceEditField.Visible = 'off';
            app.surfaceEditField.Position = [162 355 100 22];

            % Create refractionCheckBox
            app.refractionCheckBox = uicheckbox(app.UIFigure);
            app.refractionCheckBox.ValueChangedFcn = createCallbackFcn(app, @refractionCheckBoxValueChanged, true);
            app.refractionCheckBox.Text = 'refraction';
            app.refractionCheckBox.Position = [20 355 72 22];

            % Create indexEditFieldLabel
            app.indexEditFieldLabel = uilabel(app.UIFigure);
            app.indexEditFieldLabel.HorizontalAlignment = 'right';
            app.indexEditFieldLabel.Visible = 'off';
            app.indexEditFieldLabel.Position = [278 355 34 22];
            app.indexEditFieldLabel.Text = 'index';

            % Create indexEditField
            app.indexEditField = uieditfield(app.UIFigure, 'numeric');
            app.indexEditField.Visible = 'off';
            app.indexEditField.Position = [327 355 65 22];
            app.indexEditField.Value = 1.33;

            % Create NbSliceEditFieldLabel
            app.NbSliceEditFieldLabel = uilabel(app.UIFigure);
            app.NbSliceEditFieldLabel.HorizontalAlignment = 'right';
            app.NbSliceEditFieldLabel.Position = [33 438 47 22];
            app.NbSliceEditFieldLabel.Text = 'NbSlice';

            % Create NbSliceEditField
            app.NbSliceEditField = uieditfield(app.UIFigure, 'numeric');
            app.NbSliceEditField.Position = [95 438 65 22];
            app.NbSliceEditField.Value = 1;

            % Create volumescanCheckBox
            app.volumescanCheckBox = uicheckbox(app.UIFigure);
            app.volumescanCheckBox.Text = 'volume scan';
            app.volumescanCheckBox.Position = [172 437 89 22];

            % Create firstangleEditFieldLabel
            app.firstangleEditFieldLabel = uilabel(app.UIFigure);
            app.firstangleEditFieldLabel.HorizontalAlignment = 'right';
            app.firstangleEditFieldLabel.Position = [28 269 58 22];
            app.firstangleEditFieldLabel.Text = 'first angle';

            % Create firstangleEditField
            app.firstangleEditField = uieditfield(app.UIFigure, 'numeric');
            app.firstangleEditField.Position = [101 269 100 22];

            % Create lastangleEditFieldLabel
            app.lastangleEditFieldLabel = uilabel(app.UIFigure);
            app.lastangleEditFieldLabel.HorizontalAlignment = 'right';
            app.lastangleEditFieldLabel.Position = [29 242 57 22];
            app.lastangleEditFieldLabel.Text = 'last angle';

            % Create lastangleEditField
            app.lastangleEditField = uieditfield(app.UIFigure, 'numeric');
            app.lastangleEditField.Position = [101 242 100 22];

            % Create axispositionxEditFieldLabel
            app.axispositionxEditFieldLabel = uilabel(app.UIFigure);
            app.axispositionxEditFieldLabel.HorizontalAlignment = 'right';
            app.axispositionxEditFieldLabel.Position = [35 321 103 22];
            app.axispositionxEditFieldLabel.Text = 'axis position    x';

            % Create axispositionxEditField
            app.axispositionxEditField = uieditfield(app.UIFigure, 'numeric');
            app.axispositionxEditField.Position = [150 321 70 22];

            % Create yEditFieldLabel
            app.yEditFieldLabel = uilabel(app.UIFigure);
            app.yEditFieldLabel.HorizontalAlignment = 'right';
            app.yEditFieldLabel.Position = [251 321 25 22];
            app.yEditFieldLabel.Text = ' y';

            % Create yEditField
            app.yEditField = uieditfield(app.UIFigure, 'numeric');
            app.yEditField.Position = [282 321 68 22];

            % Create firstangleEditField_2Label
            app.firstangleEditField_2Label = uilabel(app.UIFigure);
            app.firstangleEditField_2Label.HorizontalAlignment = 'right';
            app.firstangleEditField_2Label.Position = [222 268 58 22];
            app.firstangleEditField_2Label.Text = 'first angle';

            % Create firstangleEditField_2
            app.firstangleEditField_2 = uieditfield(app.UIFigure, 'numeric');
            app.firstangleEditField_2.Position = [295 268 100 22];

            % Create lastangleEditField_2Label
            app.lastangleEditField_2Label = uilabel(app.UIFigure);
            app.lastangleEditField_2Label.HorizontalAlignment = 'right';
            app.lastangleEditField_2Label.Position = [223 241 57 22];
            app.lastangleEditField_2Label.Text = 'last angle';

            % Create lastangleEditField_2
            app.lastangleEditField_2 = uieditfield(app.UIFigure, 'numeric');
            app.lastangleEditField_2.Position = [295 241 100 22];

            % Create UITable
            app.UITable = uitable(app.UIFigure);
            app.UITable.ColumnName = {'Z'; 'tild x axis'; 'tild y axis'; 'Column 4'};
            app.UITable.RowName = {};
            app.UITable.SelectionType = 'column';
            app.UITable.Position = [91 92 332 123];

            % Create APPLYButton
            app.APPLYButton = uibutton(app.UIFigure, 'push');
            app.APPLYButton.ButtonPushedFcn = createCallbackFcn(app, @APPLYButtonPushed, true);
            app.APPLYButton.BackgroundColor = [1 0 0];
            app.APPLYButton.Position = [47 52 100 22];
            app.APPLYButton.Text = 'APPLY';

            % Create replicateCheckBox
            app.replicateCheckBox = uicheckbox(app.UIFigure);
            app.replicateCheckBox.ValueChangedFcn = createCallbackFcn(app, @replicateCheckBoxValueChanged, true);
            app.replicateCheckBox.Text = 'replicate';
            app.replicateCheckBox.Position = [166 53 67 22];

            % Create CancelButton
            app.CancelButton = uibutton(app.UIFigure, 'push');
            app.CancelButton.Position = [257 53 100 22];
            app.CancelButton.Text = 'Cancel';

            % Create unequalintervalsCheckBox
            app.unequalintervalsCheckBox = uicheckbox(app.UIFigure);
            app.unequalintervalsCheckBox.ValueChangedFcn = createCallbackFcn(app, @unequalintervalsCheckBoxValueChanged, true);
            app.unequalintervalsCheckBox.Text = 'unequal intervals';
            app.unequalintervalsCheckBox.Position = [27 214 113 22];

            % Create rotationaroundyaxisanglesindegreesLabel
            app.rotationaroundyaxisanglesindegreesLabel = uilabel(app.UIFigure);
            app.rotationaroundyaxisanglesindegreesLabel.Position = [228 293 238 22];
            app.rotationaroundyaxisanglesindegreesLabel.Text = 'rotation around y axis    (angles in degrees)';

            % Create rotationaroundxaxisLabel
            app.rotationaroundxaxisLabel = uilabel(app.UIFigure);
            app.rotationaroundxaxisLabel.Position = [35 293 120 22];
            app.rotationaroundxaxisLabel.Text = 'rotation around x axis';

            % 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 = set_slices

            runningApp = getRunningApp(app);

            % Check for running singleton app
            if isempty(runningApp)

                % Create UIFigure and components
                createComponents(app)

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

                % Focus the running singleton app
                figure(runningApp.UIFigure)

                app = runningApp;
            end

            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