function varargout = OACM_1_length_width(varargin)
% OACM_1_LENGTH_WIDTH MATLAB code for OACM_1_length_width.fig
%      OACM_1_LENGTH_WIDTH, by itself, creates a new OACM_1_LENGTH_WIDTH or raises the existing
%      singleton*.
%
%      H = OACM_1_LENGTH_WIDTH returns the handle to a new OACM_1_LENGTH_WIDTH or the handle to
%      the existing singleton*.
%
%      OACM_1_LENGTH_WIDTH('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in OACM_1_LENGTH_WIDTH.M with the given input arguments.
%
%      OACM_1_LENGTH_WIDTH('Property','Value',...) creates a new OACM_1_LENGTH_WIDTH or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before OACM_1_length_width_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to OACM_1_length_width_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help OACM_1_length_width

% Last Modified by GUIDE v2.5 13-Jan-2023 11:52:44

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @OACM_1_length_width_OpeningFcn, ...
                   'gui_OutputFcn',  @OACM_1_length_width_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before OACM_1_length_width is made visible.
function OACM_1_length_width_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to OACM_1_length_width (see VARARGIN)


global file
global filename
global maskColor
global maskLinewidth
global boundary_x
global boundary_y
global thres_init
global thres
global res_length
global suspected_length_of_timestamp
global timeStampsFrame_flag
global rb_unit_state
global showProgress
global showGrid
global minConfidenceValue

filename = [];

addlistener(handles.slider_pics,'ContinuousValueChange',@(hObject,eventdata)OACM_1_length_width('updateImage',hObject,eventdata,guidata(hObject)));
set(handles.slider_pics, 'Enable', 'off');


axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
set(gca,'Visible', 'on')

axes(handles.axes_showArea);            % Auswahl des entsprechenden Axes-Objekts
set(gca,'Visible', 'on')


maskColor = 'r';
maskLinewidth = 2;

res_pixels = 100;
res(5) = 31.4;
res(4) = 25.595;
res(3) = 20.477;
res(2) = 15.74;
res(1) = 14.7;
res(6) = 58.6;
res(7) = 293.0;

for i=1:length(res)
    resString{1, i} = num2str(res(i));
end
set(handles.popupmenu_resolution, 'String', resString);
contents = cellstr(get(handles.popupmenu_resolution, 'String'));
getVal = contents(get(handles.popupmenu_resolution, 'Value'));

res_length = str2num(getVal{1});

set(handles.edit_resolution_pixels, 'String', num2str(res_pixels));
set(handles.rb_unit_um, 'Value', 1);
set(handles.rb_getTimestampsAutomatic, 'Value', 1);

rb_unit_state = get(get(handles.rb_unit,'SelectedObject'),'Tag');

thres_init = 0.2;
thres_max = 1;
thres_step = 0.01;
thres = thres_init;

set(handles.slider_threshold, 'Min', 0, 'Max', thres_max, 'SliderStep', [thres_step/(thres_max-thres_step), 2*thres_step/(thres_max-thres_step)], 'Value', thres_init, 'Enable', 'off');

timeStampsFrame_flag = 0;
suspected_length_of_timestamp = 13;
minConfidenceValue = 0.6;

% timestamps_roi_x = 200;
% timestamps_roi_y = 50;
% timestamps_roi_x_upperLeft = 1;
% timestamps_roi_y_upperLeft = 1;

% set(handles.edit_timestamps_roi_horizontal, 'String', num2str(timestamps_roi_x));
% set(handles.edit_timestamps_roi_vertical, 'String', num2str(timestamps_roi_y));

showGrid = 0;
set(handles.cb_showGrid, 'Value', showGrid);
enableDisable_grid(handles);

showProgress = 1;
set(handles.cb_showProgress, 'Value', showProgress);

file = [];
boundary_x = [];
boundary_y = [];


% Ausgrauen zu Beginn
set(handles.button_chooseArea, 'Enable', 'off');
set(handles.button_setArea, 'Enable', 'off');
set(handles.button_chooseRefLines, 'Enable', 'off');
set(handles.button_setRefLines, 'Enable', 'off');
set(handles.button_getLengthWidth, 'Enable', 'off');
set(handles.cb_showProgress, 'Enable', 'off');
set(handles.cb_showGrid, 'Enable', 'off');
set(handles.button_Save, 'Enable', 'off');
set(handles.button_SaveInt, 'Enable', 'off');
set(handles.button_manualCorrectionLength, 'Enable', 'off');
set(handles.button_manualCorrectionWidth, 'Enable', 'off');
set(handles.button_manualCorrectionOk, 'Enable', 'off');
% set(handles.button_cancel, 'Enable', 'off');
set(findall(handles.rb_getTimestamps, '-property', 'enable'), 'enable', 'off');
set(findall(handles.eg_timestamps_roi, '-property', 'enable'), 'enable', 'off');
set(handles.button_openSettings, 'Enable', 'off');
set(handles.button_saveSettings, 'Enable', 'off');

% Choose default command line output for OACM_1_length_width
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes OACM_1_length_width wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = OACM_1_length_width_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in button_choosePic.
function button_choosePic_Callback(hObject, eventdata, handles)
% hObject    handle to button_choosePic (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global userLine
global userArea
global userArea_timestamps
global file
global boundary_x
global boundary_y
global filename
global path
global posWidth
global posLength
global pL
global pW
global timestamps_roi_x
global timestamps_roi_y
global timestamps_roi_x_upperLeft
global timestamps_roi_y_upperLeft
global maskBoundary
global refLineLengthMask
global refLineWidthMask
global userAreaMask
global thres
global thres_init

global fps
global fps_no

filename_old = filename;
filename = [];

try
[filename,path] = uigetfile('*.tif;*.png;*.jpg',...
   'Select One or More Pictures', ...
   'MultiSelect', 'on');

    if iscell(filename)
        newDataFlag = 1;
    elseif filename ~= 0
        newDataFlag = 1;
    else
        newDataFlag = 0;
    end
       
    if newDataFlag == 1
        file = [];
        boundary_x = [];
        boundary_y = [];
        posLength = [];
        posWidth = [];
        pL = [];
        pW = [];
        timestamps_roi_x = [];
        timestamps_roi_y = [];
        timestamps_roi_x_upperLeft = [];
        timestamps_roi_y_upperLeft = [];
        maskBoundary = [];
        refLineLengthMask = [];
        refLineWidthMask = [];
        userAreaMask = [];
        
        fps = [];
        fps_no = [];
        
        axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
        cla;
        hold(handles.axes_showImage,'off');
        if ~isempty(userLine)
            delete(userLine);
        end
        if ~isempty(userArea)
            delete(userArea);
        end
        if ~isempty(userArea_timestamps)
            delete(userArea_timestamps);
        end

        axes(handles.axes_showArea);
        cla;
        hold(handles.axes_showArea,'off');
        axes(handles.axes_showEdgeDetection);
        cla;
        hold(handles.axes_showEdgeDetection,'off');
        axes(handles.axes_showHistogram);
        cla;
        hold(handles.axes_showHistogram,'off');


        if iscell(filename)
            for i=1:length(filename)
                picPathname{i} = [path filename{i}];
                file{i} = imread(picPathname{i});
                if length(size(file{i})) == 3
                    tmpfile = file{i}(:,:,1);
                    file{i} = tmpfile;
                end
            end
            showImage(handles, file{1});
            set(handles.slider_pics, 'Min', 1, 'Max', length(file), 'SliderStep', [1/(length(file)-1), 2/(length(file)-1)], 'Value', 1, 'Enable', 'on');
        else
            picPathname = [path filename];
            file = imread(picPathname);
            if length(size(file)) == 3
                tmpfile = file(:,:,1);
                file = tmpfile;
            end
            showImage(handles, file);
            set(handles.slider_pics, 'Enable', 'off');
            set(handles.slider_pics, 'Value', 1)
        end
        
        thres = thres_init;
        set(handles.slider_threshold, 'Value', thres_init, 'Enable', 'off');
        set(handles.text_threshold, 'String', get(handles.slider_threshold, 'Value'));
        
        showImageNo(handles, 1);
        guidata(hObject,handles);
        set(handles.button_chooseArea, 'Enable', 'on');

        set(handles.button_setArea, 'Enable', 'off');
        set(handles.button_chooseRefLines, 'Enable', 'off');
        set(handles.button_setRefLines, 'Enable', 'off');
        set(handles.button_getLengthWidth, 'Enable', 'off');
        set(handles.cb_showProgress, 'Enable', 'off');
        set(handles.cb_showGrid, 'Enable', 'on');
        set(handles.button_Save, 'Enable', 'off');
        set(handles.button_SaveInt, 'Enable', 'off');
        set(handles.button_manualCorrectionLength, 'Enable', 'off');
        set(handles.button_manualCorrectionWidth, 'Enable', 'off');
        set(handles.button_openSettings, 'Enable', 'on');
        set(handles.button_saveSettings, 'Enable', 'on');
        set(findall(handles.rb_getTimestamps, '-property', 'enable'), 'enable', 'on');
        set(findall(handles.eg_timestamps_roi, '-property', 'enable'), 'enable', 'on');
        
        set(handles.text_min, 'String', '');
        set(handles.text_sec, 'String', '');
        set(handles.text_length, 'String', '');
        set(handles.text_width, 'String', '');
    
    else
        filename = filename_old;
    end

catch
    set(handles.button_chooseArea, 'Enable', 'off');
    warndlg('No files uploaded!','Warning');
end



function showImage(handles, pic)
global boundary_x
global boundary_y
global maskColor
global maskLinewidth
global timestamps_roi_x
global posLength

% axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
h = imshow(pic, 'Parent', handles.axes_showImage);
h.Parent.Visible = 'on';

if ~isempty(boundary_x)
    hold(handles.axes_showImage,'on');
    plot(handles.axes_showImage, boundary_x, boundary_y, 'Color', maskColor, 'Linewidth', maskLinewidth);
    hold(handles.axes_showImage,'off');
end
if ~isempty(timestamps_roi_x)
    plotRectTimestamps(handles);
end

enableDisable_grid(handles);


function showImageNo(handles, imageNoTmp)
global file
global imageNoAct

imageNoAct = imageNoTmp;

if iscell(file)
    imageNoMax = length(file);
else
    imageNoMax = 1;
end
imageNo = ['Image ' num2str(imageNoAct) ' of ' num2str(imageNoMax)];
set(handles.text_imageNo, 'String', imageNo);



function updateImage(hObject, eventdata, handles)
global file
global imageNoAct

imageNoAct = round(get(hObject, 'Value'));
showImageNo(handles, imageNoAct);
if iscell(file)
    pic = file{imageNoAct};
else
    pic = file;
end
showImage(handles, pic);

guidata(hObject,handles);


function showArea(handles, pic)

%setBoundaries();
% axes(handles.axes_showArea);            % Auswahl des entsprechenden Axes-Objekts

global file
global meanGL
%global ImageNoAct

%meanGL = 0;
%set(handles.button_SaveInt, 'Enable', 'on');          % Damit button für Speicherung der Intensitätsvalues angeklickt und gespeichert werden kann

h = imshow(pic, 'Parent', handles.axes_showArea);
h.Parent.Visible = 'on';

if iscell(file)
    set(handles.slider_pics, 'Enable', 'on');
end

imageNoAct = round(get(handles.slider_pics, 'Value'));
showImageNo(handles, imageNoAct);

if iscell(file)
    imageNoMax = length(file);
    pic = file{imageNoAct};
else
    pic = file;
end

showHisto(handles, pic);

meanGL = mean2(file{imageNoAct});

set(handles.text_intensity, 'String', meanGL);

axes(handles.axes_showCurve);

hold on;
%line(imageNoAct, meanGL, 'LineStyle', '-');


%erste Option

%p = [imageNoAct meanGL];                
%x = plot(p);


%zweite Option

p = plot(imageNoAct, meanGL,'-x', 'LineWidth', 2);
%plot(imageNoAct, meanGL,'x', 'LineWidth', 2)   % "x" wird fetter angezeigt


%xlim([0 imageNoAct]);
grid on;
hold off;

enableDisable_grid(handles)


function showHisto(handles, pic1)

axes(handles.axes_showHistogram);
[pixelCount, grayLevels] = imhist(pic1);
bar(pixelCount);        %y-Achse zeigt Pixelanzeige, 
xlim([0 grayLevels(end)]); % Skalierung der x-Achse manuel (Intensitätswert wird bei der x-achse angezeigt)
grid on;
set(handles.button_SaveInt, 'Enable', 'on');
enableDisable_grid(handles)


% --- Executes on slider movement.
function slider_pics_Callback(hObject, eventdata, handles)
% hObject    handle to slider_pics (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

global file
global boundary_x
global boundary_y
global thres
global imageNoAct
global posLength
global pL
global pW

imageNoAct = round(get(handles.slider_pics, 'Value'));
showImageNo(handles, imageNoAct);
showImage(handles, file{imageNoAct});

if ~isempty(boundary_x)
    showArea(handles, cropImage(file{imageNoAct}));
    hold(handles.axes_showImage,'on');
    plot(handles.axes_showImage, boundary_x, boundary_y, 'r-');
    if ~isempty(posLength)
        showRefLines(handles)
    end
    hold(handles.axes_showImage,'off');
end
if strcmp(get(handles.slider_threshold, 'Enable'), 'on')
    showImageKirschEdgeThres(handles, file{imageNoAct}, thres, 1);            
end
if ~isempty(pL) && imageNoAct <= length(pL)
    p1L = pL{imageNoAct}{1};
    p2L = pL{imageNoAct}{2};
    p1W = pW{imageNoAct}{1};
    p2W = pW{imageNoAct}{2};

    showImageKirschEdgeWidthLength(handles, p1L, p2L, p1W, p2W);
    laenge = calculateLength(handles, p1L, p2L);
    displayLength(handles, laenge);
    breite = calculateWidth(handles, p1W, p2W);
    displayWidth(handles, breite);
end

  

% --- Executes during object creation, after setting all properties.
function slider_pics_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider_pics (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on button press in button_setRefLines.
function button_setRefLines_Callback(hObject, eventdata, handles)
% hObject    handle to button_setRefLines (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global refLineLength
global refLineWidth
global refLineLengthMask
global refLineWidthMask
global posLength
global posWidth
global file

if iscell(file)
    set(handles.slider_pics, 'Enable', 'on');
end

tmp_1 = refLineLength;
tmp_2 = refLineWidth;

pos_tmp_1 = getPosition(tmp_1);
pos_tmp_2 = getPosition(tmp_2);

length_tmp_1 = norm([pos_tmp_1(2,1)-pos_tmp_1(1,1) pos_tmp_1(2,2)-pos_tmp_1(1,2)]);
length_tmp_2 = norm([pos_tmp_2(2,1)-pos_tmp_2(1,1) pos_tmp_2(2,2)-pos_tmp_2(1,2)]);

if length_tmp_1 > length_tmp_2
    refLineLength = tmp_1;
    refLineWidth = tmp_2;
    posLength = pos_tmp_1;
    posWidth = pos_tmp_2;
else
    refLineLength = tmp_2;
    refLineWidth = tmp_1;
    posLength = pos_tmp_2;
    posWidth = pos_tmp_1;
end

imageNoAct = round(get(handles.slider_pics, 'Value'));
if iscell(file)
    pic = file{imageNoAct};
else
    pic = file;
end

tmp_lengthMask = refLineLength.createMask();
tmp_widthMask = refLineWidth.createMask();

% se = strel('line',3,90);
se = strel('line',1,90);
refLineLengthMask = imdilate(tmp_lengthMask, se);
refLineWidthMask = imdilate(tmp_widthMask, se);


croppedImage = cropImage(pic);
hold(handles.axes_showArea,'off');
showArea(handles, croppedImage);
hold(handles.axes_showArea,'on');
showRefLines(handles)

set(handles.button_setRefLines, 'Enable', 'off');
set(handles.button_getLengthWidth, 'Enable', 'on');
set(handles.cb_showProgress, 'Enable', 'on');


function showRefLines(handles)
global posLength
global posWidth
global boundary_x
global boundary_y
global file

minX = min(boundary_x);
minY = min(boundary_y);

axes(handles.axes_showArea);            % Auswahl des entsprechenden Axes-Objekts
hold(handles.axes_showArea,'on');
plot(posLength(:,1), posLength(:,2), 'b--', 'LineWidth', 2)
plot(posWidth(:,1), posWidth(:,2), 'b--', 'LineWidth', 2)
hold(handles.axes_showArea,'off');

axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
imageNoAct = round(get(handles.slider_pics, 'Value'));
showImageNo(handles, imageNoAct);
if iscell(file)
    imageNoMax = length(file);
    pic = file{imageNoAct};
else
    pic = file;
end
hold(handles.axes_showImage,'off');
showImage(handles, pic);

hold(handles.axes_showImage,'on');
plot(posLength(:,1)+minX, posLength(:,2)+minY, 'b--', 'LineWidth', 2)
plot(posWidth(:,1)+minX, posWidth(:,2)+minY, 'b--', 'LineWidth', 2)
hold(handles.axes_showImage,'off');


% res_pixels = str2num(get(handles.edit_resolution_pixels, 'String'));
% res_length = str2num(get(handles.edit_resolution_length, 'String'));
% 
% scaling = res_length/res_pixels;
% 
% if (isempty(res_pixels) || isempty(res_length))
%   % File doesn't exist -- didn't find it there.  Check the search path for it.
%     errorMessage = sprintf('Error: Missing resolution');
%     uiwait(warndlg(errorMessage));
%     return;
% end
% 
% userLinePos = userLine.getPosition;
% x1 = userLinePos(1,1);
% x2 = userLinePos(2,1);
% y1 = userLinePos(1,2);
% y2 = userLinePos(2,2);
% 
% 
% initialLength = round(sqrt((x1-x2)^2+(y1-y2)^2)*scaling, 4);
% 
% switch get(get(handles.rb_unit,'SelectedObject'),'Tag')
%     case 'rb_unit_um'
%         einheit = ' µm';
%     case 'rb_unit_nm'
%         einheit = ' nm';
%     case 'rb_unit_mm'
%         einheit = ' mm';
%     otherwise
%         einheit = ' [ ]';
% end
% 
% lengthString = [num2str(initialLength) einheit];
% set(handles.text_initLength, 'String', lengthString);



function edit_resolution_pixels_Callback(hObject, eventdata, handles)
% hObject    handle to edit_resolution_pixels (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_resolution_pixels as text
%        str2double(get(hObject,'String')) returns contents of edit_resolution_pixels as a double


% --- Executes during object creation, after setting all properties.
function edit_resolution_pixels_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_resolution_pixels (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes when selected object is changed in rb_unit.
function rb_unit_SelectionChangedFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in rb_unit 
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global rb_unit_state
rb_unit_state = get(eventdata.NewValue, 'Tag');


%{
function showArea1(handles, pic)

h = imshow(pic, 'Parent', handles.axes_showArea);
h.Parent.Visible = 'on';

enableDisable_grid(handles)
%}



% --- Executes on button press in button_chooseRefLines.
function button_chooseRefLines_Callback(hObject, eventdata, handles)
% hObject    handle to button_chooseRefLines (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global file
global refLineLength
global refLineWidth

set(handles.slider_pics, 'Enable', 'off');

axes(handles.axes_showArea);            % Auswahl des entsprechenden Axes-Objekts

if ~isempty(refLineLength)
    delete(refLineLength);
end
if ~isempty(refLineWidth)
    delete(refLineWidth);
end

if iscell(file)
    imageNoAct = round(get(handles.slider_pics, 'Value'));
    pic = file{imageNoAct};
else
    imageNoAct = 1;
    pic = file;
end

showImageNo(handles, imageNoAct);
showImage(handles, pic);
hold(handles.axes_showArea,'off');
showArea(handles, cropImage(pic));
hold(handles.axes_showArea,'on');

refLineLength = drawline();
refLineWidth = drawline();

set(handles.button_setRefLines, 'Enable', 'on');
set(handles.button_Save, 'Enable', 'off');


% Create a binary image ("mask") from the ROI object.
% userLineImage = userLine.createMask();


% --- Executes on button press in button_chooseArea.
function button_chooseArea_Callback(hObject, eventdata, handles)
% hObject    handle to button_chooseArea (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global boundary_x
global boundary_y
global file
global thres

global userLine
global posLength
global posWidth
global pL
global pW
global meanGL


imageNoAct = round(get(handles.slider_pics, 'Value'));
showImageNo(handles, imageNoAct);

boundary_x = [];
boundary_y = [];

if iscell(file)
    pic = file{imageNoAct};
else
    pic = file;
end

showImage(handles, pic);
axes(handles.axes_showArea);
cla;
axes(handles.axes_showEdgeDetection);
cla;
axes(handles.axes_showHistogram);
cla;
axes(handles.axes_showCurve);
cla;

posLength = [];
posWidth = [];
pL = [];
pW = [];
if ~isempty(userLine)
    delete(userLine);
end

set(handles.button_setArea, 'Enable', 'off');
set(handles.button_chooseRefLines, 'Enable', 'off');
set(handles.button_setRefLines, 'Enable', 'off');
set(handles.slider_threshold, 'Enable', 'off');
set(handles.button_getLengthWidth, 'Enable', 'off');
set(handles.cb_showProgress, 'Enable', 'off');
set(handles.button_Save, 'Enable', 'on');

set(handles.text_length, 'String', '');
set(handles.text_width, 'String', '');
set(handles.text_intensity, 'String', '');

set(handles.text_min, 'String', '');
set(handles.text_sec, 'String', '');

%%%%% generate Area
global userArea

set(handles.slider_pics, 'Enable', 'off');

axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
if ~isempty(userArea)
    delete(userArea);
end

userArea = imfreehand();

set(handles.button_setArea, 'Enable', 'on');


% --- Executes on button press in button_setArea.
function button_setArea_Callback(hObject, eventdata, handles)
% hObject    handle to button_setArea (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global file
global boundary_x
global boundary_y

if iscell(file)
    set(handles.slider_pics, 'Enable', 'on');
end

imageNoAct = round(get(handles.slider_pics, 'Value'));
showImageNo(handles, imageNoAct);

if iscell(file)
    imageNoMax = length(file);
    pic = file{imageNoAct};
else
    pic = file;
end

%setBoundaries();
%showArea(handles, pic);

global userArea
global maskBoundary
global userAreaMask

userAreaMask = userArea.createMask();
pic1 = pic(userAreaMask);


% Get coordinates of the boundary of the drawn region.
maskBoundaries = bwboundaries(userAreaMask);
boundary_x = maskBoundaries{1}(:, 2); % Columns.
boundary_y = maskBoundaries{1}(:, 1); % Rows.

left = min(boundary_x);
width = max(boundary_x) - min(boundary_x) +1;
bottom = min(boundary_y);
height = max(boundary_y) - min(boundary_y) +1;

maskBoundary = [left, bottom, width, height];

hold(handles.axes_showImage,'off');
showImage(handles, pic);
hold(handles.axes_showImage,'on');
plot(handles.axes_showImage, boundary_x, boundary_y, 'r-');
hold(handles.axes_showImage,'off');

croppedImage = cropImage(pic);
hold(handles.axes_showArea,'off');
showArea(handles, croppedImage);
hold(handles.axes_showArea,'on');
showHisto(handles, pic1);

set(handles.button_setArea, 'Enable', 'off');
set(handles.button_chooseRefLines, 'Enable', 'on');

%%% Edge Detection direkt anzeigen:
global thres

set(handles.slider_threshold, 'Enable', 'on');
set(handles.slider_threshold, 'Value', thres);
set(handles.text_threshold, 'String', get(handles.slider_threshold, 'Value'));

% imageNoAct = round(get(handles.slider_pics, 'Value'));
% 
% if iscell(file)
%     pic = file{imageNoAct};
% else
%     pic = file;
% end

%global userArea
%global userAreaMask

%userAreaMask = userArea.createMask();
%{
axes(handles.axes_showHistogram);
selectedPixelValues = pic(userAreaMask);           %binaryImage da es die Maske selbst ist
[pixelCount, grayLevels] = imhist(selectedPixelValues);
bar(pixelCount);        %y-Achse zeigt Pixelanzeige, 
xlim([0 grayLevels(end)]); % Skalierung der x-Achse manuel (Intensitätswert wird bei der x-achse angezeigt)
grid on;
%}
showImageKirschEdgeThres(handles, pic, thres, 1);


function showArea_afterOpeningSettings(hObject, eventdata, handles)
% hObject    handle to button_setArea (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global file
global imageNoAct
global thres
global userAreaMask

if iscell(file)
    pic = file{imageNoAct};
else
    pic = file;
end

croppedImage = cropImage(pic);
hold(handles.axes_showArea,'off');
showArea(handles, croppedImage);
hold(handles.axes_showArea,'on');

set(handles.slider_threshold, 'Enable', 'on');
set(handles.slider_threshold, 'Value', thres);
set(handles.text_threshold, 'String', get(handles.slider_threshold, 'Value'));

showImageKirschEdgeThres(handles, pic, thres, 1);

%{
function setBoundaries()
global userArea
global maskBoundary
global boundary_x
global boundary_y
global userAreaMask

userAreaMask = userArea.createMask();

% Get coordinates of the boundary of the drawn region.
maskBoundaries = bwboundaries(userAreaMask);
boundary_x = maskBoundaries{1}(:, 2); % Columns.
boundary_y = maskBoundaries{1}(:, 1); % Rows.

left = min(boundary_x);
width = max(boundary_x) - min(boundary_x) +1;
bottom = min(boundary_y);
height = max(boundary_y) - min(boundary_y) +1;

maskBoundary = [left, bottom, width, height];
%}




function croppedImage = cropImage(pic)

global maskBoundary
global userAreaMask

if size(pic, 1) == 1
    userAreaImageData = mat2gray(pic.CData);
    userAreaImageData(~userAreaMask) = 0;
else
    userAreaImageData = pic;
    userAreaImageData(~userAreaMask) = 0;
end

croppedImage = imcrop(userAreaImageData, maskBoundary);




% --- Executes on slider movement.
function slider_threshold_Callback(hObject, eventdata, handles)
% hObject    handle to slider_threshold (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

global file
global thres

set(hObject, 'Value', round(get(hObject, 'Value'),2));
set(handles.text_threshold, 'String', num2str(get(hObject, 'Value')));
imageNoAct = round(get(handles.slider_pics, 'Value'));

thres = get(hObject, 'Value');

if iscell(file)
    pic = file{imageNoAct};
else
    pic = file;
end

showImageKirschEdgeThres(handles, pic, thres, 1);


% --- Executes during object creation, after setting all properties.
function slider_threshold_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider_threshold (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end



function showImageKirschEdgeThres(handles, file, thres, sliderMovement, pic)
global boundary_x
global binary_POI
global imageNoAct
global showProgress

if iscell(file)
   kirsch_image = kirschEdgeThreshold(file{imageNoAct}, thres);
elseif isempty(file)
   kirsch_image = [];
else
   kirsch_image = kirschEdgeThreshold(file, thres);
end
   
if isempty(boundary_x)
    pic = kirsch_image;
else
    pic = cropImage(kirsch_image);
end
if isempty(file)
    pic = [];
end

binary_POI = pic;


if showProgress == 1 || sliderMovement == 1
    h = imshow(pic, 'Parent', handles.axes_showEdgeDetection);
    h.Parent.Visible = 'on';
    enableDisable_grid(handles)
end





% function showImageKirschEdge(handles, file)
% global boundary_x
% global binary_POI
% global showProgress
% 
% if iscell(file)
%    kirsch_image = kirschEdgeThreshold(file{imageNoAct});
% elseif isempty(file)
%    kirsch_image = [];
% else
%    kirsch_image = kirschEdgeThreshold(file);
% end
% 
% if isempty(boundary_x)
%     pic = kirsch_image;
% else
%     pic = cropImage(kirsch_image);
% end
% if isempty(file)
%     pic = [];
% end
% 
% binary_POI = pic;
% 
% if showProgress
%     h = imshow(pic, [], 'Parent', handles.axes_showEdgeDetection);
%     h.Parent.Visible = 'on';
% end


% --- Executes on button press in button_getLengthWidth.
function button_getLengthWidth_Callback(hObject, eventdata, handles)
% hObject    handle to button_getLengthWidth (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global file
global thres
global imageNoAct
global boundary_x
global boundary_y
global lengthSaved
global widthSaved
global pW
global pL
global newLength
global newWidth
global flagCorL
global flagCorW
% global cancel
global showProgress
global errorCount

% cancel = 0;
flagCorL = 0;
flagCorW = 0;
lengthSaved = [];
widthSaved = [];
pW = [];
pL = [];
newLength = [];
newWidth = [];
errorCount = [];
errorCount(1) = 0;

set(handles.text_min, 'String', ''); 
set(handles.text_sec, 'String', '');
set(handles.text_estMin, 'String', ''); 
set(handles.text_estSec, 'String', '');


t_init = tic;


if iscell(file)
    numberOfFiles = length(file);
else
    numberOfFiles = 1;
end

% set(handles.button_cancel, 'Enable', 'on');

% try
    
    f = waitbar(0,'1','Name','Evaluation progress',...
        'CreateCancelBtn','setappdata(gcbf,''canceling'',1)', 'windowstyle', 'modal');
    setappdata(f,'canceling',0);
    
    i=1;
    t_estMin = NaN;
    t_estSec = NaN;
    
    while i <= numberOfFiles
        
        % Update waitbar and message
        waitbar(i/numberOfFiles,f,sprintf('Image %i of %i - est. time left: %.0f minutes %.1f seconds', i, numberOfFiles, t_estMin, t_estSec))
        % Check for clicked Cancel button
        if getappdata(f,'canceling')
            break
        end
        
        imageNoAct = i;
        if showProgress
            set(handles.slider_pics, 'Value', i)
            showImageNo(handles, imageNoAct);
        end
        
        if iscell(file)
            pic = file{imageNoAct};
        else
            pic = file;
        end
        
        % create binary POI
        if showProgress
            showImageKirschEdgeThres(handles, pic, thres, 1);
        else
            showImageKirschEdgeThres(handles, pic, thres, 0);
        end
        
        [lengthSaved(i), widthSaved(i), pL{i}, pW{i}] = getLengthWidth(hObject, handles);
 
        p1L = pL{1,i}{1};
        p2L = pL{1,i}{2};
        p1W = pW{1,i}{1};
        p2W = pW{1,i}{2};

        if showProgress
            showArea(handles, cropImage(pic));
            showRefLines(handles);
            showImageKirschEdgeWidthLength(handles, p1L, p2L, p1W, p2W);
            displayLength(handles, lengthSaved(i));
            displayWidth(handles, widthSaved(i));

            drawnow
        end
        
%         if cancel == 1
%             break
%         end

        tstep(i) = toc(t_init);
        if i > 1
            tstep(i) = tstep(i) - sum(tstep(1:i-1));
        end
        
        dt = sum(tstep)/length(tstep);
        t_fin = dt*numberOfFiles;
        t_est = t_fin - toc(t_init);
        
        if t_est > 0
            t_estMin = floor(t_est/60);
            t_estSec = rem(t_est,60);
        else
            t_estMin = 0;
            t_estSec = 0;
        end
    
        % estimation after i images
        if i == 2
            t_initMin = floor(dt*i/60);
            t_initSec = rem(dt*i,60);
            set(handles.text_estMin, 'String', sprintf('%.0f', t_estMin + t_initMin)); 
            set(handles.text_estSec, 'String', sprintf('%.1f', t_estSec + t_initSec));
        end
        
        i = i+1;
        
    end
    
    t = toc(t_init);
    tmin = floor(t/60);
    tsec = rem(t,60);
   
    savedNo = length(lengthSaved);
    
    showImage(handles, pic);
    showArea(handles, cropImage(pic));
    set(handles.slider_pics, 'Value', savedNo);
    showImageNo(handles, savedNo);
    showRefLines(handles);
    showImageKirschEdgeWidthLength(handles, p1L, p2L, p1W, p2W);
	displayLength(handles, lengthSaved(savedNo));
    displayWidth(handles, widthSaved(savedNo));
    
    drawnow
    
    delete(f)
    
    lengthSaved = lengthSaved';
    
    set(handles.text_min, 'String', sprintf('%.0f', tmin));
    set(handles.text_sec, 'String', sprintf('%.1f', tsec));

%     set(handles.button_cancel, 'Enable', 'off');
    set(handles.button_manualCorrectionLength, 'Enable', 'on');
    set(handles.button_manualCorrectionWidth, 'Enable', 'on');
    set(handles.button_openSettings, 'Enable', 'on');
    set(handles.button_manualCorrectionOk, 'Enable', 'off');
    set(findall(handles.rb_getTimestamps, '-property', 'enable'), 'enable', 'on');
    set(findall(handles.eg_timestamps_roi, '-property', 'enable'), 'enable', 'on');
    set(handles.button_Save, 'Enable', 'on');
    set(handles.button_saveSettings, 'Enable', 'on');
    
% catch
% %     set(handles.button_cancel, 'Enable', 'off');
%     set(handles.button_manualCorrectionLength, 'Enable', 'off');
%     set(handles.button_manualCorrectionWidth, 'Enable', 'off');
%     set(handles.button_manualCorrectionOk, 'Enable', 'off');
%     set(findall(handles.rb_getTimestamps, '-property', 'enable'), 'enable', 'off');
%     set(findall(handles.eg_timestamps_roi, '-property', 'enable'), 'enable', 'off');
%     set(handles.button_openSettings, 'Enable', 'off');
%     set(handles.button_saveSettings, 'Enable', 'off');
%     set(handles.button_Save, 'Enable', 'off');
%     set(handles.button_saveSettings, 'Enable', 'off');
%     
%     uiwait(warndlg(sprintf('Attention! Please use lower threshold vlaue!'),'Warning'));
% end



function [laenge, breite, posL, posW] = getLengthWidth(hObject, handles)
global binary_POI
% global maskBoundary
global refLineLengthMask
global refLineWidthMask
global imageNoAct
global errorCount

try 
    
    posL = [];
    posW = [];
    laenge = [];
    breite = [];

    bin_POI_Length = (binary_POI == refLineLengthMask) & (refLineLengthMask == 1);
    bin_POI_Width = (binary_POI == refLineWidthMask) & (refLineWidthMask == 1);

    % figure
    % imshow(binary_POI)
    % figure
    % imshow(refLineLengthMask)
    % figure
    % imshow(bin_POI_Length)
    % figure
    % imshow(refLineWidthMask)
    % figure
    % imshow(bin_POI_Width)

    %%%% Laenge
    oneInd = find(bin_POI_Length);
    % Indizes der "Einsen"
    x_ones = fix(oneInd/size(bin_POI_Length,1)+1);
    y_ones = mod(oneInd, size(bin_POI_Length,1));
    tmp = y_ones==0;
    x_ones(tmp) = x_ones(tmp)-1;
    y_ones(tmp) = size(bin_POI_Length,1);
    clear tmp

    % Matrix aller "Einser-Indizes"
    A = [x_ones y_ones];
    % Abstand der Punkte in der Matrix zueinander
    Adist = pdist(A);
    Adist = Adist';

    %# find the indices corresponding to each distance
    tmp = ones(size(A,1));
    tmp = tril(tmp,-1); %# creates a matrix that has 1's below the diagonal
    %# get the indices of the 1's
    [indrow, indcol] = find(tmp);
    clear tmp

    % Abstand und zugehoerige Punkte (als Reihen-Indizes)
    out = [Adist, indrow, indcol];

    % maximaler Abstand
    [indmaxrow, indmaxcol] = find(Adist==max(Adist(:,1)));
    % Reihen-Indizes der Punkte mit dem groessten Abstand zueinander
    indPkt_1 = out(indmaxrow,2);
    indPkt_2 = out(indmaxrow,3);

    % Koordinaten der zwei aeussersten Punkte der Laenge nach
    p1L = A(indPkt_1,:);
    p2L = A(indPkt_2,:);
    posL = {p1L; p2L};

    %%%% Breite
    oneInd = find(bin_POI_Width);
    % Indizes der "Einsen"
    x_ones = fix(oneInd/size(bin_POI_Width,1)+1);
    y_ones = mod(oneInd, size(bin_POI_Width,1));
    tmp = y_ones==0;
    x_ones(tmp) = x_ones(tmp)-1;
    y_ones(tmp) = size(bin_POI_Width,1);
    clear tmp

    % Matrix aller "Einser-Indizes"
    A = [x_ones y_ones];
    % Abstand der Punkte in der Matrix zueinander
    Adist = pdist(A);
    Adist = Adist';

    %# find the indices corresponding to each distance
    tmp = ones(size(A,1));
    tmp = tril(tmp,-1); %# creates a matrix that has 1's below the diagonal
    %# get the indices of the 1's
    [indrow, indcol] = find(tmp);
    clear tmp

    % Abstand und zugehoerige Punkte (als Reihen-Indizes)
    out = [Adist, indrow, indcol];

    % maximaler Abstand
    [indmaxrow, indmaxcol] = find(Adist==max(Adist(:,1)));
    % Reihen-Indizes der Punkte mit dem groessten Abstand zueinander
    indPkt_1 = out(indmaxrow,2);
    indPkt_2 = out(indmaxrow,3);

    % Koordinaten der zwei aeussersten Punkte der Breite nach
    p1W = A(indPkt_1,:);
    p2W = A(indPkt_2,:);
    posW = {p1W; p2W};

    laenge = calculateLength(handles, p1L, p2L);
    breite = calculateWidth(handles, p1W, p2W);

catch
    opts = struct('WindowStyle','modal',... 
              'Interpreter','tex');
    errorCount(1) = errorCount(1) + 1;
    errorCount(end+1) = imageNoAct;
    if errorCount(1) == 1 
        warndlg(sprintf('Attention! There is %i WARNING!\nMeasurement of image no. %g was not successfull!\nPlease check threshold value and/ or reference lines!', ...
            errorCount(1), errorCount(2)), 'Warning', opts);
    else
        str = ['Attention! There are %i WARNINGS!\nMeasurement of images no. ', repmat('%g, ', 1, numel(errorCount(2:end))-1), '%g was not successfull!\nPlease check threshold value and/ or reference lines!'];
        warndlg(sprintf(str, errorCount(1), errorCount(2:end)), 'Warning', opts);
    end
    laenge = NaN;
    breite = NaN;
    posL = {[NaN NaN]; [NaN NaN]};
    posW = {[NaN NaN]; [NaN NaN]};
end



% % Mittelpunkt
% pM = p2+0.5*(p1-p2);
% 
% picWidth = maskBoundary(3);
% picHeight = maskBoundary(4);
% 
% % Senkrechte zu p1/p2 mit kleiner Winkeldrehung
% index = 1;
% 
% addPixel = 5;
% angle = 1;
% 
% for i=-angle:1:angle
%     alpha = 90+i;
%     
%     rotMat = [cosd(alpha) sind(alpha); -sind(alpha) cosd(alpha)]';
%     pRotiert = rotMat*(p1-p2)';
% 
%     porthfkt = polyfit([pM(1) pM(1)+pRotiert(1)], [pM(2) pM(2)+pRotiert(2)], 1);
% 
%     x_orth = [];
%     y_orth = [];
% %     
%     x_orth = 0:picWidth;
%     x_orth = x_orth';
%     y_orth = polyval(porthfkt, x_orth);
% 
%     if picWidth > picHeight
%         x_orth(y_orth <= 0) = [];
%         y_orth(y_orth <= 0) = [];
%         x_orth(y_orth >= picHeight) = [];
%         y_orth(y_orth >= picHeight) = [];
%     end
%     
%     x_orth_ed = [];
%     y_orth_ed = [];
%     for x = 1:size(x_orth,1)
%         for m = -round(addPixel/2):1:round(addPixel/2)
%             x_orth_ed = [x_orth_ed(1:end); x_orth(x)+m];
%         end
%     end
% 
%     if addPixel > 0
%         y_orth_ed = reshape(repmat(y_orth,1,(addPixel+2))', (addPixel+2)*size(y_orth,1), []);
%     else
%         y_orth_ed = y_orth;
%     end
%     y_orth_ed = floor(y_orth_ed);
% 
%     y_orth_ed(x_orth_ed<=0) = [];
%     x_orth_ed(x_orth_ed<=0) = [];
%     x_orth_ed(y_orth_ed<=0) = [];
%     y_orth_ed(y_orth_ed<=0) = [];
%     x_orth_ed(y_orth_ed>picHeight) = [];
%     y_orth_ed(y_orth_ed>picHeight) = [];
%     y_orth_ed(x_orth_ed>picWidth) = [];
%     x_orth_ed(x_orth_ed>picWidth) = [];
%     
%     orthMat = [x_orth_ed y_orth_ed];
% 
%     saveX = [];
%     saveY = [];
%     
%     for x = 1:length(orthMat)
%         if binary_POI(orthMat(x,2), orthMat(x,1)) == 1
%           saveX(end+1) = orthMat(x,1);
%           saveY(end+1) = orthMat(x,2);
%         end
%     end
%     
% %     plot(saveX,saveY,'o')
%     
%     if index > 0 && ~isempty(saveX)
%             orthogonal{index} = [saveX(1) saveY(1); saveX(end) saveY(end)];
%             showImageKirschEdgeWidthLength(handles, p1, p2, pM, orthogonal{index})
%             widths(index) = displayWidth(handles,orthogonal{index});
%             index = index+1;
%     end
% end
% 
% index = find(widths==max(widths));
% widthIndex = index(1);
% 
% showImageKirschEdgeWidthLength(handles, p1, p2, pM, orthogonal{widthIndex})




function showImageKirschEdgeWidthLength(handles, p1L, p2L, p1W, p2W)

global binary_POI

h = imshow(binary_POI, 'Parent', handles.axes_showEdgeDetection);

line_xL = [p1L(1) p2L(1)];
line_yL = [p1L(2) p2L(2)];

% line_orth_x = [pM(1) pM(1)+orth(1)];
% line_orth_y = [pM(2) pM(2)+orth(2)];

hold(handles.axes_showEdgeDetection,'on');
plot(handles.axes_showEdgeDetection, p1L(1),p1L(2), 'ro');
plot(handles.axes_showEdgeDetection, p2L(1),p2L(2), 'ro');
plot(handles.axes_showEdgeDetection, line_xL, line_yL, 'r', 'LineWidth', 2)

line_xW = [p1W(1) p2W(1)];
line_yW = [p1W(2) p2W(2)];
% plot(handles.axes_showEdgeDetection, pM(1),pM(2), 'r*', 'MarkerSize', 10)
% % plot(handles.axes_showEdgeDetection, line_orth_x, line_orth_y, 'r', 'LineWidth', 3)
% plot(handles.axes_showEdgeDetection, orth(:,1), orth(:,2), 'r', 'LineWidth', 3)
% plot(handles.axes_showEdgeDetection, orth(1,1), orth(1,2), 'ro')
% plot(handles.axes_showEdgeDetection, orth(end,1), orth(end,2), 'ro')
plot(handles.axes_showEdgeDetection, p1W(1),p1W(2), 'ro');
plot(handles.axes_showEdgeDetection, p2W(1),p2W(2), 'ro');
plot(handles.axes_showEdgeDetection, line_xW, line_yW, 'r', 'LineWidth', 2)
hold(handles.axes_showEdgeDetection,'off');

drawnow

% h.Parent.Visible = 'on';
enableDisable_grid(handles)


function laenge = calculateLength(handles, p1, p2)
global res_length

res_pixels = str2num(get(handles.edit_resolution_pixels, 'String'));

scaling = res_length/res_pixels;
laenge = round(norm(p1-p2)*scaling, 4);


function displayLength(handles, laenge)

switch get(get(handles.rb_unit,'SelectedObject'),'Tag')
    case 'rb_unit_um'
        einheit = ' µm';
    case 'rb_unit_nm'
        einheit = ' nm';
    case 'rb_unit_mm'
        einheit = ' mm';
    otherwise
        einheit = ' [ ]';
end

lengthString = [num2str(laenge) einheit];
set(handles.text_length, 'String', lengthString);


function breite = calculateWidth(handles, p1, p2)
global res_length

res_pixels = str2num(get(handles.edit_resolution_pixels, 'String'));

scaling = res_length/res_pixels;
% width = round(norm(vec(1,:)-vec(2,:))*scaling, 4);
breite = round(norm(p1-p2)*scaling, 4);


function displayWidth(handles, breite)
switch get(get(handles.rb_unit,'SelectedObject'),'Tag')
    case 'rb_unit_um'
        einheit = ' µm';
    case 'rb_unit_nm'
        einheit = ' nm';
    case 'rb_unit_mm'
        einheit = ' mm';
    otherwise
        einheit = ' [ ]';
end

widthString = [num2str(breite) einheit];
set(handles.text_width, 'String', widthString);




% --- Executes on button press in button_Save.
function button_Save_Callback(hObject, eventdata, handles)
% hObject    handle to button_Save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global path
global file
global filename
global lengthSaved
global widthSaved
global intensitySaved
global suspected_length_of_timestamp
global errorCount
global txt_confidence
global minConfidenceValue

global imageNoAct
global meanGL

global fps_no
global picName_folder

opts = struct('WindowStyle','modal',... 
              'Interpreter','tex');
errorCount = [];
errorCount(1) = 0;

Length = lengthSaved;
Width = widthSaved';
Intensity = meanGL;

if iscell(file)
    if isempty(filename)
        numberOfFiles = length(picName_folder);
        Picture = picName_folder;
    else
        numberOfFiles = length(filename);
        Picture = filename';
        tryPic = [path filename{1}];
    end
else
    numberOfFiles = 1;
    Picture{1} = filename;
    tryPic = [path Picture{1}];
end

%{
imageNoAct = round(get(handles.slider_pics, 'Value'));
showImageNo(handles, imageNoAct);

if iscell(file)
    imageNoMax = length(file);
    pic = file{imageNoAct};
else
    pic = file;
end

%}


switch get(get(handles.rb_getTimestamps,'SelectedObject'),'Tag')
    case 'rb_getTimestampsDisabled'

        if length(Length) < length(Picture)
            Length(end+1:length(Picture)) = NaN;
            Width(end+1:length(Picture)) = NaN;
            Intensity(end+1:length(Picture)) = NaN;
        end
        saveData = table(Picture, Length, Width, Intensity');
        saveNoTime = 1;
        
    case 'rb_getTimestampsAutomatic'
        % Zeitstempel lesen
        saveNoTime = 0;
        timestampInData_flag = 0;
        timestampInPic_flag = 0;
        timestampInFile_flag = 0;
        
        try [tryName tryTimestamp] = getTimeStamp(tryPic);
            timestampInData_flag = 1;
        catch
            
            try [tryName tryTimestamp] = getTimeStamp_fps(1, 0);
                timestampInFile_flag = 1;
            catch
            
                try [tryName, data] = getTimeStamp_OCR(1);
                    tryTimestamp = data{1};
                    check = length(tryTimestamp) == suspected_length_of_timestamp && txt_confidence > minConfidenceValue;
                    if check  ~= 1
                        answer = questdlg('Attention! Timestamps might not be read correctly...', ...
                            'Proceed anyway?', ...
                            'proceed', 'proceed w/o timestamps', 'cancel', 'proceed');
                        switch answer
                            case 'proceed'
                                timestampInPic_flag = 1;
                            case 'proceed w/o timestamps'
                                timestampInPic_flag = 0;
                                saveNoTime = 1;
                            case 'cancel'
                                timestampInPic_flag = 0;
                            otherwise
                                timestampInPic_flag = 0;
                        end
                    else
                        timestampInPic_flag = 1;
                    end
                catch
                    answer = questdlg('Timestamps not readable - Save without timestamps?', ...
                        'Proceed saving?', ...
                        'save', 'cancel', 'save');
                    switch answer
                        case 'save'
                            saveNoTime = 1;
                        otherwise
                    end
                end
            end
        end
        
        if saveNoTime == 1
            saveData = table(Picture, Length, Width, Intensity');
        else
            if timestampInData_flag == 1 || timestampInPic_flag == 1 || timestampInFile_flag == 1
    
                if timestampInFile_flag == 1
                    if length(fps_no) >= 1
                        check = 0;
                        while check == 0
                            prompt = {'You chose at least two sessions. Please enter loop intervall > 0 seconds (e.g. session start every 5 min means 300 seconds):'};
                            dlgtitle = 'Input';
                            dims = [1];
                            definput = {'300'};
                            pause = inputdlg(prompt,dlgtitle,dims,definput);
                            if isempty(pause)
                                check = 0;
                            elseif isempty(str2num(pause{1}))
                                check = 0;
                            else
                                check = 1;
                                pause = str2num(pause{1});
                            end
                        end
                    end 
                end
                
                f = waitbar(0,'1','Name','Saving progress',...
                    'CreateCancelBtn','setappdata(gcbf,''canceling'',1)');
                setappdata(f,'canceling',0);
                
                for i=1:numberOfFiles
                   % Update waitbar and message
                    waitbar(i/numberOfFiles,f,sprintf('Image %i of %i', i, numberOfFiles))
                   % Check for clicked Cancel button
                    if getappdata(f,'canceling')
                        break
                    end
                    if iscell(file)
                        if ~isempty(filename)
                            tmp_file = [path filename{i}];
                        end
                    else
                        tmp_file = [path filename];
                    end
                    if timestampInData_flag == 1
                        [fname{i}, fTimestamp{i}] = getTimeStamp(tmp_file);
                    elseif timestampInFile_flag == 1
                        [fname{i}, fTimestamp{i}] = getTimeStamp_fps(i, pause);
                    elseif timestampInPic_flag == 1
                        [fname{i}, fTimestampData{i}] = getTimeStamp_OCR(i);
                        fTimestamp{i} = fTimestampData{i}{1};
                        check = length(fTimestamp{i}) == suspected_length_of_timestamp && txt_confidence > minConfidenceValue;
                        if check~= 1
                          % uiwait(warndlg(sprintf('Attention! Timestamp might not be read correctly at image no. %i !', i),'Warning'));
                          % warndlg(sprintf('Attention! Timestamp might not be read correctly at image no. %i !', i),'Warning');
                            errorCount(1) = errorCount(1) +1;
                            errorCount(end+1) = i;
                            if errorCount(1) == 1 
                                warndlg(sprintf('Attention! There is %i WARNING!\nTimestamp might not be read correctly at image no. %i !', ...
                                    errorCount(1), errorCount(2)), 'Warning', opts);
                            else
                                str = ['Attention! There are %i WARNINGS!\nTimestamp might not be read correctly at image no. ', repmat('%g, ', 1, numel(errorCount(2:end))-1), '%g !'];
                                warndlg(sprintf(str, errorCount(1), errorCount(2:end)), 'Warning', opts);
                            end                            
                        end
                    end
                end
                delete(f)

                if length(Length) < length(Picture)
                    Length(end+1:length(Picture)) = NaN;
                end
                if length(Width) < length(Picture)
                    Width(end+1:length(Picture)) = NaN;
                end
                 if length(Intensity) < length(Picture)
                    Intensity(end+1:length(Picture)) = NaN;
                end
                if length(fTimestamp) < length(Picture)
                    for i=length(fTimestamp):length(Picture)
                        fTimestamp{i} = 'NaN';
                    end
                end
                
                %showHisto(handles, pic);

                %meanGL = mean2(file{imageNoAct});
                %meanGL = mean2(pic);
                %set(handles.text_intensity, 'String', meanGL);

                %Intensity = meanGL;
                
                Timestamp = fTimestamp';
                saveData = table(Picture, Timestamp, Intensity');

                clear Timestamp fTimestamp
            end
        end
    otherwise
end

if saveNoTime == 1 || timestampInData_flag == 1 || timestampInPic_flag == 1 || timestampInFile_flag == 1
    try [tmp_file, savepath] = uiputfile('*.xlsx');
        writetable(saveData, [savepath tmp_file]);
    catch
        warndlg('Attention! Not saved!','Warning');
    end
end


% function [fname, time, tmp] = getTimeStamp_OCR(number)
function [fname, data] = getTimeStamp_OCR(number)

global filename
global file
global path
global timestamps_roi_x_upperLeft
global timestamps_roi_y_upperLeft
global timestamps_roi_x
global timestamps_roi_y
global txt_confidence

if iscell(file)
    tmp_file = [path filename{number}];
    fileToExamine = file{number};
else
    tmp_file = [path filename];
    fileToExamine = file;
end

info = imfinfo(tmp_file);
A = info.Filename;
tmp = strsplit(A, '\');
fname = tmp{end};
fname = fname(1:end-4);

% region of interest (timestamp) [x1 x2 y1 y2]
roi = [timestamps_roi_x_upperLeft timestamps_roi_x_upperLeft+timestamps_roi_x timestamps_roi_y_upperLeft timestamps_roi_y_upperLeft+timestamps_roi_y];

roi_timestamp = fileToExamine(roi(3):roi(4), roi(1):roi(2));
tmptime = ocr(roi_timestamp, 'CharacterSet', '0123456789:.');

% figure
% imshow(roi_timestamp)
% 
% Iocr = insertObjectAnnotation(roi_timestamp, 'rectangle', ...
%                               tmptime.WordBoundingBoxes, ...
%                               tmptime.WordConfidences);
% figure
% imshow(Iocr)

tmptime.WordConfidences;
txt_confidence = min(tmptime.WordConfidences);

time_string = tmptime.Words;
%time_string = tmptime.Words{1}


if length(time_string) > 1
    time_string_tmp = time_string{1};
    for i=2:length(time_string)
        time_string_tmp = [time_string_tmp time_string{i}];
    end
    time_string_check{1} = time_string_tmp;
else
    time_string_check = time_string;
end

del = 0;
for j=1:length(time_string_check{1}) 
    if strcmp(time_string_check{1}(j), ' ') || strcmp(time_string_check{1}(j), ':') || strcmp(time_string_check{1}(j), '.')
        del(end+1) = j;
    end
end

time_string_check{1}(del(2:end)) = [];

time = [time_string_check{1}(1:2) ':' time_string_check{1}(3:4) ':' time_string_check{1}(5:6) '.' time_string_check{1}(7:end)];

data = {time};


function [fname, time] = getTimeStamp(file)

info = imfinfo(file);
title = info.ImageDescription;

A = info.Filename;
tmp = strsplit(A, '\');
fname = tmp{end};
fname = fname(1:end-4);

clear tmp
C = strsplit(title, ', ');
for i=1:length(C)
    if ~isempty(strfind(C{i},'Time'))
        tmp = strsplit(C{i}, ' "');
        tmp_time = tmp{2};
        tmp_time = tmp_time(1:end-1);
    end
end

% time = tmp_time

tmp = strsplit(tmp_time, '-');
min = tmp{end-1}(end-3:end-2);
sec = tmp{end-1}(end-1:end);
time = [min ':' sec '.' tmp{end}];


% function [fname, time, tmp] = getTimeStamp_OCR(number)
function [fname, time] = getTimeStamp_fps(number, pause)

global fps
global fps_no
global picName_folder

pos = 0;
tmp = 0;
tmp_old = 0;

for i = 1:length(fps_no)
    tmp = tmp_old + fps_no(i);
    if number <= tmp && number > tmp_old
        pos = i;
    end
    tmp_old = tmp;
end

if pos == 1
    if number-1 == 0
        time = 0;
    else
        time = 1/fps(pos)*(number-1);
    end
else
    if number-1 - sum(fps_no(1:pos-1)) == 0
        time = (pos-1)*pause;
    else
        time = 1/fps(pos) * (number-1 - sum(fps_no(1:pos-1))) + (pos-1)*pause;
    end
end

hou = floor(time/3600);
min = mod(floor(time/60),60);
sec = mod(time,60);
tmp = strsplit(num2str(sec), '.');
time = [num2str(hou) ':' num2str(min) ':' num2str(floor(sec)) '.' tmp{end}];

fname = picName_folder{number};


% --- Executes on button press in button_manualCorrectionWidth.
function button_manualCorrectionWidth_Callback(hObject, eventdata, handles)
% hObject    handle to button_manualCorrectionWidth (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global newWidth
global flagCorW

axes(handles.axes_showEdgeDetection);            % Auswahl des entsprechenden Axes-Objekts

flagCorW = 1;
newWidth = imline();

set(handles.button_manualCorrectionWidth, 'Enable', 'off');
set(handles.button_manualCorrectionOk, 'Enable', 'on');



% --- Executes on button press in button_manualCorrectionLength.
function button_manualCorrectionLength_Callback(hObject, eventdata, handles)
% hObject    handle to button_manualCorrectionLength (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global newLength
global flagCorL
axes(handles.axes_showEdgeDetection);            % Auswahl des entsprechenden Axes-Objekts

flagCorL = 1;
newLength = imline();

set(handles.button_manualCorrectionLength, 'Enable', 'off');
set(handles.button_manualCorrectionOk, 'Enable', 'on');



% --- Executes on button press in button_manualCorrectionOk.
function button_manualCorrectionOk_Callback(hObject, eventdata, handles)
% hObject    handle to button_manualCorrectionOk (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global imageNoAct
global pW
global pL
global newLength
global newWidth
global widthSaved
global lengthSaved
global flagCorW
global flagCorL


%%%%% Breite
if flagCorW == 1
    tmp_W = newWidth;
    % Positionen/Koordinaten
    pos_tmp_W = getPosition(tmp_W);
    p1W = pos_tmp_W(1,:);
    p2W = pos_tmp_W(2,:);
    % Abstand der Punkte
    breite = calculateWidth(handles, p1W, p2W);
    displayWidth(handles, breite);

    pW{imageNoAct} = {p1W; p2W};
    widthSaved(imageNoAct) = breite;
    flagCorW = 0;
else
    p1W = pW{imageNoAct}{1};
    p2W = pW{imageNoAct}{2};
end

%%%%% Laenge
if flagCorL == 1
    tmp_L = newLength;
    % Positionen/Koordinaten
    pos_tmp_L = getPosition(tmp_L);
    p1L = pos_tmp_L(1,:);
    p2L = pos_tmp_L(2,:);
    % Abstand der Punkte
    laenge = calculateLength(handles, p1L, p2L);
    displayLength(handles, laenge);

    pL{imageNoAct} = {p1L; p2L};
    lengthSaved(imageNoAct) = laenge;
    flagCorL = 0;
else
    p1L = pL{imageNoAct}{1};
    p2L = pL{imageNoAct}{2};
end

showImageKirschEdgeWidthLength(handles, p1L, p2L, p1W, p2W);

delete(newLength);
delete(newWidth);

set(handles.button_manualCorrectionOk, 'Enable', 'off');
set(handles.button_manualCorrectionLength, 'Enable', 'on');
set(handles.button_manualCorrectionWidth, 'Enable', 'on');


% --- Executes on selection change in popupmenu_resolution.
function popupmenu_resolution_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu_resolution (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_resolution contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_resolution

global res_length

contents = cellstr(get(hObject, 'String'));
getVal = contents(get(hObject, 'Value'));
res_length = str2num(getVal{1});



% --- Executes during object creation, after setting all properties.
function popupmenu_resolution_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu_resolution (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% % --- Executes on button press in button_cancel.
% function button_cancel_Callback(hObject, eventdata, handles)
% % hObject    handle to button_cancel (see GCBO)
% % eventdata  reserved - to be defined in a future version of MATLAB
% % handles    structure with handles and user data (see GUIDATA)
% 
% global cancel
% 
% currentPicNum = get(handles.slider_pics, 'Value');
% question = sprintf('Cancel measurement process after No. %d?', currentPicNum);
% answer = questdlg(question, 'Cancel Measurement', 'Yes', 'No', 'Yes');
% % Handle response
% switch answer
%     case 'Yes'
%         cancel = 1;
%         set(hObject, 'Enable', 'off');
%     case 'No'
%         cancel = 0;
%     otherwise
%         cancel = 0;
% end
   


% --- Executes when selected object is changed in rb_getTimestamps.
function rb_getTimestamps_SelectionChangedFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in rb_getTimestamps 
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global rb_getTimestamps_state
global timeStampsFrame_flag
rb_getTimestamps_state = get(eventdata.NewValue, 'Tag');

switch get(get(handles.rb_getTimestamps,'SelectedObject'),'Tag')
    case 'rb_getTimestampsDisabled'
%         set(handles.button_Save, 'Enable', 'on');
    case 'rb_getTimestampsAutomatic'
        if timeStampsFrame_flag == 0
            set(handles.button_Save, 'Enable', 'off');
        end            
    otherwise
end


% --- Executes on button press in button_setFrameTimestamps.
function button_setFrameTimestamps_Callback(hObject, eventdata, handles)
% hObject    handle to button_setFrameTimestamps (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global posLength
global timestamps_roi_x
global timestamps_roi_y
global timestamps_roi_x_upperLeft
global timestamps_roi_y_upperLeft
global userArea_timestamps
global file
global timeStampsFrame_flag

timeStampsFrame_flag = 0;
set(handles.slider_pics, 'Enable', 'off');

axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
if ~isempty(userArea_timestamps)
    delete(userArea_timestamps);
end

userArea_timestamps = imrect();
rect_pos = userArea_timestamps.getPosition;

timestamps_roi_x_upperLeft = floor(rect_pos(1));
timestamps_roi_y_upperLeft = floor(rect_pos(2));
timestamps_roi_x = floor(rect_pos(3))+1;
timestamps_roi_y = floor(rect_pos(4))+1;

delete(userArea_timestamps);

updateImage(hObject, eventdata, handles);
if ~isempty(posLength)
    showRefLines(handles)
end

if iscell(file)
    set(handles.slider_pics, 'Enable', 'on');
else
    set(handles.slider_pics, 'Enable', 'off');
end

timeStampsFrame_flag = 1;


function plotRectTimestamps(handles)
    global timestamps_roi_x
    global timestamps_roi_y
    global timestamps_roi_x_upperLeft
    global timestamps_roi_y_upperLeft
    
    hold(handles.axes_showImage,'on');
    plot(handles.axes_showImage, [timestamps_roi_x_upperLeft timestamps_roi_x_upperLeft+timestamps_roi_x], ...
         [timestamps_roi_y_upperLeft timestamps_roi_y_upperLeft] , 'y--', 'LineWidth', 2);
    plot(handles.axes_showImage, [timestamps_roi_x_upperLeft timestamps_roi_x_upperLeft+timestamps_roi_x], ...
         [timestamps_roi_y_upperLeft+timestamps_roi_y timestamps_roi_y_upperLeft+timestamps_roi_y] , 'y--', 'LineWidth', 2);
    plot(handles.axes_showImage, [timestamps_roi_x_upperLeft timestamps_roi_x_upperLeft], ...
         [timestamps_roi_y_upperLeft timestamps_roi_y_upperLeft+timestamps_roi_y] , 'y--', 'LineWidth', 2);
    plot(handles.axes_showImage, [timestamps_roi_x_upperLeft+timestamps_roi_x timestamps_roi_x_upperLeft+timestamps_roi_x], ...
         [timestamps_roi_y_upperLeft timestamps_roi_y_upperLeft+timestamps_roi_y] , 'y--', 'LineWidth', 2);
    hold(handles.axes_showImage,'off');


% --- Executes on button press in button_saveSettings.
function button_saveSettings_Callback(hObject, eventdata, handles)
% hObject    handle to button_saveSettings (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global thres
global res_length
global refLineLengthMask
global refLineWidthMask
global posLength
global posWidth
global boundary_x
global boundary_y
global maskBoundary
global userAreaMask
global timestamps_roi_x
global timestamps_roi_y
global timestamps_roi_x_upperLeft
global timestamps_roi_y_upperLeft
global rb_unit_state
global showProgress 
global showGrid 

res_pixels = str2num(get(handles.edit_resolution_pixels, 'String'));
rb_getTimestamps = get(get(handles.rb_getTimestamps,'SelectedObject'),'Tag');


try [tmp_file, savepath] = uiputfile('*.mat');
    save([savepath tmp_file], 'thres', 'rb_getTimestamps', 'showProgress', 'showGrid', ...
                              'timestamps_roi_x', 'timestamps_roi_x_upperLeft', ...
                              'timestamps_roi_y', 'timestamps_roi_y_upperLeft', ...
                              'res_length', 'res_pixels', 'rb_unit_state', ...
                              'refLineLengthMask', 'refLineWidthMask', 'posLength', 'posWidth', ...
                              'boundary_x', 'boundary_y', 'userAreaMask', 'maskBoundary' ...
                          );
catch
    warndlg('Attention! Not saved!','Warning');
end



% --- Executes on button press in button_openSettings.
function button_openSettings_Callback(hObject, eventdata, handles)
% hObject    handle to button_openSettings (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global imageNoAct
global thres
global res_length
global refLineLengthMask
global refLineWidthMask
global posLength
global posWidth
global boundary_x
global boundary_y
global maskBoundary
global userAreaMask
global timestamps_roi_x
global timestamps_roi_y
global timestamps_roi_x_upperLeft
global timestamps_roi_y_upperLeft
global pL
global pW
global rb_unit_state
global showProgress 
global showGrid

try
    [tmp_file, openpath] = uigetfile('*.mat');

    thres = [];
    res_length = [];
    refLineLengthMask = [];
    refLineWidthMask = [];
    posLength = [];
    posWidth = [];
    boundary_x = [];
    boundary_y = [];
    maskBoundary = [];
    userAreaMask = [];
    timestamps_roi_x = [];
    timestamps_roi_y = [];
    timestamps_roi_x_upperLeft = [];
    timestamps_roi_y_upperLeft = [];
    pL = [];
    pW = [];
    rb_unit_state = [];
    rb_getTimestamps = [];
    showProgress = [];
    showGrid = 0;

    load([openpath, tmp_file]);    

    % Resolution
    set(handles.edit_resolution_pixels, 'String', num2str(res_pixels));
    
    contents = cellstr(get(handles.popupmenu_resolution, 'String'));
    for idx=1:length(contents)
       if strcmp(num2str(res_length), contents{idx})
           break
       end
    end
    set(handles.popupmenu_resolution, 'Value', idx);
    getVal = contents(get(handles.popupmenu_resolution, 'Value'));
    res_length = str2double(getVal{1});

    switch rb_unit_state
        case 'rb_unit_um'
            set(handles.rb_unit_um, 'Value', 1);
        case 'rb_unit_nm'
            set(handles.rb_unit_nm, 'Value', 1);
        case 'rb_unit_mm'
            set(handles.rb_unit_mm, 'Value', 1);
        otherwise
    end
    
    % show progress
    set(handles.cb_showProgress, 'Value', showProgress);
    % show grid
    set(handles.cb_showGrid, 'Value', showGrid);
    
    % Timestamps
    switch rb_getTimestamps
        case 'rb_getTimestampsDisabled'
            set(handles.rb_getTimestampsDisabled, 'Value', 1);
        case 'rb_getTimestampsAutomatic'
            set(handles.rb_getTimestampsAutomatic, 'Value', 1);
        otherwise
    end
    
    % Plots
    if ~isempty(userAreaMask)
        showArea_afterOpeningSettings(hObject, eventdata, handles)
        set(handles.button_chooseRefLines, 'Enable', 'on');
    end
    if ~isempty(posLength)
        showRefLines(handles)
        set(handles.button_getLengthWidth, 'Enable', 'on');
        set(handles.cb_showProgress, 'Enable', 'on');
    end

    % Buttons
    set(handles.button_Save, 'Enable', 'off');
    set(handles.text_length, 'String', '');
    set(handles.text_width, 'String', '');
    set(handles.text_min, 'String', '');
    set(handles.text_sec, 'String', '');
    set(handles.text_estMin, 'String', '');
    set(handles.text_estSec, 'String', '');

catch
    warndlg('Attention! Something went wrong, settings may not be loaded completely!','Warning');
end


% --- Executes on button press in cb_showProgress.
function cb_showProgress_Callback(hObject, eventdata, handles)
% hObject    handle to cb_showProgress (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of cb_showProgress
global showProgress

showProgress = get(hObject,'Value');


% --- Executes on button press in cb_showGrid.
function cb_showGrid_Callback(hObject, eventdata, handles)
% hObject    handle to cb_showGrid (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of cb_showGrid
global showGrid

showGrid = get(hObject,'Value');
enableDisable_grid(handles)


function enableDisable_grid(handles)
global showGrid
if showGrid == 1
    enable_grid(handles)
else
    disable_grid(handles)
end


function enable_grid(handles)

gridColor = [1 1 1];
gridAlpha = 0.5;

handles.axes_showImage.GridColor = gridColor;
handles.axes_showImage.GridAlpha = gridAlpha;
handles.axes_showImage.XGrid = 'on';
handles.axes_showImage.YGrid = 'on';

handles.axes_showArea.GridColor = gridColor;
handles.axes_showArea.GridAlpha = gridAlpha;
handles.axes_showArea.XGrid = 'on';
handles.axes_showArea.YGrid = 'on';

handles.axes_showEdgeDetection.GridColor = gridColor;
handles.axes_showEdgeDetection.GridAlpha = gridAlpha;
handles.axes_showEdgeDetection.XGrid = 'on';
handles.axes_showEdgeDetection.YGrid = 'on';

handles.axes_showHistogram.GridColor = gridColor;
handles.axes_showHistogram.GridAlpha = gridAlpha;
handles.axes_showHistogram.XGrid = 'on';
handles.axes_showHistogram.YGrid = 'on';




function disable_grid(handles)

handles.axes_showImage.XGrid = 'off';
handles.axes_showImage.YGrid = 'off';

handles.axes_showArea.XGrid = 'off';
handles.axes_showArea.YGrid = 'off';

handles.axes_showEdgeDetection.XGrid = 'off';
handles.axes_showEdgeDetection.YGrid = 'off';

handles.axes_showHistogram.XGrid = 'off';
handles.axes_showHistogram.YGrid = 'off';


% --- Executes on button press in button_openFolder.
function button_openFolder_Callback(hObject, eventdata, handles)
% hObject    handle to button_openFolder (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global userLine
global userArea
global userArea_timestamps
global file
global boundary_x
global boundary_y
global filename
global path
global posWidth
global posLength
global pL
global pW
global timestamps_roi_x
global timestamps_roi_y
global timestamps_roi_x_upperLeft
global timestamps_roi_y_upperLeft
global maskBoundary
global refLineLengthMask
global refLineWidthMask
global userAreaMask
global thres
global thres_init

global fps
global fps_no
global picName_folder

filename_old = filename;
filename = [];
picName_folder_old = picName_folder;
picName_folder = [];

try

    try
        path = uigetdir();

        f = waitbar(0,'Loading','Name','Opening data...', ...
            'windowstyle', 'modal');
                
        filesOrFolders = dir(path);

        for k = 3:length(filesOrFolders)
            filesOrFolderNames{k-2} = [path '\' getfield(filesOrFolders, {k,1}, 'name')];
        end
        
        filesOrFolderNames = filesOrFolderNames';
        picPathname{1} = '';
        
        if isfolder(filesOrFolderNames{1})
            folders = filesOrFolderNames;
            fps = [];
            fps_no = [];
            for k = 1:length(folders)
                info = importdata([folders{k} '\framerate.txt']);
                fps(k) = info.data(5);
                fps_no(k) = info.data(1);

                tmp = dir([folders{k} '\*.png']);
                for j = 1:length(tmp)
                    picPathname{end+1} = [folders{k} '\' getfield(tmp, {j,1}, 'name')];
                end
            end
            
            picPathname = picPathname';
            picPathname(1) = [];
            
            for j = 1:length(picPathname)
                tmp = strsplit(picPathname{j}, '\');
                picName_folder{j} = [tmp{end-1} '_' tmp{end}];
                tmp = strsplit(picName_folder{j}, '.');
                picName_folder{j} = tmp{end-1};
            end
            picName_folder = picName_folder';
     
         else
            info = importdata([path '\framerate.txt']);
            fps(1) = info.data(5);
            fps_no(1) = info.data(1);
        
            tmp = dir([path '\*.png']);
            for j = 1:length(tmp)
                picPathname{end+1} = [getfield(tmp, {j,1}, 'name')];
            end
            
            picPathname = picPathname';
            picPathname(1) = [];
            picName_folder = picPathname;
            
            for j = 1:length(picName_folder)
                tmp = strsplit(picName_folder{j}, '.');
                picName_folder{j} = tmp{end-1};
            end
            
            for j = 1:length(picPathname)
                picPathname{j} = [path '\' picPathname{j}];
            end
        end
        
        newDataFlag = 1;

    catch
        newDataFlag = 0;
        if exist('f')
            delete(f)
        end
    end
    
       
    if newDataFlag == 1
        file = [];
        boundary_x = [];
        boundary_y = [];
        posLength = [];
        posWidth = [];
        pL = [];
        pW = [];
        timestamps_roi_x = [];
        timestamps_roi_y = [];
        timestamps_roi_x_upperLeft = [];
        timestamps_roi_y_upperLeft = [];
        maskBoundary = [];
        refLineLengthMask = [];
        refLineWidthMask = [];
        userAreaMask = [];
        
        axes(handles.axes_showImage);            % Auswahl des entsprechenden Axes-Objekts
        cla;
        hold(handles.axes_showImage,'off');
        if ~isempty(userLine)
            delete(userLine);
        end
        if ~isempty(userArea)
            delete(userArea);
        end
        if ~isempty(userArea_timestamps)
            delete(userArea_timestamps);
        end

        axes(handles.axes_showArea);
        cla;
        hold(handles.axes_showArea,'off');
        axes(handles.axes_showEdgeDetection);
        cla;
        hold(handles.axes_showEdgeDetection,'off');
        axes(handles.axes_showHistogram);
        cla;
        hold(handles.axes_showHistogram,'off');
        axes(handles.axes_showCurve);
        cla;
        hold(handles.axes_showCurve,'off');


        for i=1:length(picPathname)
            % Update waitbar and message
            waitbar(i/length(picPathname),f,sprintf('Picture %i of %i', i, length(picPathname)))

            file{i} = imread(picPathname{i});
            if length(size(file{i})) == 3
                tmpfile = file{i}(:,:,1);
                file{i} = tmpfile;
            end
        end
        
        showImage(handles, file{1});
        set(handles.slider_pics, 'Min', 1, 'Max', length(file), 'SliderStep', [1/(length(file)-1), 2/(length(file)-1)], 'Value', 1, 'Enable', 'on');
        
        
        thres = thres_init;
        set(handles.slider_threshold, 'Value', thres_init, 'Enable', 'off');
        set(handles.text_threshold, 'String', get(handles.slider_threshold, 'Value'));
        
        showImageNo(handles, 1);
        guidata(hObject,handles);
        set(handles.button_chooseArea, 'Enable', 'on');

        set(handles.button_setArea, 'Enable', 'off');
        set(handles.button_chooseRefLines, 'Enable', 'off');
        set(handles.button_setRefLines, 'Enable', 'off');
        set(handles.button_getLengthWidth, 'Enable', 'off');
        set(handles.cb_showProgress, 'Enable', 'off');
        set(handles.cb_showGrid, 'Enable', 'on');
        set(handles.button_Save, 'Enable', 'off');
        set(handles.button_SaveInt, 'Enable', 'off');
        set(handles.button_SaveInt, 'Enable', 'off');
        set(handles.button_manualCorrectionLength, 'Enable', 'off');
        set(handles.button_manualCorrectionWidth, 'Enable', 'off');
        set(handles.button_openSettings, 'Enable', 'on');
        set(handles.button_saveSettings, 'Enable', 'on');
        set(findall(handles.rb_getTimestamps, '-property', 'enable'), 'enable', 'on');
        set(findall(handles.eg_timestamps_roi, '-property', 'enable'), 'enable', 'on');
        
        set(handles.text_min, 'String', '');
        set(handles.text_sec, 'String', '');
        set(handles.text_length, 'String', '');
        set(handles.text_width, 'String', '');
    
        delete(f)
        
    else
        filename = filename_old;
        picName_folder = picName_folder_old;
        if exist('f')
            delete(f)
        end
        warndlg('No files uploaded!','Warning');
    end

catch
    if exist('f')
        delete(f)
    end
    set(handles.button_chooseArea, 'Enable', 'off');
    warndlg('No files uploaded!','Warning');
end

% --- Executes on button press in button_SaveInt.
function button_SaveInt_Callback(hObject, eventdata, handles)
% hObject    handle to button_SaveInt (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global path
global file
global filename
global lengthSaved
global widthSaved
%global intensitySaved
global suspected_length_of_timestamp
global errorCount
global txt_confidence
global minConfidenceValue

global fps_no
global picName_folder
global imageNoAct
global meanGL

opts = struct('WindowStyle','modal',... 
              'Interpreter','tex');
errorCount = [];
errorCount(1) = 0;

Intensity = meanGL;
Length = lengthSaved;
Width = widthSaved';

%showArea(handles, pic)



if iscell(file)
    if isempty(filename)
        numberOfFiles = length(picName_folder);
        Picture = picName_folder;
    else
        numberOfFiles = length(filename);
        Picture = filename';
        tryPic = [path filename{1}];
    end
else
    numberOfFiles = 1;
    Picture{1} = filename;
    tryPic = [path Picture{1}];
    
end


%meanGL = length(Length);

%meanGL = mean2(file{imageNoAct});

%Intensity = meanGL;

%imageNoAct = round(get(handles.slider_pics, 'Value'));
%showImageNo(handles, imageNoAct);

%if iscell(file)
    %imageNoMax = length(file);
    %pic = file{imageNoAct};
%else
    %pic = file;
%end

%showHisto(handles, pic);

%meanGL = mean2(file{imageNoAct});
%meanGL = mean2(pic);
%set(handles.text_intensity, 'String', meanGL);

%Intensity = meanGL;




switch get(get(handles.rb_getTimestamps,'SelectedObject'),'Tag')
    case 'rb_getTimestampsDisabled'

        if length(Length) < length(Picture)
            Length(end+1:length(Picture)) = NaN;
            Width(end+1:length(Picture)) = NaN;
            Intensity(end+1:length(Picture)) = NaN;
        end
        saveData = table(Picture, Width, Length, Intensity');
        saveNoTime = 1;
        
    case 'rb_getTimestampsAutomatic'
        % Zeitstempel lesen
        saveNoTime = 0;
        timestampInData_flag = 0;
        timestampInPic_flag = 0;
        timestampInFile_flag = 0;
        
        try [tryName tryTimestamp] = getTimeStamp(tryPic);
            timestampInData_flag = 1;
        catch
            
            try [tryName tryTimestamp] = getTimeStamp_fps(1, 0);
                timestampInFile_flag = 1;
            catch
            
                try [tryName, data] = getTimeStamp_OCR(1);
                    tryTimestamp = data{1};
                    check = length(tryTimestamp) == suspected_length_of_timestamp && txt_confidence > minConfidenceValue;
                    if check  ~= 1
                        answer = questdlg('Attention! Timestamps might not be read correctly...', ...
                            'Proceed anyway?', ...
                            'proceed', 'proceed w/o timestamps', 'cancel', 'proceed');
                        switch answer
                            case 'proceed'
                                timestampInPic_flag = 1;
                            case 'proceed w/o timestamps'
                                timestampInPic_flag = 0;
                                saveNoTime = 1;
                            case 'cancel'
                                timestampInPic_flag = 0;
                            otherwise
                                timestampInPic_flag = 0;
                        end
                    else
                        timestampInPic_flag = 1;
                    end
                catch
                    answer = questdlg('Timestamps not readable - Save without timestamps?', ...
                        'Proceed saving?', ...
                        'save', 'cancel', 'save');
                    switch answer
                        case 'save'
                            saveNoTime = 1;
                        otherwise
                    end
                end
            end
        end
        
        if saveNoTime == 1
            saveData = table(Picture, Length, Width, Intensity');
        else
            if timestampInData_flag == 1 || timestampInPic_flag == 1 || timestampInFile_flag == 1
    
                if timestampInFile_flag == 1
                    if length(fps_no) >= 1
                        check = 0;
                        while check == 0
                            prompt = {'You chose at least two sessions. Please enter loop intervall > 0 seconds (e.g. session start every 5 min means 300 seconds):'};
                            dlgtitle = 'Input';
                            dims = [1];
                            definput = {'300'};
                            pause = inputdlg(prompt,dlgtitle,dims,definput);
                            if isempty(pause)
                                check = 0;
                            elseif isempty(str2num(pause{1}))
                                check = 0;
                            else
                                check = 1;
                                pause = str2num(pause{1});
                            end
                        end
                    end 
                end
                
                f = waitbar(0,'1','Name','Saving progress',...
                    'CreateCancelBtn','setappdata(gcbf,''canceling'',1)');
                setappdata(f,'canceling',0);
                
                for i=1:numberOfFiles
                   % Update waitbar and message
                    waitbar(i/numberOfFiles,f,sprintf('Image %i of %i', i, numberOfFiles))
                   % Check for clicked Cancel button
                    if getappdata(f,'canceling')
                        break
                    end
                    if iscell(file)
                        if ~isempty(filename)
                            tmp_file = [path filename{i}];
                        end
                    else
                        tmp_file = [path filename];
                    end
                    if timestampInData_flag == 1
                        [fname{i}, fTimestamp{i}] = getTimeStamp(tmp_file);
                    elseif timestampInFile_flag == 1
                        [fname{i}, fTimestamp{i}] = getTimeStamp_fps(i, pause);
                    elseif timestampInPic_flag == 1
                        [fname{i}, fTimestampData{i}] = getTimeStamp_OCR(i);
                        fTimestamp{i} = fTimestampData{i}{1};
                        check = length(fTimestamp{i}) == suspected_length_of_timestamp && txt_confidence > minConfidenceValue;
                        if check~= 1
                          % uiwait(warndlg(sprintf('Attention! Timestamp might not be read correctly at image no. %i !', i),'Warning'));
                          % warndlg(sprintf('Attention! Timestamp might not be read correctly at image no. %i !', i),'Warning');
                            errorCount(1) = errorCount(1) +1;
                            errorCount(end+1) = i;
                            if errorCount(1) == 1 
                                warndlg(sprintf('Attention! There is %i WARNING!\nTimestamp might not be read correctly at image no. %i !', ...
                                    errorCount(1), errorCount(2)), 'Warning', opts);
                            else
                                str = ['Attention! There are %i WARNINGS!\nTimestamp might not be read correctly at image no. ', repmat('%g, ', 1, numel(errorCount(2:end))-1), '%g !'];
                                warndlg(sprintf(str, errorCount(1), errorCount(2:end)), 'Warning', opts);
                            end                            
                        end
                    end
                end
                delete(f)

                if length(Length) < length(Picture)
                    Length(end+1:length(Picture)) = NaN;
                end
                if length(Width) < length(Picture)
                    Width(end+1:length(Picture)) = NaN;
                end
                if length(Intensity) < length(Picture)
                    Intensity(end+1:length(Picture)) = NaN;
                end
                if length(fTimestamp) < length(Picture)
                    for i=length(fTimestamp):length(Picture)
                        fTimestamp{i} = 'NaN';
                    end
                end
                
                %Intensity = meanGL;
                %Intensity = length(numberOfFiles);
                Timestamp = fTimestamp';
                saveData = table(Picture, Timestamp, Intensity'); 
                clear Timestamp fTimestamp
            end
        end
    otherwise
end

        
if saveNoTime == 1 || timestampInData_flag == 1 || timestampInPic_flag == 1 || timestampInFile_flag == 1
    try [tmp_file, savepath] = uiputfile('*.xlsx');
        writetable(saveData, [savepath tmp_file]);
    catch
        warndlg('Attention! Not saved!','Warning');
    end

    
    
end
