classdef cam_app < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                      matlab.ui.Figure
        BLabel                        matlab.ui.control.Label
        GLabel                        matlab.ui.control.Label
        RLabel                        matlab.ui.control.Label
        SaturatedpixelsEditField_3    matlab.ui.control.NumericEditField
        SaturatedpixelsEditField_2    matlab.ui.control.NumericEditField
        SaturatedpixelsEditField      matlab.ui.control.NumericEditField
        SaturatedpixelsLabel          matlab.ui.control.Label
        OutputfileEditField           matlab.ui.control.EditField
        OutputfileEditFieldLabel      matlab.ui.control.Label
        SelectsavelocationButton      matlab.ui.control.Button
        ReloadappButton               matlab.ui.control.Button
        EditField_4                   matlab.ui.control.NumericEditField
        HueSlider                     matlab.ui.control.Slider
        HueSliderLabel                matlab.ui.control.Label
        OutputpathEditField           matlab.ui.control.EditField
        OutputpathLabel               matlab.ui.control.Label
        SaveimageButton               matlab.ui.control.Button
        ResetvaluesButton             matlab.ui.control.Button
        EditField_3                   matlab.ui.control.NumericEditField
        WhitebalanceSlider            matlab.ui.control.Slider
        WhitebalanceSliderLabel       matlab.ui.control.Label
        EditField_2                   matlab.ui.control.NumericEditField
        EditField                     matlab.ui.control.NumericEditField
        OffLamp                       matlab.ui.control.Lamp
        OffLabel                      matlab.ui.control.Label
        ExposureSlider                matlab.ui.control.Slider
        ExposureSliderLabel           matlab.ui.control.Label
        GainSlider                    matlab.ui.control.Slider
        GainSliderLabel               matlab.ui.control.Label
        StartStopWebcampreviewButton  matlab.ui.control.Button
    end

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

        % Code that executes after component creation
        function startupFcn(app)
        clear all
        
        global prev start SavePath ImNum
               
        prev = 0;
        start = 0;
        SavePath = [];
        ImNum = 0;
               
        % Change the current folder to the folder of this m-file.
        userpath(fileparts(which(mfilename)));

        end

        % Button pushed function: StartStopWebcampreviewButton
        function StartStopWebcampreviewButtonPushed(app, event)
        global prev cam Gain im start Hfig
        
        try
            Gain = app.GainSlider.Value;
            Hfig = [];
            g = groot;
            
            if start == 0
