function [seedinfo,outstate] = ncorr_gui_seedpreview(reference,current,roi,num_region,pos_seed,radius,cutoff_diffnorm,cutoff_iteration,enabled_stepanalysis,subsettrunc,num_img,total_imgs,pos_parent)
% This is a GUI for displaying the seeds before accepting them. Its
% possible the seeds are not correct or do not converge, so I included this
% utility as a check.
%
% Inputs -----------------------------------------------------------------%
%   reference - ncorr_class_img; used for displaying the background
%   image and calculations
%   current -  ncorr_class_img(s); used for displaying the background
%   image and calculations
%   roi - ncorr_class_roi; ROI corresponding to the reference image
%   num_region - integer; number corresponding to the region
%   pos_seed - integer array; 1st column is the x-position of the seed; 2nd
%   is the y-position. Each row corresponds to a thread in ascending order
%   (i.e. the first row is the first thread).
%   radius - integer; radius of subset
%   cutoff_diffnorm - double; cutoff of norm of the difference vector
%   cutoff_iteration - integer; cutoff for number of iterations
%   enabled_stepanalysis - logical; if true, then process as many seeds as
%   possible. If false, process all the seeds.
%   subsettrunc - logical; if true, then enable subset truncation
%   num_img - integer; number of reference image being analyzed
%   total_imgs - integer; total number of images being analyzed
%   pos_parent - integer array; this is the position of the parent figure
%   which determines where to position this figure
%
% Outputs ----------------------------------------------------------------%
%   seedinfo - struct; contains struct('paramvector',{},'num_region',{},'num_thread',{},'computepoints',{}) 
%   which is information on the location of the seed, the deformation 
%   parameters for that seed, the region number, and the thread assigned for 
%   computation.
%   outstate - integer; returns either out.cancelled, out.failed, or
%   out.success.
%
% Note that if step analysis is enabled, outstate will return success if at
% least one image is seeded. If no seeds are found, it will return failed.
% However, if step analysis is disabled, outstate will return success only 
% if all images are seeded correctly, or else it will return failed.
    
    % Data ---------------------------------------------------------------%
    % Initialize Outputs 
    outstate = out.cancelled;
    seedinfo = struct('paramvector',{},'num_region',{},'num_thread',{},'computepoints',{}); % paramvector = [x y u v du/dx du/dy dv/dx dv/dy corrcoef]
    % Get GUI handles
    handles_gui = init_gui();
    % Run c-tor
    feval(ncorr_util_wrapcallbacktrycatch(@constructor,handles_gui.figure));
    
    % Callbacks ----------------------------------------------------------%      
    function constructor()        
        % Calculate seeds. ncorr_alg_seedanalysis will return failed if no
        % images are seeded correctly in the case that step analysis is
        % enabled. If step analysis is disabled, it will return failed if
        % any of the seeds are processed incorrectly.
        [seedinfo_prelim,convergence_prelim,outstate_seeds] = ncorr_alg_seedanalysis(reference, ...
                                                                                     current, ...
                                                                                     roi, ...
                                                                                     num_region, ...
                                                                                     pos_seed, ...
                                                                                     radius, ...
                                                                                     cutoff_diffnorm, ...
                                                                                     cutoff_iteration, ...
                                                                                     enabled_stepanalysis, ...
                                                                                     subsettrunc, ...
                                                                                     num_img, ...
                                                                                     total_imgs);      
        
        if (outstate_seeds == out.success)
            % NOTE: Seeds are ordered in seedinfo_prelim WRT to thread 
            % number when processed by ncorr_alg_seedanalysis (i.e. 
            % seedinfo_prelim(i) == thread number i), so this isnt 
            % explicitly checked when displaying subsets corresponding 
            % to different threads.

            % Check to see if any seeds have a relatively high
            % correlation coefficient and warn the user about it.
            paramvectorcollection = vertcat(seedinfo_prelim.paramvector); % The ninth column is the correlation coefficients
            if (any(paramvectorcollection(:,9) > 0.4))
                h_error = errordlg('High correlation coefficient detected. One of the seed points is possibly incorrect. Proceed with caution.','Error','modal');
                uiwait(h_error);
            end

            % Precompute cirrois
            cirrois = struct('mask',{},'region',{},'boundary',{},'x',{},'y',{},'radius',{});
            for i = 0:size(pos_seed,1)-1
                cirrois(i+1) = roi.get_cirroi(pos_seed(i+1,1),pos_seed(i+1,2),radius,subsettrunc);   
            end   

            % Precompute the subsets, so they do not need to be
            % recalculated when switching between images/threads.
            % Initialize
            preview_subsets_ref = zeros(cirrois(1).radius*2+1,cirrois(1).radius*2+1,length(cirrois));
            preview_subsets_cur = zeros(cirrois(1).radius*2+1,cirrois(1).radius*2+1,length(cirrois),size(seedinfo_prelim,3));

            % Interpolate
            gs_buffer_ref = reference.get_gs();
            for i = 0:size(seedinfo_prelim,3)-1
                % Getting bcoefficients could be time consuming if a
                % lot of high resolution images are being processed.
                bcoef_buffer_cur = current(i+1).get_bcoef();
                for j = 0:size(seedinfo_prelim,1)-1                    
                    for k = 0:size(cirrois(j+1).region.noderange,1)-1
                        x_ref = k+(cirrois(j+1).x-cirrois(j+1).radius);
                        for l = 0:2:cirrois(j+1).region.noderange(k+1)-1
                            % Transform x_ref and y_ref and then
                            % interpolate
                            vec_y_ref = (cirrois(j+1).region.nodelist(k+1,l+1):cirrois(j+1).region.nodelist(k+1,l+2))';
                            vec_x_ref = repmat(x_ref,length(vec_y_ref),1);

                            % Fill reference subset - only do this once
                            if (i == 0)
                                preview_subsets_ref(vec_y_ref-(cirrois(j+1).y-cirrois(j+1).radius)+1,k+1,j+1) = gs_buffer_ref(vec_y_ref+1,x_ref+1);
                            end

                            % Transform ref coordinates
                            vec_x_cur = vec_x_ref + seedinfo_prelim(j+1,1,i+1).paramvector(3) + seedinfo_prelim(j+1,1,i+1).paramvector(5)*(vec_x_ref-cirrois(j+1).x) + seedinfo_prelim(j+1,1,i+1).paramvector(6)*(vec_y_ref-cirrois(j+1).y);
                            vec_y_cur = vec_y_ref + seedinfo_prelim(j+1,1,i+1).paramvector(4) + seedinfo_prelim(j+1,1,i+1).paramvector(7)*(vec_x_ref-cirrois(j+1).x) + seedinfo_prelim(j+1,1,i+1).paramvector(8)*(vec_y_ref-cirrois(j+1).y); 

                            % Interpolate
                            vec_interp_cur = ncorr_alg_interpqbs([vec_x_cur vec_y_cur],bcoef_buffer_cur,0,0,current(i+1).border_bcoef);

                            % Note that any values interpolated out of 
                            % the range of the bcoefficient matrix in 
                            % ncorr_alg_interpqbs is set to NaN. 
                            % Set these NaNs to zero for display
                            % purposes.
                            vec_interp_cur(isnan(vec_interp_cur)) = 0;

                            % Fill current subset
                            preview_subsets_cur(vec_y_ref-cirrois(j+1).y+cirrois(j+1).radius+1,k+1,j+1,i+1) = vec_interp_cur;
                        end
                    end
                end
            end

            % Set Data            
            setappdata(handles_gui.figure,'cirrois',cirrois);
            setappdata(handles_gui.figure,'num_cur',size(seedinfo_prelim,3)-1);
            setappdata(handles_gui.figure,'num_thread',size(pos_seed,1)-1);
            setappdata(handles_gui.figure,'preview_subsets_ref',preview_subsets_ref);
            setappdata(handles_gui.figure,'preview_subsets_cur',preview_subsets_cur);
            setappdata(handles_gui.figure,'seedinfo_prelim',seedinfo_prelim);
            setappdata(handles_gui.figure,'convergence_prelim',convergence_prelim);

            % Update
            update_axes('set');

            % Set Visible
            set(handles_gui.figure,'Visible','on'); 
        elseif (outstate_seeds == out.failed)
            h_error = errordlg('Seed placement failed; please replace seeds.','Error','modal');
            uiwait(h_error);

            outstate = out.failed;
                
            % Exit
            close(handles_gui.figure);
        else
            % Analysis was cancelled - exit.
            close(handles_gui.figure);
        end
    end
    
    function callback_edit_threadnum(hObject,eventdata) %#ok<INUSD>
        % Get data
        num_thread = getappdata(handles_gui.figure,'num_thread');  
        
        num_thread_prelim = str2double(get(handles_gui.edit_threadnum,'string'));
        if (ncorr_util_isintbb(num_thread_prelim,1,size(pos_seed,1),'Thread number') == out.success)    
            num_thread = num_thread_prelim-1;
        end      
        
        % Set data
        setappdata(handles_gui.figure,'num_thread',num_thread);
        
        % Update
        update_axes('set');
    end

    function callback_edit_imgnum(hObject,eventdata) %#ok<INUSD>
        % Get data
        num_cur = getappdata(handles_gui.figure,'num_cur');  
        seedinfo_prelim = getappdata(handles_gui.figure,'seedinfo_prelim');
        
        num_cur_prelim = str2double(get(handles_gui.edit_imgnum,'string')); 
        if (ncorr_util_isintbb(num_cur_prelim,1,size(seedinfo_prelim,3),'Current image number') == out.success)    
            num_cur = num_cur_prelim-1;
        end     
        
        % Set data
        setappdata(handles_gui.figure,'num_cur',num_cur);
        
        % Update
        update_axes('set');
    end

    function callback_button_finish(hObject,eventdata) %#ok<INUSD>
        % Get data
        seedinfo_prelim = getappdata(handles_gui.figure,'seedinfo_prelim');
        
        % Set output
        for i = 0:size(seedinfo_prelim,3)-1
            for j = 0:size(seedinfo_prelim,1)-1
                seedinfo(j+1,1,i+1) = seedinfo_prelim(j+1,1,i+1);
            end
        end
        outstate = out.success;              
        
        % Exit        
        close(handles_gui.figure);
    end

    function callback_button_cancel(hObject,eventdata) %#ok<INUSD>
        close(handles_gui.figure);
    end  

    function callback_button_left_thread(hObject,eventdata) %#ok<INUSD>
        % Get data
        num_thread = getappdata(handles_gui.figure,'num_thread');
        
        % Check for overshoot
        if (num_thread > 0) 
            num_thread = num_thread-1;
        end    
        
        % Set data
        setappdata(handles_gui.figure,'num_thread',num_thread); 
            
        % Update
        update_axes('set');
    end

    function callback_button_right_thread(hObject,eventdata) %#ok<INUSD>
        % Get data
        num_thread = getappdata(handles_gui.figure,'num_thread');  
        
        % Check for overshoot
        if (num_thread < size(pos_seed,1)-1)            
            num_thread = num_thread+1;
        end      
        
        % Set data
        setappdata(handles_gui.figure,'num_thread',num_thread);
        
        % Update
        update_axes('set');
    end

    function callback_button_left_cur(hObject,eventdata) %#ok<INUSD>
        % Get data        
        num_cur = getappdata(handles_gui.figure,'num_cur');
        
        % Check for overshoot
        if (num_cur > 0)
            num_cur = num_cur-1;
        end    
                        
        % Set data
        setappdata(handles_gui.figure,'num_cur',num_cur); 
            
        % Update
        update_axes('set');
    end

    function callback_button_right_cur(hObject,eventdata) %#ok<INUSD>
        % Get data
        num_cur = getappdata(handles_gui.figure,'num_cur');  
        seedinfo_prelim = getappdata(handles_gui.figure,'seedinfo_prelim');
        
        % Check for overshoot
        if (num_cur < size(seedinfo_prelim,3)-1)      
            num_cur = num_cur+1;
        end     
        
        % Set data
        setappdata(handles_gui.figure,'num_cur',num_cur);
        
        % Update
        update_axes('set');
    end

    function update_axes(action)
        % Get data
        num_cur = getappdata(handles_gui.figure,'num_cur');
        num_thread = getappdata(handles_gui.figure,'num_thread');
        preview_subsets_ref = getappdata(handles_gui.figure,'preview_subsets_ref');
        preview_subsets_cur = getappdata(handles_gui.figure,'preview_subsets_cur');
        cirrois = getappdata(handles_gui.figure,'cirrois');
        seedinfo_prelim = getappdata(handles_gui.figure,'seedinfo_prelim');
        convergence_prelim = getappdata(handles_gui.figure,'convergence_prelim');
        
        if (strcmp(action,'set'))
            gs_buffer_ref = reference.get_gs();
            gs_buffer_cur = current(num_cur+1).get_gs();
                    
            % Paint reference subset and subset locations     
            preview_subsetloc_ref = gs_buffer_ref;        
            preview_subsetloc_cur = gs_buffer_cur;         

            % Iterate over num_thread last so that it highlights this
            % subset over the others
            for i = [0:num_thread-1 num_thread+1:size(pos_seed,1)-1 num_thread]
                for j = 0:size(cirrois(i+1).region.noderange,1)-1
                    x_ref = j+(cirrois(i+1).x-cirrois(i+1).radius);
                    for k = 0:2:cirrois(i+1).region.noderange(j+1)-1
                        for l = cirrois(i+1).region.nodelist(j+1,k+1):cirrois(i+1).region.nodelist(j+1,k+2)
                            y_ref = l;   

                            % Fill subset locations
                            if (i == num_thread)
                                % User brighter highlight to indicate this is
                                % the seed corresponding to the current
                                % threads
                                preview_subsetloc_ref(y_ref+1,x_ref+1) = gs_buffer_ref(y_ref+1,x_ref+1)+1.75*reference.max_gs;
                            else
                                % Do regular highlight
                                preview_subsetloc_ref(y_ref+1,x_ref+1) = gs_buffer_ref(y_ref+1,x_ref+1)+reference.max_gs;
                            end

                            % defvector_init(1) = u 
                            % defvector_init(2) = v 
                            % defvector_init(3) = du_dx 
                            % defvector_init(4) = du_dy 
                            % defvector_init(5) = dv_dx 
                            % defvector_init(6) = dv_dy
                            % y_cur = y_ref + v + dv/dx*deltax + dv/dy*deltay  
                            % x_cur = x_ref + u + du/dx*deltax + du/dy*deltay

                            x_cur = x_ref + seedinfo_prelim(i+1,1,num_cur+1).paramvector(3) + seedinfo_prelim(i+1,1,num_cur+1).paramvector(5)*(x_ref-cirrois(i+1).x) + seedinfo_prelim(i+1,1,num_cur+1).paramvector(6)*(y_ref-cirrois(i+1).y);
                            y_cur = y_ref + seedinfo_prelim(i+1,1,num_cur+1).paramvector(4) + seedinfo_prelim(i+1,1,num_cur+1).paramvector(7)*(x_ref-cirrois(i+1).x) + seedinfo_prelim(i+1,1,num_cur+1).paramvector(8)*(y_ref-cirrois(i+1).y); 

                            % x_cur and y_cur could be out of bounds, check
                            % before using them
                            if (floor(x_cur) >= 0 && floor(y_cur) >= 0 && ceil(x_cur) < size(gs_buffer_cur,2) && ceil(y_cur) < size(gs_buffer_cur,1))
                                % Fill subset locations. This is a crude
                                % approximation of the current subset. Use both
                                % floor and ceil of transformed locations to 
                                % highlight the area of the current subset.
                                if (i == num_thread)
                                    % User brighter highlight to indicate this is
                                    % the seed corresponding to the thread of
                                    % interest
                                    preview_subsetloc_cur(floor(y_cur)+1,floor(x_cur)+1) = gs_buffer_cur(floor(y_cur)+1,floor(x_cur)+1)+1.75*current(num_cur+1).max_gs;  
                                    preview_subsetloc_cur(ceil(y_cur)+1,ceil(x_cur)+1) = gs_buffer_cur(ceil(y_cur)+1,ceil(x_cur)+1)+1.75*current(num_cur+1).max_gs; 
                                else
                                    % Do regular highlight
                                    preview_subsetloc_cur(floor(y_cur)+1,floor(x_cur)+1) = gs_buffer_cur(floor(y_cur)+1,floor(x_cur)+1)+current(num_cur+1).max_gs;  
                                    preview_subsetloc_cur(ceil(y_cur)+1,ceil(x_cur)+1) = gs_buffer_cur(ceil(y_cur)+1,ceil(x_cur)+1)+current(num_cur+1).max_gs; 
                                end
                            end
                        end
                    end
                end
            end

            % Set Images
            imshow(preview_subsets_ref(:,:,num_thread+1),[reference.min_gs reference.max_gs],'Parent',handles_gui.axes_refsubset);
            set(handles_gui.axes_refsubset,'Visible','off');
            imshow(preview_subsetloc_ref,[reference.min_gs 2*reference.max_gs],'Parent',handles_gui.axes_refsubsetloc);
            set(handles_gui.axes_refsubsetloc,'Visible','off');

            imshow(preview_subsets_cur(:,:,num_thread+1,num_cur+1),[current(num_cur+1).min_gs current(num_cur+1).max_gs],'Parent',handles_gui.axes_cursubset);
            set(handles_gui.axes_cursubset,'Visible','off');
            imshow(preview_subsetloc_cur,[current(num_cur+1).min_gs 2*current(num_cur+1).max_gs],'Parent',handles_gui.axes_cursubsetloc);
            set(handles_gui.axes_cursubsetloc,'Visible','off');

            % Set Texts
            if (convergence_prelim(num_thread+1,1,num_cur+1).num_iterations < cutoff_iteration)
                set(handles_gui.text_num_iterations_num,'String',num2str(convergence_prelim(num_thread+1,1,num_cur+1).num_iterations,'%6.0f'),'ForegroundColor', 'k');  
            else
                set(handles_gui.text_num_iterations_num,'String',[num2str(convergence_prelim(num_thread+1,1,num_cur+1).num_iterations,'%6.0f') ' (Max)' ],'ForegroundColor', 'r');  
            end            
            set(handles_gui.text_gradnorm_num,'String',num2str(convergence_prelim(num_thread+1,1,num_cur+1).diffnorm));
            set(handles_gui.text_corrcoef_num,'String',num2str(seedinfo_prelim(num_thread+1,1,num_cur+1).paramvector(9)));
            set(handles_gui.text_thread,'String', ['Thread: ' num2str(num_thread+1)]);     
            set(handles_gui.text_cur,'String', ['Name: ' current(num_cur+1).name(1:min(end,22))]); 
            set(handles_gui.text_ref,'String', ['Name: ' reference.name(1:min(end,22))]); 
            
            % Set buttons
            % Set left/right buttons for current image
            set(handles_gui.edit_imgnum,'String',num2str(num_cur+1));
            if (size(seedinfo_prelim,3) == 1)
                set(handles_gui.button_right_cur,'Enable','off');
                set(handles_gui.button_left_cur,'Enable','off');
                set(handles_gui.edit_imgnum,'Enable','off');
            elseif (num_cur == 0)
                set(handles_gui.button_right_cur,'Enable','on');
                set(handles_gui.button_left_cur,'Enable','off');
                set(handles_gui.edit_imgnum,'Enable','on');
            elseif (num_cur == size(seedinfo_prelim,3)-1)
                set(handles_gui.button_right_cur,'Enable','off');
                set(handles_gui.button_left_cur,'Enable','on');
                set(handles_gui.edit_imgnum,'Enable','on');
            else
                set(handles_gui.button_right_cur,'Enable','on');
                set(handles_gui.button_left_cur,'Enable','on'); 
                set(handles_gui.edit_imgnum,'Enable','on');                                                                       
            end
            
            % Set left/right buttons for thread number
            set(handles_gui.edit_threadnum,'String',num2str(num_thread+1));
            if (size(pos_seed,1) == 1)
                set(handles_gui.button_right_thread,'Enable','off');
                set(handles_gui.button_left_thread,'Enable','off');
                set(handles_gui.edit_threadnum,'Enable','off');
            elseif (num_thread == 0)
                set(handles_gui.button_right_thread,'Enable','on');
                set(handles_gui.button_left_thread,'Enable','off');
                set(handles_gui.edit_threadnum,'Enable','on');
            elseif (num_thread == size(pos_seed,1)-1)
                set(handles_gui.button_right_thread,'Enable','off');
                set(handles_gui.button_left_thread,'Enable','on');
                set(handles_gui.edit_threadnum,'Enable','on');
            else
                set(handles_gui.button_right_thread,'Enable','on');
                set(handles_gui.button_left_thread,'Enable','on');   
                set(handles_gui.edit_threadnum,'Enable','on');                                                                     
            end
        end 
    end

    function handles_gui = init_gui()
    % GUI controls -------------------------------------------------------%
        % Figure
        handles_gui.figure = figure( ...
            'Tag', 'figure', ...
            'Units', 'characters', ...
            'Position', ncorr_util_figpos(pos_parent,[56.1 167]), ...
            'Name', 'Seed Preview', ...
            'MenuBar', 'none', ...
            'NumberTitle', 'off', ...
            'Color', get(0,'DefaultUicontrolBackgroundColor'), ...
            'handlevisibility','off', ...
            'DockControls','off', ...
            'WindowStyle','modal', ...
            'Resize','off', ...
            'Visible','off', ...
            'IntegerHandle','off', ...
            'Interruptible','off');

        % Panels        
        handles_gui.group_menu = uibuttongroup( ...
            'Parent', handles_gui.figure, ...
            'Tag', 'group_menu', ...
            'Units', 'characters', ...
            'Position', [2 48.7 35 6.7], ...
            'Title', 'Menu', ...
            'Interruptible','off');

        handles_gui.group_ref = uibuttongroup( ...
            'Parent', handles_gui.figure, ...
            'Tag', 'group_reference', ...
            'Units', 'characters', ...
            'Position', [39.0 0.75 62 54.6], ...
            'Title', 'Reference', ...
            'Interruptible','off');

        handles_gui.group_cur = uibuttongroup( ...
            'Parent', handles_gui.figure, ...
            'Tag', 'group_current', ...
            'Units', 'characters', ...
            'Position', [103 0.75 62 54.6], ...
            'Title', 'Current', ...
            'Interruptible','off');

        % Axes
        handles_gui.axes_refsubsetloc = axes( ...
            'Parent', handles_gui.group_ref, ...
            'Tag', 'axes_refsubsetloc', ...
            'Units', 'characters', ...
            'Visible', 'off', ...
            'Position', [2.1 35.7 56.5 17], ...
            'Interruptible','off');

        handles_gui.axes_cursubsetloc = axes( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'axes_cursubsetloc', ...
            'Units', 'characters', ...
            'Visible', 'off', ...
            'Position', [2.1 35.7 56.5 17], ...
            'Interruptible','off');

        handles_gui.axes_refsubset = axes( ...
            'Parent', handles_gui.group_ref, ...
            'Tag', 'axes_refsubset', ...
            'Units', 'characters', ...
            'Visible', 'off', ...
            'Position', [2.1 13.1 56.5 17], ...
            'Interruptible','off');

        handles_gui.axes_cursubset = axes( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'axes_cursubset', ...
            'Units', 'characters', ...
            'Visible', 'off', ...
            'Position', [2.1 13.1 56.5 17], ...
            'Interruptible','off');

        % Static Texts
        handles_gui.text_refsubloc = uicontrol( ...
            'Parent', handles_gui.group_ref, ...
            'Tag', 'text_cur', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 33.6 56.5 1.2], ...
            'String', 'Location of Reference Subset', ...
            'Interruptible','off');

        handles_gui.text_cursubloc = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_cursubloc', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 33.6 56.5 1.2], ...
            'String', 'Approximate Location of Current Subset', ...
            'Interruptible','off');

        handles_gui.text_refsub = uicontrol( ...
            'Parent', handles_gui.group_ref, ...
            'Tag', 'text_refsub', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 11.0 56.5 1.2], ...
            'String', 'Reference Subset', ...
            'Interruptible','off');

        handles_gui.text_cursub = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_cursub', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 11.0 56.5 1.2], ...
            'String', 'Transformed Current Subset', ...
            'Interruptible','off');

        handles_gui.text_num_iterations = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_num_iterations', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 8.4 38.5 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', '# of Gauss Newton Iterations:', ...
            'Interruptible','off');
        
        handles_gui.text_gradnorm = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_gradnorm', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 6.6 38.5 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', 'Norm of difference vector:', ...
            'Interruptible','off');
        
        handles_gui.text_corrcoef = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_corrcoef', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 4.8 38.5 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', 'Correlation Coefficient:', ...
            'Interruptible','off');
        
        handles_gui.text_num_iterations_num = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_num_iterations_num', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [41.5 8.4 13 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', '', ...
            'Interruptible','off');
        
        handles_gui.text_gradnorm_num = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_gradnorm_num', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [41.5 6.6 13 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', '', ...
            'Interruptible','off');
        
        handles_gui.text_corrcoef_num = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_corrcoef_num', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [41.5 4.8 13 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', '', ...
            'Interruptible','off');       
        
        handles_gui.text_thread = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_thread', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 3.0 56.9 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', 'Thread:', ...
            'Interruptible','off');   
        
        handles_gui.text_cur = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'text_cur', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 1.2 56.9 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', 'Name:', ...
            'Interruptible','off');  
        
        handles_gui.text_ref = uicontrol( ...
            'Parent', handles_gui.group_ref, ...
            'Tag', 'text_ref', ...
            'Style', 'text', ...
            'Units', 'characters', ...
            'Position', [2.1 1.2 56.9 1.2], ...
            'HorizontalAlignment', 'Left', ...
            'String', 'Name:', ...
            'Interruptible','off');  
        
        % Edit
        handles_gui.edit_threadnum = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'edit_threadnum', ...
            'Style', 'edit', ...
            'Units', 'characters', ...
            'Position', [44.3 3.1 7 1.2], ...
            'String', '', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_edit_threadnum,handles_gui.figure), ...
            'Enable', 'off', ...
            'Interruptible','off');
        
        handles_gui.edit_imgnum = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'edit_imgnum', ...
            'Style', 'edit', ...
            'Units', 'characters', ...
            'Position', [44.3 1.2 7 1.2], ...
            'String', '', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_edit_imgnum,handles_gui.figure), ...
            'Enable', 'off', ...
            'Interruptible','off');
        
        % Pushbuttons        
        handles_gui.button_finish = uicontrol( ...
            'Parent', handles_gui.group_menu, ...
            'Tag', 'button_finish', ...
            'Style', 'pushbutton', ...
            'Units', 'characters', ...
            'Position', [2.1 3 29.7 1.7], ...
            'String', 'Finish', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_button_finish,handles_gui.figure), ...
            'Interruptible','off');

        handles_gui.button_cancel = uicontrol( ...
            'Parent', handles_gui.group_menu, ...
            'Tag', 'button_cancel', ...
            'Style', 'pushbutton', ...
            'Units', 'characters', ...
            'Position', [2.1 1 29.7 1.7], ...
            'String', 'Cancel', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_button_cancel,handles_gui.figure), ...
            'Interruptible','off');

        handles_gui.button_left_thread = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'button_left_thread', ...
            'Style', 'pushbutton', ...
            'Units', 'characters', ...
            'Position', [37.3 2.9 6 1.5], ...
            'String', '<', ...
            'Enable', 'off', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_button_left_thread,handles_gui.figure), ...
            'Interruptible','off');

        handles_gui.button_right_thread = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'button_right_thread', ...
            'Style', 'pushbutton', ...
            'Units', 'characters', ...
            'Position', [52.3 2.9 6 1.5], ...
            'String', '>', ...
            'Enable', 'off', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_button_right_thread,handles_gui.figure), ...
            'Interruptible','off');
        
        handles_gui.button_left_cur = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'button_left_cur', ...
            'Style', 'pushbutton', ...
            'Units', 'characters', ...
            'Position', [37.3 1.1 6 1.5], ...
            'String', '<', ...
            'Enable', 'off', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_button_left_cur,handles_gui.figure), ...
            'Interruptible','off');

        handles_gui.button_right_cur = uicontrol( ...
            'Parent', handles_gui.group_cur, ...
            'Tag', 'button_right_cur', ...
            'Style', 'pushbutton', ...
            'Units', 'characters', ...
            'Position', [52.3 1.1 6 1.5], ...
            'String', '>', ...
            'Enable', 'off', ...
            'Callback', ncorr_util_wrapcallbacktrycatch(@callback_button_right_cur,handles_gui.figure), ...
            'Interruptible','off');
    end
       
    % Pause until figure is closed ---------------------------------------%
    waitfor(handles_gui.figure);    
end
