classdef lab_2_extra < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure             matlab.ui.Figure
        PalleteButtonGroup   matlab.ui.container.ButtonGroup
        GrayButton           matlab.ui.control.ToggleButton
        RGBButton            matlab.ui.control.ToggleButton
        PaddingButtonGroup   matlab.ui.container.ButtonGroup
        ZerosButton          matlab.ui.control.ToggleButton
        CircularButton       matlab.ui.control.ToggleButton
        ReplicateButton      matlab.ui.control.ToggleButton
        SymmetricButton      matlab.ui.control.ToggleButton
        FieldParamALabel     matlab.ui.control.Label
        FieldParamBLabel     matlab.ui.control.Label
        FilterParamAField    matlab.ui.control.Slider
        FilterParamBField    matlab.ui.control.Slider
        FilterDropDown       matlab.ui.control.DropDown
        FilterDropDownLabel  matlab.ui.control.Label
        LoadImageButton      matlab.ui.control.Button
        FilterImage          matlab.ui.control.UIAxes
        MainImage            matlab.ui.control.UIAxes
    end

    
    properties (Access = private)
        ImageRGB
        ImageGray
        ImageBinary
        CurrentImage
        ProcessedImage
        FilterType
        FilterPadding
        FilterImg
        FilterMinMax
    end
    
    methods (Access = private)
        
        function results = Filter(app)
            switch app.FilterType
                case 0
                    app.ProcessedImage = app.CurrentImage;
                    app.FilterImage.Children.Visible = 'off';
                case 1
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 2
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 3
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 4
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 5
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 6
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 7
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 8
                    app.PrepareFilter;
                    app.ProcessedImage = imfilter(app.CurrentImage, app.FilterImg,app.FilterPadding);
                case 9 
                    app.ProcessedImage = medfilt2(app.CurrentImage,[app.FilterParamAField.Value,app.FilterParamBField.Value],app.FilterPadding);
                    app.FilterImage.Children.Visible = 'off';
            end
            
        end
        
        function results = DrawImage(app)
            imshow(app.ProcessedImage,'Parent',app.MainImage);
            
        end
        
        function results = PrepareFilter(app)
           app.FilterImage.Children.Visible = 'on'
            switch app.FilterType
                case 1
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1},[app.FilterParamAField.Value,app.FilterParamBField.Value]);
                case 2
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1},app.FilterParamAField.Value);
                case 3
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1},app.FilterParamAField.Value, app.FilterParamBField.Value);
                case 4
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1},app.FilterParamAField.Value);
                case 5
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1},app.FilterParamAField.Value, app.FilterParamBField.Value);
                case 6
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1},app.FilterParamAField.Value, app.FilterParamBField.Value);
                case 7
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1});
                case 8
                    app.FilterImg = fspecial(app.FilterDropDown.Items{app.FilterType+1});
            end
            app.FilterMinMax = [min(app.FilterImg,[],'all'),max(app.FilterImg,[],'all')];
            if app.FilterMinMax(1)==app.FilterMinMax(2)
                app.FilterMinMax(2) = app.FilterMinMax(2)+1;
            end
            imshow(app.FilterImg,app.FilterMinMax,'Parent',app.FilterImage);
        end
    end
    

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

        % Code that executes after component creation
        function startupFcn(app)
            app.FilterType = 0;
            app.FilterParamAField.Visible = "off";
            app.FilterParamAField.Enable = "off";
            app.FilterParamBField.Visible = "off";
            app.FilterParamBField.Enable = "off";
            app.FieldParamALabel.Visible = "off";
            app.FieldParamBLabel.Visible = "off";
            app.ProcessedImage = zeros(60,60);
            app.FilterPadding = 0;
            app.FilterImg = zeros(20,20);
            imshow(app.FilterImg,Parent=app.FilterImage);
            app.FilterImage.Children.Visible = 'off';
            app.PaddingButtonGroup.Visible="off";
            app.DrawImage
            
        end

        % Button pushed function: LoadImageButton
        function LoadImageButtonPushed(app, event)
            [file, path] = uigetimagefile;
            if ~isempty(file)
            app.ImageRGB = double(imread(file))/255;
            app.ImageGray = rgb2gray(app.ImageRGB);
            app.CurrentImage = app.ImageRGB;
            
            app.ProcessedImage = app.CurrentImage;
            app.Filter;
            app.DrawImage;
            end
        end

        % Value changed function: FilterDropDown
        function FilterDropDownValueChanged(app, event)
            value = app.FilterDropDown.Value;
            app.FilterType = value;
            if value==9
                app.CurrentImage = app.ImageGray;
                app.PalleteButtonGroup.SelectedObject = app.GrayButton;
                app.RGBButton.Enable = "off";
                if app.PaddingButtonGroup ~= app.SymmetricButton
                    app.PaddingButtonGroup.SelectedObject = app.ZerosButton;
                    app.FilterPadding = "Zeros";
                end
                app.CircularButton.Enable = "off";
                app.ReplicateButton.Enable = "off";
            else
                app.RGBButton.Enable = "on";
                app.CircularButton.Enable = "on";
                app.ReplicateButton.Enable = "on";
                if app.PaddingButtonGroup.SelectedObject == app.ZerosButton
                    app.FilterPadding = 0;
                end
            end


            if value>0
            app.PaddingButtonGroup.Visible = "on";
            if value <9
                app.FilterImage.Children.Visible = 'on'
            else
                app.FilterImage.Children.Visible = 'off'
            end
            PA = {"on","on","on","on","on","on","off","off","on"};
            PB = {"on","off","on","off","on","on","off","off","on"};
            PALabel = {"Size - X", "Radius", "H-size", "Alpha","H-size","Length","","","Size - X"};
            PBLabel = {"Size - Y", "", "Sigma", "","Sigma","Theta","","", "Size - Y"};
            PALimits = {[1,30],[1,30],[1,30], [0,1],[1,30],[1,30],[0,1],[0,1], [1,30]};
            PBLimits = {[1,30],[0,1],[0.1,10], [0,1],[0.01,2],[0,180],[0,1],[0,1], [1,30]};
            PADefault = [3, 5, 3, .5, 3, 9, 1, 1,3];
            PBDefault = [3, 1, 1, 1, .5, 0, 1, 1,3];
            app.FilterParamAField.Visible = PA{value};
            app.FilterParamAField.Enable = PA{value};
            app.FilterParamBField.Visible = PB{value};
            app.FilterParamBField.Enable = PB{value};
            app.FieldParamALabel.Text = PALabel{value};
            app.FieldParamBLabel.Text = PBLabel{value};
            app.FilterParamAField.Limits = PALimits{value};
            app.FilterParamBField.Limits = PBLimits{value};
            app.FilterParamAField.Value = PADefault(value);
            app.FilterParamBField.Value = PBDefault(value);
            app.FieldParamALabel.Visible = PA{value};
            app.FieldParamBLabel.Visible = PB{value};
            else
            app.PaddingButtonGroup.Visible = "off";
            app.FilterImage.Children.Visible = 'off'
            app.FilterParamAField.Visible = "off";
            app.FilterParamAField.Enable = "off";
            app.FilterParamBField.Visible = "off";
            app.FilterParamBField.Enable = "off";
            app.FieldParamALabel.Visible = "off";
            app.FieldParamBLabel.Visible = "off";
            end
           
            app.Filter;
            app.DrawImage;
        end

        % Value changed function: FilterParamBField
        function FilterParamBFieldValueChanged2(app, event)
            value = app.FilterParamBField.Value;
            NeedInt = [true, false, false, false, false, false, false, false,true];
            if NeedInt(app.FilterDropDown.Value)
                app.FilterParamBField.Value = round(value);
            end

            app.Filter;
            app.DrawImage;
        end

        % Value changed function: FilterParamAField
        function FilterParamAFieldValueChanged2(app, event)
            value = app.FilterParamAField.Value;
            NeedInt = [true, true, true, false, true,true, false, false,true];
            if NeedInt(app.FilterDropDown.Value)
                app.FilterParamAField.Value = round(value);
            end
            app.Filter;
            app.DrawImage;
        end

        % Selection changed function: PaddingButtonGroup
        function PaddingButtonGroupSelectionChanged(app, event)
            selectedButton = app.PaddingButtonGroup.SelectedObject;
            if selectedButton == app.ZerosButton && app.FilterType<9;
                app.FilterPadding = 0;
            else
            app.FilterPadding = selectedButton.Text;
            end
            app.Filter;
            app.DrawImage;
        end

        % Selection changed function: PalleteButtonGroup
        function PalleteButtonGroupSelectionChanged(app, event)
            selectedButton = app.PalleteButtonGroup.SelectedObject;
            if selectedButton == app.RGBButton
                app.CurrentImage = app.ImageRGB;
            else
                app.CurrentImage = app.ImageGray;
            end
            app.Filter;
            app.DrawImage;
        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 1743 1114];
            app.UIFigure.Name = 'MATLAB App';

            % Create MainImage
            app.MainImage = uiaxes(app.UIFigure);
            app.MainImage.Position = [10 161 1373 941];

            % Create FilterImage
            app.FilterImage = uiaxes(app.UIFigure);
            app.FilterImage.Position = [1409 429 300 255];

            % Create LoadImageButton
            app.LoadImageButton = uibutton(app.UIFigure, 'push');
            app.LoadImageButton.ButtonPushedFcn = createCallbackFcn(app, @LoadImageButtonPushed, true);
            app.LoadImageButton.Position = [1490 1017 100 23];
            app.LoadImageButton.Text = 'Load Image';

            % Create FilterDropDownLabel
            app.FilterDropDownLabel = uilabel(app.UIFigure);
            app.FilterDropDownLabel.HorizontalAlignment = 'right';
            app.FilterDropDownLabel.Position = [1442 950 32 22];
            app.FilterDropDownLabel.Text = 'Filter';

            % Create FilterDropDown
            app.FilterDropDown = uidropdown(app.UIFigure);
            app.FilterDropDown.Items = {'none', 'average', 'disk', 'gaussian', 'laplacian', 'log', 'motion', 'prewitt', 'sobel', 'median'};
            app.FilterDropDown.ItemsData = [0 1 2 3 4 5 6 7 8 9];
            app.FilterDropDown.ValueChangedFcn = createCallbackFcn(app, @FilterDropDownValueChanged, true);
            app.FilterDropDown.Position = [1489 950 100 22];
            app.FilterDropDown.Value = 0;

            % Create FilterParamBField
            app.FilterParamBField = uislider(app.UIFigure);
            app.FilterParamBField.Limits = [-99 101];
            app.FilterParamBField.ValueChangedFcn = createCallbackFcn(app, @FilterParamBFieldValueChanged2, true);
            app.FilterParamBField.Position = [1518 860 150 3];
            app.FilterParamBField.Value = 1;

            % Create FilterParamAField
            app.FilterParamAField = uislider(app.UIFigure);
            app.FilterParamAField.Limits = [1 30];
            app.FilterParamAField.ValueChangedFcn = createCallbackFcn(app, @FilterParamAFieldValueChanged2, true);
            app.FilterParamAField.Position = [1518 930 150 3];
            app.FilterParamAField.Value = 1;

            % Create FieldParamBLabel
            app.FieldParamBLabel = uilabel(app.UIFigure);
            app.FieldParamBLabel.HorizontalAlignment = 'right';
            app.FieldParamBLabel.Position = [1442 850 67 22];
            app.FieldParamBLabel.Text = 'Slider';

            % Create FieldParamALabel
            app.FieldParamALabel = uilabel(app.UIFigure);
            app.FieldParamALabel.HorizontalAlignment = 'right';
            app.FieldParamALabel.Position = [1442 911 67 22];
            app.FieldParamALabel.Text = 'H-size';

            % Create PaddingButtonGroup
            app.PaddingButtonGroup = uibuttongroup(app.UIFigure);
            app.PaddingButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @PaddingButtonGroupSelectionChanged, true);
            app.PaddingButtonGroup.Title = 'Padding';
            app.PaddingButtonGroup.Position = [1589 688 123 125];

            % Create SymmetricButton
            app.SymmetricButton = uitogglebutton(app.PaddingButtonGroup);
            app.SymmetricButton.Text = 'Symmetric';
            app.SymmetricButton.Position = [12 50 100 23];

            % Create ReplicateButton
            app.ReplicateButton = uitogglebutton(app.PaddingButtonGroup);
            app.ReplicateButton.Text = 'Replicate';
            app.ReplicateButton.Position = [12 28 100 23];

            % Create CircularButton
            app.CircularButton = uitogglebutton(app.PaddingButtonGroup);
            app.CircularButton.Text = 'Circular';
            app.CircularButton.Position = [12 6 100 23];

            % Create ZerosButton
            app.ZerosButton = uitogglebutton(app.PaddingButtonGroup);
            app.ZerosButton.Text = 'Zeros';
            app.ZerosButton.Position = [12 72 100 23];
            app.ZerosButton.Value = true;

            % Create PalleteButtonGroup
            app.PalleteButtonGroup = uibuttongroup(app.UIFigure);
            app.PalleteButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @PalleteButtonGroupSelectionChanged, true);
            app.PalleteButtonGroup.Title = 'Pallete';
            app.PalleteButtonGroup.Position = [1467 688 123 125];

            % Create RGBButton
            app.RGBButton = uitogglebutton(app.PalleteButtonGroup);
            app.RGBButton.Text = 'RGB';
            app.RGBButton.Position = [11 71 100 23];
            app.RGBButton.Value = true;

            % Create GrayButton
            app.GrayButton = uitogglebutton(app.PalleteButtonGroup);
            app.GrayButton.Text = 'Gray';
            app.GrayButton.Position = [11 50 100 23];

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

            % 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