%                 user = getenv('username');
%                 app.OutputpathEditField.Value = ['C:\Users\' user '\Desktop\image_1'];
                start = 1;
            end
            
            if prev == 0
                
                prev = 1;
                
                app.OffLamp.Color = 'green';
                app.OffLabel.Text = 'On';
                
                if isempty(g.Children) % find if figure window is open or close            
                    Hfig = figure('name','Camera preview','NumberTitle','off');
                end
                
                if ~isempty(cam)  
                    clear cam
                end 
                cam = webcam('HD USB Camera');

            else
                prev = 0;        
                
                app.OffLamp.Color = 'red';
                app.OffLabel.Text = 'Off';
            end
     
            cam.BacklightCompensation = 2;
            cam.WhiteBalanceMode = 'manual';
            cam.Sharpness = 0;       


            % set default values
            app.GainSlider.Value = 1;
            app.ExposureSlider.Value = -5;
            app.WhitebalanceSlider.Value = 4600;
            app.HueSlider.Value = 0;           
            app.EditField.Value = 1;
            app.EditField_2.Value = -5;
            app.EditField_3.Value = 4600;
            app.EditField_4.Value = 0;            
            Gain = app.EditField.Value;       

            if ~isempty(cam)  
                cam.Exposure     = round(app.EditField_2.Value);    
                cam.WhiteBalance = round(app.EditField_3.Value);  
                cam.Hue          = round(app.EditField_4.Value);  
            end  
   
            
            while prev
                
                G0 = Gain^3/110 + 1;
                
                im = snapshot(cam)*G0;
                
                app.SaturatedpixelsEditField.Value = round(sum(sum(im(:,:,1)==255))/(720*1280)*100,2);   
                app.SaturatedpixelsEditField_2.Value = round(sum(sum(im(:,:,2)==255))/(720*1280)*100,2);
                app.SaturatedpixelsEditField_3.Value = round(sum(sum(im(:,:,3)==255))/(720*1280)*100,2);   
                
                if ~isempty(g.Children) % find if figure window is open or close
                    imagesc(im)
                else
                    prev = 0;
                    try
                        clear Hfig
                        app.OffLamp.Color = 'red';
                        app.OffLabel.Text = 'Off';
                    catch
                    end
                end
            end
        catch
            disp("Problem with the camera.")
        end
        
        end

        % Close request function: UIFigure
        function UIFigureCloseRequest(app, event)
        global prev
        prev = 0;
        
        try
            close('Camera preview')              
        catch
        end
        
        delete(app)
            
        end

        % Value changing function: ExposureSlider
        function ExposureSliderValueChanging(app, event)
            
            global cam
            
            app.EditField_2.Value = app.ExposureSlider.Value;            
            
            if ~isempty(cam)  
                cam.Exposure = round(app.ExposureSlider.Value);                
            end
        
        end

        % Value changed function: ExposureSlider
        function ExposureSliderValueChanged(app, event)
            
            global cam
            
            app.EditField_2.Value = app.ExposureSlider.Value;
            
            if ~isempty(cam)  
                cam.Exposure = round(app.ExposureSlider.Value);              
            end
        end

        % Value changed function: GainSlider
        function GainSliderValueChanged(app, event)
            
            global Gain
            
            Gain = app.GainSlider.Value;
            app.EditField.Value = Gain;
        end

        % Value changing function: GainSlider
        function GainSliderValueChanging(app, event)
            
            global Gain
            
            Gain = app.GainSlider.Value;
            app.EditField.Value = Gain;
        end

        % Value changed function: EditField
        function EditFieldValueChanged(app, event)
            
            global Gain 
           
            Gain = app.EditField.Value;
            app.GainSlider.Value = Gain;
           
            
        end

        % Value changed function: WhitebalanceSlider
        function WhitebalanceSliderValueChanged(app, event)
            
            global cam
            
            app.EditField_3.Value = app.WhitebalanceSlider.Value;
            
            if ~isempty(cam)  
                cam.WhiteBalance = round(app.WhitebalanceSlider.Value);               
            end            
        end

        % Value changing function: WhitebalanceSlider
        function WhitebalanceSliderValueChanging(app, event)
            
            global cam
            
            app.EditField_3.Value = app.WhitebalanceSlider.Value;
            
            if ~isempty(cam)  
                cam.WhiteBalance = round(app.WhitebalanceSlider.Value);             
            end             
        end

        % Value changed function: EditField_3
        function EditField_3ValueChanged(app, event)
            
            global cam
            
            app.WhitebalanceSlider.Value = app.EditField_3.Value;
            
            if ~isempty(cam)  
                cam.WhiteBalance = round(app.EditField_3.Value);               
            end              
        end

        % Value changed function: EditField_2
        function EditField_2ValueChanged(app, event)
            
            global cam
            
            app.ExposureSlider.Value = app.EditField_2.Value;
            
            if ~isempty(cam)  
                cam.Exposure = round(app.EditField_2.Value);               
            end               
        end

        % Button pushed function: ResetvaluesButton
        function ResetvaluesButtonPushed(app, event)
            
            global cam Gain
        
            app.GainSlider.Value = 1;
            app.ExposureSlider.Value = -5;
            app.WhitebalanceSlider.Value = 4600;
            app.HueSlider.Value = 0;
            
            app.EditField.Value = 1;
            app.EditField_2.Value = -5;
            app.EditField_3.Value = 4600;
            app.EditField_4.Value = 0;
            
            Gain = app.EditField.Value;
            
            if ~isempty(cam)  
                cam.Exposure     = round(app.EditField_2.Value);    
                cam.WhiteBalance = round(app.EditField_3.Value);  
                cam.Hue          = round(app.EditField_4.Value);  
            end  
            
            
        end

        % Button pushed function: SaveimageButton
        function SaveimageButtonPushed(app, event)
            
        global im SavePath ImNum
        
        if isempty(SavePath)
            disp("Please select an output folder.")
        else
                 
            ImName = ['image_' num2str(ImNum) '.png'];
            
            while exist([SavePath '\' ImName])
                ImNum = ImNum + 1;
                ImName = ['image_' num2str(ImNum) '.png'];
            end
            
            try
                imwrite(im,[SavePath '\' ImName])
            catch
            end

            ImNum = ImNum + 1;
            ImName = ['image_' num2str(ImNum) '.png'];
            app.OutputfileEditField.Value = ImName;
        end

        
        
        end

        % Value changing function: HueSlider
        function HueSliderValueChanging(app, event)
            
            global cam
            
            app.EditField_4.Value = app.HueSlider.Value;
            
            if ~isempty(cam)  
                cam.Hue = round(app.HueSlider.Value);               
            end         
            
        end

        % Value changed function: EditField_4
        function EditField_4ValueChanged(app, event)
            
            global cam
            
            app.HueSlider.Value = app.EditField_4.Value;
            
            if ~isempty(cam)  
                cam.Hue = round(app.EditField_4.Value);               
            end   
        end

        % Value changed function: HueSlider
        function HueSliderValueChanged(app, event)
            
            global cam
            
            app.EditField_4.Value = app.HueSlider.Value;
            
            if ~isempty(cam)  
                cam.Hue = round(app.HueSlider.Value);               
            end    
        end

        % Button pushed function: ReloadappButton
        function ReloadappButtonPushed(app, event)
            
            global prev Gain Hfig cam
            
            prev = 0;
            Gain = 0;
            
            clear cam Hfig
            
            try
                close('Camera preview')              
            catch
            end
            
            delete(app)
            cam_app()
            
        end

        % Button pushed function: SelectsavelocationButton
        function SelectsavelocationButtonPushed(app, event)
            
            global SavePath ImNum
        
            SavePath = uigetdir();
            
            if SavePath == 0
                SavePath = [];
            else
                            
                app.OutputpathEditField.Value = SavePath;
                
                ImName = ['image_' num2str(ImNum) '.png'];
                
                if exist([SavePath '\' ImName])
                
                    while exist([SavePath '\' ImName])
                        ImNum = ImNum + 1;
                        ImName = ['image_' num2str(ImNum) '.png'];
                    end
                else
                    ImNum = 0;
                end
                    
                ImName = ['image_' num2str(ImNum) '.png'];
                
                app.OutputfileEditField.Value = ImName;
                    
            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 683 564];
            app.UIFigure.Name = 'UI Figure';
            app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @UIFigureCloseRequest, true);

            % Create StartStopWebcampreviewButton
            app.StartStopWebcampreviewButton = uibutton(app.UIFigure, 'push');
            app.StartStopWebcampreviewButton.ButtonPushedFcn = createCallbackFcn(app, @StartStopWebcampreviewButtonPushed, true);
            app.StartStopWebcampreviewButton.FontSize = 16;
            app.StartStopWebcampreviewButton.FontWeight = 'bold';
            app.StartStopWebcampreviewButton.Position = [249 477 228 26];
            app.StartStopWebcampreviewButton.Text = 'Start/Stop Webcam preview';

            % Create GainSliderLabel
            app.GainSliderLabel = uilabel(app.UIFigure);
            app.GainSliderLabel.HorizontalAlignment = 'right';
            app.GainSliderLabel.FontSize = 14;
            app.GainSliderLabel.FontWeight = 'bold';
            app.GainSliderLabel.Position = [72 364 37 22];
            app.GainSliderLabel.Text = 'Gain';

            % Create GainSlider
            app.GainSlider = uislider(app.UIFigure);
            app.GainSlider.Limits = [1 10];
            app.GainSlider.MajorTicks = [1 2 3 4 5 6 7 8 9 10];
            app.GainSlider.ValueChangedFcn = createCallbackFcn(app, @GainSliderValueChanged, true);
            app.GainSlider.ValueChangingFcn = createCallbackFcn(app, @GainSliderValueChanging, true);
            app.GainSlider.Position = [130 373 381 3];
            app.GainSlider.Value = 1;

            % Create ExposureSliderLabel
            app.ExposureSliderLabel = uilabel(app.UIFigure);
            app.ExposureSliderLabel.HorizontalAlignment = 'right';
            app.ExposureSliderLabel.FontSize = 14;
            app.ExposureSliderLabel.FontWeight = 'bold';
            app.ExposureSliderLabel.Position = [40 294 69 22];
            app.ExposureSliderLabel.Text = 'Exposure';

            % Create ExposureSlider
            app.ExposureSlider = uislider(app.UIFigure);
            app.ExposureSlider.Limits = [-13 -1];
            app.ExposureSlider.MajorTicks = [-13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1];
            app.ExposureSlider.ValueChangedFcn = createCallbackFcn(app, @ExposureSliderValueChanged, true);
            app.ExposureSlider.ValueChangingFcn = createCallbackFcn(app, @ExposureSliderValueChanging, true);
            app.ExposureSlider.MinorTicks = [];
            app.ExposureSlider.Position = [130 303 389 3];
            app.ExposureSlider.Value = -5;

            % Create OffLabel
            app.OffLabel = uilabel(app.UIFigure);
            app.OffLabel.HorizontalAlignment = 'right';
            app.OffLabel.FontSize = 16;
            app.OffLabel.Position = [490 480 27 22];
            app.OffLabel.Text = 'Off';

            % Create OffLamp
            app.OffLamp = uilamp(app.UIFigure);
            app.OffLamp.Position = [532 480 20 20];
            app.OffLamp.Color = [1 0 0];

            % Create EditField
            app.EditField = uieditfield(app.UIFigure, 'numeric');
            app.EditField.Limits = [1 10];
            app.EditField.ValueDisplayFormat = '%2.1f';
            app.EditField.ValueChangedFcn = createCallbackFcn(app, @EditFieldValueChanged, true);
            app.EditField.HorizontalAlignment = 'center';
            app.EditField.FontSize = 14;
            app.EditField.Position = [544 361 98 22];
            app.EditField.Value = 1;

            % Create EditField_2
            app.EditField_2 = uieditfield(app.UIFigure, 'numeric');
            app.EditField_2.Limits = [-13 -1];
            app.EditField_2.RoundFractionalValues = 'on';
            app.EditField_2.ValueDisplayFormat = '%11.0f';
            app.EditField_2.ValueChangedFcn = createCallbackFcn(app, @EditField_2ValueChanged, true);
            app.EditField_2.HorizontalAlignment = 'center';
            app.EditField_2.FontSize = 14;
            app.EditField_2.Position = [544 291 98 22];
            app.EditField_2.Value = -5;

            % Create WhitebalanceSliderLabel
            app.WhitebalanceSliderLabel = uilabel(app.UIFigure);
            app.WhitebalanceSliderLabel.HorizontalAlignment = 'right';
            app.WhitebalanceSliderLabel.FontSize = 14;
            app.WhitebalanceSliderLabel.FontWeight = 'bold';
            app.WhitebalanceSliderLabel.Position = [9 224 100 22];
            app.WhitebalanceSliderLabel.Text = 'White balance';

            % Create WhitebalanceSlider
            app.WhitebalanceSlider = uislider(app.UIFigure);
            app.WhitebalanceSlider.Limits = [2800 6500];
            app.WhitebalanceSlider.ValueChangedFcn = createCallbackFcn(app, @WhitebalanceSliderValueChanged, true);
            app.WhitebalanceSlider.ValueChangingFcn = createCallbackFcn(app, @WhitebalanceSliderValueChanging, true);
            app.WhitebalanceSlider.Position = [130 233 389 3];
            app.WhitebalanceSlider.Value = 4600;

            % Create EditField_3
            app.EditField_3 = uieditfield(app.UIFigure, 'numeric');
            app.EditField_3.Limits = [2800 6500];
            app.EditField_3.ValueDisplayFormat = '%11.0f';
            app.EditField_3.ValueChangedFcn = createCallbackFcn(app, @EditField_3ValueChanged, true);
            app.EditField_3.HorizontalAlignment = 'center';
            app.EditField_3.FontSize = 14;
            app.EditField_3.Position = [544 221 98 22];
            app.EditField_3.Value = 4600;

            % Create ResetvaluesButton
            app.ResetvaluesButton = uibutton(app.UIFigure, 'push');
            app.ResetvaluesButton.ButtonPushedFcn = createCallbackFcn(app, @ResetvaluesButtonPushed, true);
            app.ResetvaluesButton.FontSize = 14;
            app.ResetvaluesButton.Position = [542 403 100 40];
            app.ResetvaluesButton.Text = {'Reset'; 'values'};

            % Create SaveimageButton
            app.SaveimageButton = uibutton(app.UIFigure, 'push');
            app.SaveimageButton.ButtonPushedFcn = createCallbackFcn(app, @SaveimageButtonPushed, true);
            app.SaveimageButton.FontSize = 14;
            app.SaveimageButton.FontWeight = 'bold';
            app.SaveimageButton.Position = [41 19 100 24];
            app.SaveimageButton.Text = 'Save image';

            % Create OutputpathLabel
            app.OutputpathLabel = uilabel(app.UIFigure);
            app.OutputpathLabel.HorizontalAlignment = 'right';
            app.OutputpathLabel.FontSize = 14;
            app.OutputpathLabel.Position = [179 54 83 22];
            app.OutputpathLabel.Text = 'Output path:';

            % Create OutputpathEditField
            app.OutputpathEditField = uieditfield(app.UIFigure, 'text');
            app.OutputpathEditField.Editable = 'off';
            app.OutputpathEditField.FontSize = 14;
            app.OutputpathEditField.Position = [277 54 393 22];

            % Create HueSliderLabel
            app.HueSliderLabel = uilabel(app.UIFigure);
            app.HueSliderLabel.HorizontalAlignment = 'right';
            app.HueSliderLabel.FontSize = 14;
            app.HueSliderLabel.FontWeight = 'bold';
            app.HueSliderLabel.Position = [77 151 32 22];
            app.HueSliderLabel.Text = 'Hue';

            % Create HueSlider
            app.HueSlider = uislider(app.UIFigure);
            app.HueSlider.Limits = [-40 40];
            app.HueSlider.ValueChangedFcn = createCallbackFcn(app, @HueSliderValueChanged, true);
            app.HueSlider.ValueChangingFcn = createCallbackFcn(app, @HueSliderValueChanging, true);
            app.HueSlider.Position = [130 160 389 3];

            % Create EditField_4
            app.EditField_4 = uieditfield(app.UIFigure, 'numeric');
            app.EditField_4.Limits = [-40 40];
            app.EditField_4.ValueDisplayFormat = '%11.1f';
            app.EditField_4.ValueChangedFcn = createCallbackFcn(app, @EditField_4ValueChanged, true);
            app.EditField_4.HorizontalAlignment = 'center';
            app.EditField_4.FontSize = 14;
            app.EditField_4.Position = [544 148 98 22];

            % Create ReloadappButton
            app.ReloadappButton = uibutton(app.UIFigure, 'push');
            app.ReloadappButton.ButtonPushedFcn = createCallbackFcn(app, @ReloadappButtonPushed, true);
            app.ReloadappButton.FontSize = 16;
            app.ReloadappButton.FontWeight = 'bold';
            app.ReloadappButton.Position = [86 476 106 26];
            app.ReloadappButton.Text = 'Reload app.';

            % Create SelectsavelocationButton
            app.SelectsavelocationButton = uibutton(app.UIFigure, 'push');
            app.SelectsavelocationButton.ButtonPushedFcn = createCallbackFcn(app, @SelectsavelocationButtonPushed, true);
            app.SelectsavelocationButton.FontSize = 14;
            app.SelectsavelocationButton.FontWeight = 'bold';
            app.SelectsavelocationButton.Position = [19 53 149 24];
            app.SelectsavelocationButton.Text = 'Select save location';

            % Create OutputfileEditFieldLabel
            app.OutputfileEditFieldLabel = uilabel(app.UIFigure);
            app.OutputfileEditFieldLabel.FontSize = 14;
            app.OutputfileEditFieldLabel.Position = [186 20 73 22];
            app.OutputfileEditFieldLabel.Text = 'Output file:';

            % Create OutputfileEditField
            app.OutputfileEditField = uieditfield(app.UIFigure, 'text');
            app.OutputfileEditField.Editable = 'off';
            app.OutputfileEditField.FontSize = 14;
            app.OutputfileEditField.Position = [277 20 393 22];

            % Create SaturatedpixelsLabel
            app.SaturatedpixelsLabel = uilabel(app.UIFigure);
            app.SaturatedpixelsLabel.HorizontalAlignment = 'right';
            app.SaturatedpixelsLabel.Position = [145 409 114 22];
            app.SaturatedpixelsLabel.Text = 'Saturated pixels (%)';

            % Create SaturatedpixelsEditField
            app.SaturatedpixelsEditField = uieditfield(app.UIFigure, 'numeric');
            app.SaturatedpixelsEditField.HorizontalAlignment = 'center';
            app.SaturatedpixelsEditField.Position = [276 409 45 22];

            % Create SaturatedpixelsEditField_2
            app.SaturatedpixelsEditField_2 = uieditfield(app.UIFigure, 'numeric');
            app.SaturatedpixelsEditField_2.HorizontalAlignment = 'center';
            app.SaturatedpixelsEditField_2.Position = [341 409 44 22];

            % Create SaturatedpixelsEditField_3
            app.SaturatedpixelsEditField_3 = uieditfield(app.UIFigure, 'numeric');
            app.SaturatedpixelsEditField_3.HorizontalAlignment = 'center';
            app.SaturatedpixelsEditField_3.Position = [406 409 44 22];

            % Create RLabel
            app.RLabel = uilabel(app.UIFigure);
            app.RLabel.HorizontalAlignment = 'center';
            app.RLabel.Position = [289 437 17 22];
            app.RLabel.Text = 'R';

            % Create GLabel
            app.GLabel = uilabel(app.UIFigure);
            app.GLabel.HorizontalAlignment = 'center';
            app.GLabel.Position = [351 437 25 22];
            app.GLabel.Text = 'G';

            % Create BLabel
            app.BLabel = uilabel(app.UIFigure);
            app.BLabel.HorizontalAlignment = 'center';
            app.BLabel.Position = [416 437 25 22];
            app.BLabel.Text = 'B';

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

            % 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