classdef ImageHistogramsAppExample < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure               matlab.ui.Figure
        ImageAxes              matlab.ui.control.UIAxes
        PredefinedImagesLabel  matlab.ui.control.Label
        LoadButton             matlab.ui.control.Button
        OrangePtsButton
        Image
        BWImage
        GrayImage
        ImRead
        ImCropped
        DeleteOrangePtsBtn
        Centers
        Radii
        NextButt
        FirstText               %nalezeni bodu na ramu
        SecText                 %odstraneni chybnych bodu
        ThirdText               %Nalezeni zbyvajiciho bodu
        FourthText              %Preprocessing
        FifthText
        SixthText
        SeventhText
        FindMissPtButt         
        ClickOnImAvailableToFindOrange % 1 Pokud se má reagovat na kliknutí na obrázek pro nalezení oranžového bodu, 0 nic
        ClickOnImAvailableToFindWrongTop
        ClickOnImAvailableToAddNewTop
        BWBtn
        editIntens
        EditFieldLabel
        EditField
        CropButt
        FindTopsBtn
        LabelTopBtn
        DeleteWrongTopsBtn
        Tops
        PlotTops
        WrongTops
        PlotWrongTops
        TopToDelete
        DeleteTop
        AddTopBtn
        FileNameLabel
        FileName
        ExportBtn
        NameOfProfile
        
    end
   
    methods (Access = private)
        
         function updateimage(app,imagefile)
                try
                    app.ImRead = imread(imagefile);
                    app.Image = imshow(app.ImRead, 'Parent', app.ImageAxes);  %image creation
                    app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);   

                catch ME
                    % If problem reading image, display error message
                    uialert(app.UIFigure, ME.message, 'Image Error');
                    return;
                end                
        end
    end
    

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

        % Code that executes after component creation
        function startupFcn(app)
            % Configure image axes
           
            app.ImageAxes.Visible = 'off';
            app.ImageAxes.Colormap = gray(256);
            axis(app.ImageAxes, 'image');
        end

      
        % Button pushed function: LoadButton
        function LoadButtonPushed(app, event)
               
            % Display uigetfile dialog
            filterspec = {'*.jpg;*.tif;*.png;*.gif','All Image Files'};
            [f, p] = uigetfile(filterspec,'MultiSelect','on');
            
            % Make sure user didn't cancel uigetfile dialog
            if (ischar(p))
               fname = [p f];
               updateimage(app, fname);
            end
        end
        
         function OrangeButtonPushed(app, event)
           [app.Centers, app.Image.CData, app.Radii] = findCircles(app.Image.CData);
           app.Image = imshow(app.Image.CData,'Parent',app.ImageAxes);
           app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);  
           appviscircles(app.ImageAxes,app.Centers,app.Radii)
         end
         
         function DeleteOrangeBtnPushed(app, event)
            [app.Centers,app.Radii] = deleteOrange(app.Centers,app.Radii,app.Image.CData,app.ImageAxes);
            app.Image = imshow(app.Image.CData,'Parent',app.ImageAxes);
            appviscircles(app.ImageAxes,app.Centers,app.Radii,'EdgeColor','b');
            app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);  
         end
         
         function NextButtPressed(app,event)
             [app.Centers,app.Radii] = nextOrange(app.Centers,app.Radii,app.Image.CData,app.ImageAxes);
             app.Image = imshow(app.Image.CData,'Parent',app.ImageAxes);
             appviscircles(app.ImageAxes, app.Centers(1,:),app.Radii(1),'EdgeColor','r');
             appviscircles(app.ImageAxes, app.Centers(2:length(app.Centers),:),app.Radii(2:length(app.Centers)),'EdgeColor','b');
             app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);  

         end

         function ImageButtonDownCallback(app, source, eventargs)
             if app.ClickOnImAvailableToFindOrange == 1
                 temp = app.ImageAxes.CurrentPoint; % Returns 2x3 array of points
                 loc = [temp(1,1) temp(1,2)]; % Gets the (x,y) coordinates
                 [app.Centers,app.Radii] = nalezeniZbyvajicihoBoduGUI(app.Centers, app.Radii,app.Image.CData, loc(1),loc(2));
                 app.Image = imshow(app.Image.CData,'Parent',app.ImageAxes);
                  app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);  
                 appviscircles(app.ImageAxes,app.Centers,app.Radii)
                 app.ClickOnImAvailableToFindOrange = 0;
                 app.UIFigure.Pointer = 'arrow';   
             end
             if app.ClickOnImAvailableToAddNewTop == 1
                 temp = app.ImageAxes.CurrentPoint;
                 loc = [temp(1,1) temp(1,2)];
                 app.Tops(end+1,1) = loc(2);
                 app.Tops(end,2) = loc(1);
                 app.Tops = sortrows(app.Tops,2);
                 app.PlotTops.XData = app.Tops(:,2);
                 app.PlotTops.YData = app.Tops(:,1);
                 app.UIFigure.Pointer = 'arrow';
                 app.ClickOnImAvailableToAddNewTop = 0;
             end

             
             
         end
         
         function FindMissPtButtPressed(app,event)
             app.UIFigure.Pointer = 'crosshair';
             app.ClickOnImAvailableToFindOrange = 1;
         end
         
         function CropButtPressed(app,event)
             app.ImCropped = CropImGUI(app.Image.CData, app.Centers);
             app.Image = imshow(app.ImCropped,'Parent',app.ImageAxes);
         end
         
         function BWBtnPressed(app,event)
            app.UIFigure.Pointer = 'watch';
            app.GrayImage = rgb2gray(app.Image.CData);
             app.BWImage = PreprocessingGUI(app.GrayImage);
             app.Image = imshow(app.BWImage,'Parent',app.ImageAxes);
             app.UIFigure.Pointer = 'arrow';
         end
         
         function textChanged(app,txt)
             app.UIFigure.Pointer = 'watch';
             Intensity  = str2double(txt.Value);
             app.BWImage = PreprocessingGUI(app.GrayImage,Intensity);
             app.Image = imshow(app.BWImage,'Parent',app.ImageAxes);
             app.UIFigure.Pointer = 'arrow';
             
         end
         
         function FindTopsBtnPressed(app,event)
             [startingPoint, MaxNumOfStcks] = whereToStart(app.BWImage);
              app.Tops = findTops(app.BWImage, startingPoint, MaxNumOfStcks);
              app.WrongTops = findWrongTopsAutoGUI(app.Tops);
              app.Image = imshow(app.ImCropped,'Parent',app.ImageAxes);
              app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);
              hold(app.ImageAxes, 'on');
             app.PlotTops = plot(app.ImageAxes,app.Tops(:,2),app.Tops(:,1),'b+', 'MarkerSize', 10, 'LineWidth', 2);
             if numel(app.WrongTops)>=2
                app.PlotWrongTops = plot(app.ImageAxes, app.WrongTops(:,2), app.WrongTops(:,1),'r+', 'MarkerSize', 10, 'LineWidth', 2);
             end
             app.PlotTops.ButtonDownFcn = @(txt,event)PlotTopsButtonDownCallback(app,event); 
         end
         
         function DeleteWrongTopsBtnPressed(app,event)
            YTops = app.Tops(:,1);
            XTops = app.Tops(:,2);
            app.Tops = [];
            for i = 1:length(app.WrongTops)
                XTops(XTops == app.WrongTops(i,2)) = [];
                YTops(YTops == app.WrongTops(i,1)) = [];

                app.PlotTops.YData(app.PlotTops.YData == app.WrongTops(i,1)) = [];
                app.PlotTops.XData(app.PlotTops.XData == app.WrongTops(i,2)) = [];
                if numel(app.WrongTops) == 2 
                    break;
                end
            end
            
            app.Tops(:,2) = XTops;
            app.Tops(:,1) = YTops;
             app.WrongTops(:) = [];
             app.PlotWrongTops.XData = [];
             app.PlotWrongTops.YData = [];
             
         end
         
         function LabelTopBtnPressed(app,event)
             app.UIFigure.Pointer = 'crosshair';
            % app.ClickOnImAvailableToFindWrongTop = 1;
 
         end
         
         function PlotTopsButtonDownCallback(app,event)
            theTop = [event.IntersectionPoint(1), event.IntersectionPoint(2)]; 
            app.PlotTops.XData(app.PlotTops.XData == theTop(1)) = [];
            app.PlotTops.YData(app.PlotTops.YData == theTop(2)) = [];
            app.TopToDelete = plot(app.ImageAxes,theTop(:,1),theTop(:,2),'r+', 'MarkerSize', 10, 'LineWidth', 2);
            app.UIFigure.Pointer = 'arrow';
         end
         
         function DeleteTopBtnPressed(app,event)
            XTops = app.Tops(:,1);
            YTops = app.Tops(:,2);
            app.Tops = [];
            XTops(XTops == app.TopToDelete.YData) = [];
            YTops(YTops == app.TopToDelete.XData) = [];
            app.Tops(:,1) = XTops;
            app.Tops(:,2) = YTops;
            app.TopToDelete.XData = [];
            app.TopToDelete.YData = [];
 
         end
         
         function AddTopBtnPressed(app,event)
             app.UIFigure.Pointer = 'crosshair';
             app.ClickOnImAvailableToAddNewTop = 1;
             
         end
         
         function  fileNameChanged(app,txt)
             app.NameOfProfile = txt.Value;
             
         end
         
         function ExportBtnPressed(app,event)
             app.Tops(:,1) = 1000 - app.Tops(:,1);
             writedxfline(app.NameOfProfile,app.Tops(:,2), app.Tops(:,1), zeros(length(app.Tops),1));
         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.AutoResizeChildren = 'off';
           % app.UIFigure.Units = ''
            app.UIFigure.Position = [100 50 1200 680];
            app.UIFigure.Name = 'Image Histograms';
            app.UIFigure.Resize = 'off';
            
            % Create ImageAxes
            app.ImageAxes = uiaxes(app.UIFigure);
            app.ImageAxes.XTick = [];
            app.ImageAxes.XTickLabel = {'[ ]'};
            app.ImageAxes.YTick = [];
            app.ImageAxes.Position = [43 181 557 505];
            
            
           app.ImRead = imread('P1120460.JPG');
           app.Image = imshow(app.ImRead,'Parent', app.ImageAxes);
           app.Image.ButtonDownFcn = @(txt,event)ImageButtonDownCallback(app,event);  

            % Create LoadButton
            app.LoadButton = uibutton(app.UIFigure, 'push');
            app.LoadButton.ButtonPushedFcn = createCallbackFcn(app, @LoadButtonPushed, true);
            app.LoadButton.Position = [109 80 225 22];
            app.LoadButton.Text = 'Load Custom Image';
            
            %PushButton
             app.OrangePtsButton = uibutton(app.UIFigure,'Text','Find Orange Poits','Position',[600 570 200 30], ...
            'ButtonPushedFcn',{@(btn,event) OrangeButtonPushed(app,event)});
        
            app.DeleteOrangePtsBtn = uibutton(app.UIFigure,'Text','Delete','Position',[600 490 80 30], ...
            'ButtonPushedFcn',{ @(btn,event) DeleteOrangeBtnPushed(app,event)});
        
            app.NextButt = uibutton(app.UIFigure,'Text','Next','Position',[700 490 80 30], ...
            'ButtonPushedFcn',{@(btn,event) NextButtPressed(app,event)});
        
            app.CropButt = uibutton(app.UIFigure,'Text','Crop','Position',[800 410 80 30], ...
            'ButtonPushedFcn',{@(btn,event) CropButtPressed(app,event)});
        
            app.FindTopsBtn = uibutton(app.UIFigure,'Text','Nalézt vrcholy','Position',[600 270 120 30], ...
            'ButtonPushedFcn',{@(btn,event) FindTopsBtnPressed(app,event)});
        
            app.DeleteWrongTopsBtn = uibutton(app.UIFigure,'Text','Odstranit chybné vrcholy','Position',[740 270 200 30], ...
            'ButtonPushedFcn',{@(btn,event) DeleteWrongTopsBtnPressed(app,event)});
 
             app.FindMissPtButt = uibutton(app.UIFigure,'Text','Označit bod v obrázku','Position',[600 410 180 30], ...
            'ButtonPushedFcn',{@(btn,event) FindMissPtButtPressed(app,event)});
        
            app.BWBtn = uibutton(app.UIFigure,'Text','Binární obraz','Position',[600 330 100 30], ...
            'ButtonPushedFcn',{@(btn,event) BWBtnPressed(app,event)});
            
            app.EditFieldLabel = uilabel(app.UIFigure);
            app.EditFieldLabel.HorizontalAlignment = 'right';
            app.EditFieldLabel.Position = [700 340 100 22];
            app.EditFieldLabel.Text = 'Edit Intensity';

            % Create EditField
            app.EditField = uieditfield(app.UIFigure, 'text');
            app.EditField.Position = [800 340 100 22];
            app.EditField.ValueChangedFcn = @(txt,event) textChanged(app,event);
            
            app.FirstText = uilabel(app.UIFigure);
            app.FirstText.HorizontalAlignment = 'left';
            app.FirstText.Position = [600 610 250 20];
            app.FirstText.Text = '1. Nalezení oranžových bodů na rámu';
            
            app.SecText = uilabel(app.UIFigure);
            app.SecText.HorizontalAlignment = 'left';
            app.SecText.Position = [600 530 250 20];
            app.SecText.Text = '2. Odstranění chybných bodů';
            
            app.ThirdText = uilabel(app.UIFigure);
            app.ThirdText.HorizontalAlignment = 'left';
            app.ThirdText.Position = [600 450 250 20];
            app.ThirdText.Text = '3. Nalezení zbývajících oranžových bodů';
            
            app.FourthText = uilabel(app.UIFigure);
            app.FourthText.HorizontalAlignment = 'left';
            app.FourthText.Position = [600 370 250 20];
            app.FourthText.Text = '4. Preprocessing';
            
            app.FifthText = uilabel(app.UIFigure);
            app.FifthText.HorizontalAlignment = 'left';
            app.FifthText.Position = [600 300 200 22];
            app.FifthText.Text = '5. Hledaní vrcholů kolíků';
            
            app.SixthText = uilabel(app.UIFigure);
            app.SixthText.HorizontalAlignment = 'left';
            app.SixthText.Position = [600 250 200 22];
            app.SixthText.Text = '6. Odstranění chybných vrcholů';
            
            app.LabelTopBtn = uibutton(app.UIFigure,'Text','Označit vrchol','Position',[600 210 150 30], ...
            'ButtonPushedFcn',{@(btn,event) LabelTopBtnPressed(app,event)});
        
            app.DeleteTop = uibutton(app.UIFigure,'Text','Odstranit','Position',[770 210 90 30], ...
            'ButtonPushedFcn',{@(btn,event)DeleteTopBtnPressed(app,event)});
        
            app.AddTopBtn = uibutton(app.UIFigure,'Text','Přidat vrchol','Position',[600 170 90 30], ...
            'ButtonPushedFcn',{@(btn,event)AddTopBtnPressed(app,event)});
        
            app.SeventhText = uilabel(app.UIFigure);
            app.SeventhText.HorizontalAlignment = 'left';
            app.SeventhText.Position = [600 120 200 30];
            app.SeventhText.Text = '7. Export křivky';
            
            app.FileName = uieditfield(app.UIFigure, 'text');
            app.FileName.Position = [670 70 100 22];
            app.FileName.ValueChangedFcn = @(txt,event) fileNameChanged(app,event);
            
            app.FileNameLabel = uilabel(app.UIFigure);
            app.FileNameLabel.HorizontalAlignment = 'left';
            app.FileNameLabel.Position = [600 70 80 22];
            app.FileNameLabel.Text = 'File Name:';
            
            
            app.ExportBtn = uibutton(app.UIFigure,'Text','Export','Position',[820 70 90 30], ...
            'ButtonPushedFcn',{@(btn,event)ExportBtnPressed(app,event)});

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

            % 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