classdef Extra_colors < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure               matlab.ui.Figure
        Panel                  matlab.ui.container.Panel
        BlackfromSlider        matlab.ui.control.Slider
        fromSlider_4Label      matlab.ui.control.Label
        BlacktoSlider          matlab.ui.control.Slider
        toSlider_4Label        matlab.ui.control.Label
        BlackLabel             matlab.ui.control.Label
        V3Label                matlab.ui.control.Label
        V2Label                matlab.ui.control.Label
        V1Label                matlab.ui.control.Label
        ResetButton            matlab.ui.control.Button
        V3fromSlider           matlab.ui.control.Slider
        fromSlider_3Label      matlab.ui.control.Label
        V3toSlider             matlab.ui.control.Slider
        toSlider_3Label        matlab.ui.control.Label
        V2fromSlider           matlab.ui.control.Slider
        fromSlider_2Label      matlab.ui.control.Label
        V2toSlider             matlab.ui.control.Slider
        toSlider_2Label        matlab.ui.control.Label
        V1fromSlider           matlab.ui.control.Slider
        fromSliderLabel        matlab.ui.control.Label
        V1toSlider             matlab.ui.control.Slider
        toSliderLabel          matlab.ui.control.Label
        ColorSpaceButtonGroup  matlab.ui.container.ButtonGroup
        HSVButton              matlab.ui.control.ToggleButton
        HSLButton              matlab.ui.control.ToggleButton
        CMYKButton             matlab.ui.control.ToggleButton
        RGBButton              matlab.ui.control.ToggleButton
        LoadButton             matlab.ui.control.Button
        MaskAxes               matlab.ui.control.UIAxes
        V3Axes                 matlab.ui.control.UIAxes
        V2Axes                 matlab.ui.control.UIAxes
        GrayAxes               matlab.ui.control.UIAxes
        V1Axes                 matlab.ui.control.UIAxes
        ImageAxes              matlab.ui.control.UIAxes
    end


    properties (Access = private)
        OriginalImage
        ImageRGB;
        GrayImage;
        ImageConverted;
        Mask;
        MaskAll;
        CMYKform;
        TransFunctions;
        Limits;
        Invert;

    end

    methods (Access = private)

        function results = DrawImage(app)
            imshow(app.ImageRGB.*app.Mask, Parent=app.ImageAxes);
            if app.ColorSpaceButtonGroup.SelectedObject == app.CMYKButton
                imshow(app.ImageConverted(:,:,1).*app.MaskAll(:,:,4), Parent=app.GrayAxes);
            else
                imshow(app.GrayImage.*app.Mask, Parent=app.GrayAxes);
            end
            imshow(app.Mask.*app.Mask, Parent=app.MaskAxes);
            imshow(app.ImageConverted(:,:,1).*app.MaskAll(:,:,1),Parent=app.V1Axes);
            imshow(app.ImageConverted(:,:,2).*app.MaskAll(:,:,2),Parent=app.V2Axes);
            imshow(app.ImageConverted(:,:,3).*app.MaskAll(:,:,3),Parent=app.V3Axes);
        end

        function results = CalculateLimits(app)
            app.Limits = [app.V1fromSlider.Value, app.V1toSlider.Value;app.V2fromSlider.Value, app.V2toSlider.Value;app.V3fromSlider.Value, app.V3toSlider.Value; app.BlackfromSlider.Value,app.BlacktoSlider.Value];
            app.Invert = [0,0,0,0];
            for i = 1:4
                if app.Limits(i,1)>=app.Limits(i,2)
                    app.Limits(i,:) = app.Limits(i,[2,1]);
                    app.Invert(i) = 1;
                else
                    app.Invert(i) = 0;
                end
            end
        end
        function results = CalculateMask(app,i)
            app.MaskAll(:,:,i) = (app.ImageConverted(:,:,i)>=app.Limits(i,1)) & (app.ImageConverted(:,:,i)<=app.Limits(i,2));
            if app.Invert(i)
                app.MaskAll(:,:,i) = ~app.MaskAll(:,:,i);
            end
            app.Mask = app.MaskAll(:,:,1) & app.MaskAll(:,:,2) & app.MaskAll(:,:,3) & app.MaskAll(:,:,4);

        end

        function results = rgb2hsl(app,im)
            results = rgb2hsv(im);
            results(:,:,3) = (max(im,[],3)+min(im,[],3))*.5;
        end
    end


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

        % Code that executes after component creation
        function startupFcn(app)
            app.Mask = 1;
            app.CMYKform = makecform('srgb2cmyk');
            app.TransFunctions = {@(im)im,@(im)applycform(im,app.CMYKform),@(im)app.rgb2hsl(im),@(im)rgb2hsv(im)};
        end

        % Button pushed function: LoadButton
        function LoadButtonPushed(app, event)
            try
            [file, path] = uigetimagefile;
            if ~isempty(file)
                app.ImageRGB = double(imread(file))/255;
                app.GrayImage = rgb2gray(app.ImageRGB);
                app.ImageConverted = app.ImageRGB;
                app.MaskAll = ones(size(app.GrayImage,1),size(app.GrayImage,2),4);
                app.CalculateLimits;
                for i=1:3
                    app.CalculateMask(i);
                end
                app.DrawImage;

                app.Panel.Visible = "on";
                app.ImageAxes.Visible = "on";
                app.GrayAxes.Visible = "on";
                app.MaskAxes.Visible = "on";
                app.V1Axes.Visible = "on";
                app.V2Axes.Visible = "on";
                app.V3Axes.Visible = "on";
            end
            catch e
                uialert(app.UIFigure, e.message, "Error while loading image",Interpreter="html");
            end
        end

        % Selection changed function: ColorSpaceButtonGroup
        function ColorSpaceButtonGroupSelectionChanged(app, event)
            selectedButton = app.ColorSpaceButtonGroup.SelectedObject;
            list = ["RGB","CMYK","HSL","HSV"];
            idx = find(list==selectedButton.Text);
            app.ImageConverted = app.TransFunctions{idx}(app.ImageRGB);
            if selectedButton == app.CMYKButton
                app.GrayAxes.Title.String = "Black";
                app.CalculateMask(4);
                app.BlackLabel.Visible = "on";
                app.BlackfromSlider.Visible = "on";
                app.BlacktoSlider.Visible = "on";
            else
                app.GrayAxes.Title.String = "Gray";
                app.MaskAll(:,:,4) = 1;
                app.BlackLabel.Visible = "off";
                app.BlackfromSlider.Visible = "off";
                app.BlacktoSlider.Visible = "off";
                app.BlackfromSlider.Value = 0;
                app.BlacktoSlider.Value= 1;
            end
            labels = ["Red", "Green", "Blue";"Cyan", "Magenta", "Yellow";"Hue", "Saturation", "Lightness";"Hue", "Saturation", "Value"];
            app.V1Label.Text = labels(idx,1);
            app.V2Label.Text = labels(idx,2);
            app.V3Label.Text = labels(idx,3);

            app.V1Axes.Title.String = labels(idx,1);
            app.V2Axes.Title.String = labels(idx,2);
            app.V3Axes.Title.String = labels(idx,3);
            for i = 1:3
                app.CalculateMask(i);
            end
            app.DrawImage;
        end

        % Value changed function: V1fromSlider, V1toSlider
        function V1fromSliderValueChanged(app, event)
            app.CalculateLimits;
            app.CalculateMask(1);
            app.DrawImage;
        end

        % Value changed function: V2fromSlider, V2toSlider
        function V2fromSliderValueChanged(app, event)
            app.CalculateLimits;
            app.CalculateMask(2);
            app.DrawImage;
        end

        % Value changed function: V3fromSlider, V3toSlider
        function V3fromSliderValueChanged(app, event)
            app.CalculateLimits;
            app.CalculateMask(3);
            app.DrawImage;
        end

        % Value changed function: BlackfromSlider, BlacktoSlider
        function BlackfromSliderValueChanged(app, event)
            app.CalculateLimits;
            app.CalculateMask(4);
            app.DrawImage;
        end

        % Button pushed function: ResetButton
        function ResetButtonPushed(app, event)
            app.BlackfromSlider.Value = 0;
            app.BlacktoSlider.Value= 1;
            app.V1fromSlider.Value = 0;
            app.V1toSlider.Value= 1;
            app.V2fromSlider.Value = 0;
            app.V2toSlider.Value= 1;
            app.V3fromSlider.Value = 0;
            app.V3toSlider.Value= 1;
            app.MaskAll = ones(size(app.GrayImage,1),size(app.GrayImage,2),4);
            app.Mask = 1;
            app.Limits = [0,1;0,1;0,1;0,1];
            app.Invert = [0,0,0,0];
            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 1798 737];
            app.UIFigure.Name = 'MATLAB App';

            % Create ImageAxes
            app.ImageAxes = uiaxes(app.UIFigure);
            title(app.ImageAxes, 'Image')
            app.ImageAxes.XTick = [];
            app.ImageAxes.YTick = [];
            app.ImageAxes.ZTick = [];
            app.ImageAxes.Visible = 'off';
            app.ImageAxes.Position = [3 378 480 360];

            % Create V1Axes
            app.V1Axes = uiaxes(app.UIFigure);
            title(app.V1Axes, 'Red')
            app.V1Axes.XTick = [];
            app.V1Axes.YTick = [];
            app.V1Axes.ZTick = [];
            app.V1Axes.Visible = 'off';
            app.V1Axes.Position = [3 18 480 360];

            % Create GrayAxes
            app.GrayAxes = uiaxes(app.UIFigure);
            title(app.GrayAxes, 'Gray')
            app.GrayAxes.XTick = [];
            app.GrayAxes.YTick = [];
            app.GrayAxes.ZTick = [];
            app.GrayAxes.Visible = 'off';
            app.GrayAxes.Position = [481 378 480 360];

            % Create V2Axes
            app.V2Axes = uiaxes(app.UIFigure);
            title(app.V2Axes, 'Green')
            app.V2Axes.XTick = [];
            app.V2Axes.YTick = [];
            app.V2Axes.ZTick = [];
            app.V2Axes.Visible = 'off';
            app.V2Axes.Position = [481 18 480 360];

            % Create V3Axes
            app.V3Axes = uiaxes(app.UIFigure);
            title(app.V3Axes, 'Blue')
            app.V3Axes.XTick = [];
            app.V3Axes.YTick = [];
            app.V3Axes.ZTick = [];
            app.V3Axes.Visible = 'off';
            app.V3Axes.Position = [960 18 480 360];

            % Create MaskAxes
            app.MaskAxes = uiaxes(app.UIFigure);
            title(app.MaskAxes, 'Mask')
            app.MaskAxes.XTick = [];
            app.MaskAxes.YTick = [];
            app.MaskAxes.ZTick = [];
            app.MaskAxes.Visible = 'off';
            app.MaskAxes.Position = [960 377 480 360];

            % Create LoadButton
            app.LoadButton = uibutton(app.UIFigure, 'push');
            app.LoadButton.ButtonPushedFcn = createCallbackFcn(app, @LoadButtonPushed, true);
            app.LoadButton.Position = [1450 693 100 23];
            app.LoadButton.Text = 'Load';

            % Create Panel
            app.Panel = uipanel(app.UIFigure);
            app.Panel.Visible = 'off';
            app.Panel.Position = [1450 208 339 477];

            % Create ColorSpaceButtonGroup
            app.ColorSpaceButtonGroup = uibuttongroup(app.Panel);
            app.ColorSpaceButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @ColorSpaceButtonGroupSelectionChanged, true);
            app.ColorSpaceButtonGroup.Title = 'Color Space';
            app.ColorSpaceButtonGroup.Position = [44 302 123 150];

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

            % Create CMYKButton
            app.CMYKButton = uitogglebutton(app.ColorSpaceButtonGroup);
            app.CMYKButton.Text = 'CMYK';
            app.CMYKButton.Position = [11 75 100 23];

            % Create HSLButton
            app.HSLButton = uitogglebutton(app.ColorSpaceButtonGroup);
            app.HSLButton.Text = 'HSL';
            app.HSLButton.Position = [11 54 100 23];

            % Create HSVButton
            app.HSVButton = uitogglebutton(app.ColorSpaceButtonGroup);
            app.HSVButton.Text = 'HSV';
            app.HSVButton.Position = [11 32 100 23];

            % Create toSliderLabel
            app.toSliderLabel = uilabel(app.Panel);
            app.toSliderLabel.HorizontalAlignment = 'right';
            app.toSliderLabel.Position = [130 238 25 22];
            app.toSliderLabel.Text = 'to';

            % Create V1toSlider
            app.V1toSlider = uislider(app.Panel);
            app.V1toSlider.Limits = [0 1];
            app.V1toSlider.MajorTicks = [];
            app.V1toSlider.ValueChangedFcn = createCallbackFcn(app, @V1fromSliderValueChanged, true);
            app.V1toSlider.Position = [174 247 150 3];
            app.V1toSlider.Value = 1;

            % Create fromSliderLabel
            app.fromSliderLabel = uilabel(app.Panel);
            app.fromSliderLabel.HorizontalAlignment = 'right';
            app.fromSliderLabel.Position = [125 260 29 22];
            app.fromSliderLabel.Text = 'from';

            % Create V1fromSlider
            app.V1fromSlider = uislider(app.Panel);
            app.V1fromSlider.Limits = [0 1];
            app.V1fromSlider.MajorTicks = [];
            app.V1fromSlider.ValueChangedFcn = createCallbackFcn(app, @V1fromSliderValueChanged, true);
            app.V1fromSlider.Position = [174 269 150 3];

            % Create toSlider_2Label
            app.toSlider_2Label = uilabel(app.Panel);
            app.toSlider_2Label.HorizontalAlignment = 'right';
            app.toSlider_2Label.Position = [130 176 25 22];
            app.toSlider_2Label.Text = 'to';

            % Create V2toSlider
            app.V2toSlider = uislider(app.Panel);
            app.V2toSlider.Limits = [0 1];
            app.V2toSlider.MajorTicks = [];
            app.V2toSlider.ValueChangedFcn = createCallbackFcn(app, @V2fromSliderValueChanged, true);
            app.V2toSlider.Position = [174 185 150 3];
            app.V2toSlider.Value = 1;

            % Create fromSlider_2Label
            app.fromSlider_2Label = uilabel(app.Panel);
            app.fromSlider_2Label.HorizontalAlignment = 'right';
            app.fromSlider_2Label.Position = [125 198 29 22];
            app.fromSlider_2Label.Text = 'from';

            % Create V2fromSlider
            app.V2fromSlider = uislider(app.Panel);
            app.V2fromSlider.Limits = [0 1];
            app.V2fromSlider.MajorTicks = [];
            app.V2fromSlider.ValueChangedFcn = createCallbackFcn(app, @V2fromSliderValueChanged, true);
            app.V2fromSlider.Position = [174 207 150 3];

            % Create toSlider_3Label
            app.toSlider_3Label = uilabel(app.Panel);
            app.toSlider_3Label.HorizontalAlignment = 'right';
            app.toSlider_3Label.Position = [128 125 25 22];
            app.toSlider_3Label.Text = 'to';

            % Create V3toSlider
            app.V3toSlider = uislider(app.Panel);
            app.V3toSlider.Limits = [0 1];
            app.V3toSlider.MajorTicks = [];
            app.V3toSlider.ValueChangedFcn = createCallbackFcn(app, @V3fromSliderValueChanged, true);
            app.V3toSlider.Position = [172 134 150 3];
            app.V3toSlider.Value = 1;

            % Create fromSlider_3Label
            app.fromSlider_3Label = uilabel(app.Panel);
            app.fromSlider_3Label.HorizontalAlignment = 'right';
            app.fromSlider_3Label.Position = [123 147 29 22];
            app.fromSlider_3Label.Text = 'from';

            % Create V3fromSlider
            app.V3fromSlider = uislider(app.Panel);
            app.V3fromSlider.Limits = [0 1];
            app.V3fromSlider.MajorTicks = [];
            app.V3fromSlider.ValueChangedFcn = createCallbackFcn(app, @V3fromSliderValueChanged, true);
            app.V3fromSlider.Position = [172 156 150 3];

            % Create ResetButton
            app.ResetButton = uibutton(app.Panel, 'push');
            app.ResetButton.ButtonPushedFcn = createCallbackFcn(app, @ResetButtonPushed, true);
            app.ResetButton.Position = [193 429 100 23];
            app.ResetButton.Text = 'Reset';

            % Create V1Label
            app.V1Label = uilabel(app.Panel);
            app.V1Label.Position = [33 251 67 22];
            app.V1Label.Text = 'Red';

            % Create V2Label
            app.V2Label = uilabel(app.Panel);
            app.V2Label.Position = [33 193 67 22];
            app.V2Label.Text = 'Green';

            % Create V3Label
            app.V3Label = uilabel(app.Panel);
            app.V3Label.Position = [33 137 67 22];
            app.V3Label.Text = 'Blue';

            % Create BlackLabel
            app.BlackLabel = uilabel(app.Panel);
            app.BlackLabel.Visible = 'off';
            app.BlackLabel.Position = [33 79 67 22];
            app.BlackLabel.Text = 'Black';

            % Create toSlider_4Label
            app.toSlider_4Label = uilabel(app.Panel);
            app.toSlider_4Label.HorizontalAlignment = 'right';
            app.toSlider_4Label.Visible = 'off';
            app.toSlider_4Label.Position = [130 73 25 22];
            app.toSlider_4Label.Text = 'to';

            % Create BlacktoSlider
            app.BlacktoSlider = uislider(app.Panel);
            app.BlacktoSlider.Limits = [0 1];
            app.BlacktoSlider.MajorTicks = [];
            app.BlacktoSlider.ValueChangedFcn = createCallbackFcn(app, @BlackfromSliderValueChanged, true);
            app.BlacktoSlider.Visible = 'off';
            app.BlacktoSlider.Position = [174 82 150 3];
            app.BlacktoSlider.Value = 1;

            % Create fromSlider_4Label
            app.fromSlider_4Label = uilabel(app.Panel);
            app.fromSlider_4Label.HorizontalAlignment = 'right';
            app.fromSlider_4Label.Visible = 'off';
            app.fromSlider_4Label.Position = [125 95 29 22];
            app.fromSlider_4Label.Text = 'from';

            % Create BlackfromSlider
            app.BlackfromSlider = uislider(app.Panel);
            app.BlackfromSlider.Limits = [0 1];
            app.BlackfromSlider.MajorTicks = [];
            app.BlackfromSlider.ValueChangedFcn = createCallbackFcn(app, @BlackfromSliderValueChanged, true);
            app.BlackfromSlider.Visible = 'off';
            app.BlackfromSlider.Position = [174 104 150 3];

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

            % 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