function [value] = SectorEditorTool(varargin)
% function [value] = SectorEditorTool(varargin)
%
% This is the sector editor tool, it allows the user to erode, dilate,
% merge, delete add sectors. You can also edit the point model for the
% organ and you can recalculate any of the sectors and organs at any time.
%
% Dr. A. I. Hanna (2007)

ad = loadGui;
% Set all the callback functions
ad.handles = setupcallbacks(ad.handles);
customtoolbar(ad.figMain);
% Initialize the application data structure
ad = initadstructure(ad);
setappdata(0,'SectorEditorToolData',ad);
init_gui(ad, ad.handles);
try
    uiwait(ad.figMain);
catch
    if ishandle(ad.figMain)
        delete(ad.figMain)
    end
end
value = 0;
return;
%%
function ad = loadGui
if checkSATDir(pwd) == 0
    fprintf('You are not in a valid SectorAnalysisToolbox Project directory\n');
    return;
end
error(nargchk(0,inf,nargin));
% Open, move, and get the handles from the figure file.
ad.figMain = openfig(mfilename, 'reuse');
movegui(ad.figMain, 'center');
set(ad.figMain, 'Visible', 'on');
ad.handles = guihandles(ad.figMain);
set(ad.figMain, 'Color', get(ad.handles.uipanel2, 'BackgroundColor'));
return
%%
function ad = initadstructure(ad)
ad.StagedDirString = 'Staged';
ad.OriginalsDirString = 'Originals';
ad.ProcessedDirString = 'Processed';
ad.projectpath = pwd;
ad.sector_files = FindFilenames('_sectors.tif', ad.StagedDirString);
ad.value = 0;
ad.sectors_handle =  [];
ad.edge_handle  = [];
ad.sectorcolor = [0 0 255];
ad.text_handle  = [];
ad.pri_handle  = [];
ad.currentpoint = [];
ad.morpharea = [];
ad.currentpointind = [];
ad.textcol = [1 1 1];
p = which ('SectorAnalysisToolbox');
p = fileparts(fileparts(fileparts(p)));
ad.segmentation_algs_dir = [p, filesep, 'SAT_Matlab_files_AIH\SectorAnalysisToolbox\SegmentationAlgorithms'] ;
return;
%%
function handles = setupcallbacks(handles)
set(handles.ShowSectorsChk, 'callback', {@doToggleSectors});
set(handles.ShowEdgeChk, 'callback', {@doToggleEdge});
set(handles.SectorFilesPopup, 'callback', {@doSkipFile});
set(handles.nextBtn, 'callback', {@doNext});
set(handles.prevBtn, 'callback', {@doPrev});
set(handles.add_sector_btn, 'callback', {@doAddSector});
set(handles.remove_sector_btn, 'callback', {@doRemoveSector});
set(handles.move_edge_pt_btn, 'callback', {@doMoveEdgePoints});
set(handles.gen_stat_file_btn, 'callback', {@doGenerateStatFile});
set(handles.recalc_sectors_btn, 'callback', {@doRecalcSectors});
set(handles.recalc_edge_btn, 'callback', {@doRecalcEdge});
set(handles.recalc_organ_btn, 'callback', {@doRecalcOrgan});
set(handles.def_primary_points, 'callback', {@doDefPrimaryPts});
set(handles.smooth_pts, 'callback', {@doSmoothPts});
set(handles.change_text_col_btn, 'callback', {@doChangeTextColour});
set(handles.dilate_btn, 'callback', {@doDilateSectors});
set(handles.erode_btn, 'callback', {@doErodeSectors});
set(handles.savechangesbtn, 'callback', {@doSaveSectorsImage});
set(handles.undobtn, 'callback', {@doUndo});
set(handles.morph_area_btn, 'callback', {@doSelectMorphArea});
set(handles.growredbtn, 'callback', {@doGrowRed});
set(handles.redslider, 'callback', {@doUpdateRedSlider});
set(handles.growgreenbtn, 'callback', {@doGrowGreen});
set(handles.greenslider, 'callback', {@doUpdateGreenSlider});
set(handles.growbluebtn, 'callback', {@doGrowBlue});
set(handles.blueslider, 'callback', {@doUpdateBlueSlider});
set(handles.mergesectorsbtn, 'callback', {@doMergeSectors});
set(handles.sectorcol_menu, 'callback', {@doChangeSectorColour});
set(handles.selectFirstPoint_btn, 'callback', {@doClickControlPoints});

return
%%
%
function [] = init_gui(ad, handles)
if isempty(ad.sector_files)
    str = 'No sector files found';
    set(handles.SectorFilesPopup, 'String', str);
    return;
end
str = ad.sector_files;
set(handles.SectorFilesPopup, 'String', str);
name = str{1};
loadImage(name);
displayImage();
displaySectors();
return;
%%
%
function doSkipFile(sector_popup, evd)
ad =getappdata(0, 'SectorEditorToolData');
if isempty(ad.sector_files); return; end;
zoom off; pan off;
set(ad.handles.add_sector_btn, 'value', 0);
set(ad.handles.remove_sector_btn, 'value', 0);
value = get(sector_popup, 'value');
fprintf('Skipped to file %s\n', ad.sector_files{value});
loadImage(ad.sector_files{value});
displayImage();
displaySectors();
return;
%%
%
function doNext(next_btn, evd)
ad =getappdata(0, 'SectorEditorToolData');
if isempty(ad.sector_files); return; end;
value = get(ad.handles.SectorFilesPopup, 'value');
if value < length(ad.sector_files)
    value = value + 1;
    set(ad.handles.SectorFilesPopup, 'value', value);
    doSkipFile(ad.handles.SectorFilesPopup);
end
return;
%%
%
function doRecalcSectors(recalc_sectors_btn, evd)
fprintf('Re-calculating sector information...\n');
ad =getappdata(0, 'SectorEditorToolData');
algorithm = get_project_segmentation_algorithm(ad.segmentation_algs_dir);
if isempty(algorithm)
    return;
end
filename = ad.currentImageName;
[pathname, filename, ext, vers] = fileparts(filename);
binim = imread([pathname, filesep, filename, '_organ.tif']);
w = waitbar(0, sprintf('%s', ['Processing Image ', filename]));
[algorithm_path, algorithm, alg_ext, alg_vers] =fileparts(algorithm);
[w, orig, im, binim, sectors] = feval(algorithm, ad.currentImage, w, binim);
close(w);
if sum(binim(:))>0
    imwrite(sectors, [pathname, filesep, filename, '_sectors.tif'], 'TIFF');
end
setappdata(0, 'SectorEditorToolData', ad);
doSkipFile(ad.handles.SectorFilesPopup);
return;
%%
%
function doChangeTextColour(changetextcolour, evd)
ad =getappdata(0, 'SectorEditorToolData');
col = uisetcolor;
if col==0
    return;
end
ad.textcol = col;
for i=1:length(ad.text_handle)
    set(ad.text_handle, 'Color', ad.textcol);
end
setappdata(0, 'SectorEditorToolData', ad);
%%
%
function doDefPrimaryPts(defprimbtn, evd)
ad =getappdata(0, 'SectorEditorToolData');
if get(defprimbtn, 'Value')==1
    set(ad.handles.imageAxis, 'ButtonDownFcn', {@doClickAxis})
else
    set(ad.handles.imageAxis, 'ButtonDownFcn', '');
    savePrimaries(ad);
end
setappdata(0, 'SectorEditorToolData', ad);
%%
%
function doClickAxis(axish, evd)
ad =getappdata(0, 'SectorEditorToolData');
p = get(axish, 'CurrentPoint');
ad.currentpoint = p(1,1:2);
pts = fliplr(ad.edge);
distance = sqrt(sum((pts - ones(size(pts,1),1)*ad.currentpoint).^2,2));
[val, ind] = min(distance);
ind = ind(1);
found = find(ad.primaries == ind);
if isempty(found)
    ad.primaries = [ad.primaries, ind(1)];
else
    ad.primaries(found) = [];
end
[ad.pri_handle] = plotPrimaries(ad.edge, ad.primaries, ad.handles.imageAxis, ad.pri_handle);
setappdata(0, 'SectorEditorToolData', ad);
%%
%
function doSmoothPts(smoothbtn, evd)
ad =getappdata(0, 'SectorEditorToolData');
pts = ad.edge;
pri = ad.primaries;
[pts]=smoothlandmarks(pts,pri);
ad.edge = pts;
setappdata(0, 'SectorEditorToolData', ad);
saveEdge(ad);
doSkipFile(ad.handles.SectorFilesPopup);
%%
%
function doRecalcEdge(recalc_edge_btn, evd)
fprintf('Re-calculating edge information...\n');
ad =getappdata(0, 'SectorEditorToolData');
filename = ad.currentImageName;
[pathname, filename, ext, vers] = fileparts(filename);
organfilename = [pathname, filesep, filename, '_organ.tif'];
if ~exist(organfilename, 'file')
    uiwait(msgbox('Could not find binary organ image','No binary image','modal'));
    return;
end
binim = imread(organfilename);
E = binim2SortedEdge(binim);
save([pathname, filesep, 'edge_xy.mat'], 'E');
setappdata(0, 'SectorEditorToolData', ad);
doSkipFile(ad.handles.SectorFilesPopup);
return;
%%
%
function doRecalcOrgan(recalc_organ_btn, evd)
fprintf('Re-calculating organ information...\n');
ad =getappdata(0, 'SectorEditorToolData');
algorithm = get_project_segmentation_algorithm(ad.segmentation_algs_dir);
if isempty(algorithm)
    return;
end
filename = ad.currentImageName;
[pathname, filename, ext, vers] = fileparts(filename);
organfilename = [pathname, filesep, filename, ext];
im = imread(organfilename);
w = waitbar(0, sprintf('%s', ['Processing Image ', filename]));
[algorithm_path, algorithm, alg_ext, alg_vers] =fileparts(algorithm);
[w, orig, im, binim, sectors] = feval(algorithm, ad.currentImage, w, [], 0);
close(w);
imwrite(binim, [pathname, filesep, filename, '_organ.tif'], 'TIFF');
doSkipFile(ad.handles.SectorFilesPopup);
%%
%
function saveEdge(ad)
if isempty(ad.primaries)
   return;
end
filename = ad.currentImageName;
E = ad.edge;
[pathname, filename, ext, vers] = fileparts(filename);
edgefilename = [pathname, filesep, 'edge_xy.mat'];
save(edgefilename, 'E');
fprintf('Saved edge to %s\n', edgefilename);
return;
%%
%
function savePrimaries(ad)
if isempty(ad.primaries)
   return;
end
filename = ad.currentImageName;
primaries = ad.primaries;
[pathname, filename, ext, vers] = fileparts(filename);
primaryfilename = [pathname, filesep, 'primary_landmarks.mat'];
save(primaryfilename, 'primaries');
fprintf('Saved primaries to %s\n', primaryfilename);
return;
%%
%
function doGenerateStatFile(gen_stat_file_btn, evd)
ad =getappdata(0, 'SectorEditorToolData');
fprintf('Generating excel statistics file\n');
[s,v] = listdlg('PromptString','Select files to generate statistics:', ...
    'SelectionMode','multiple', 'ListSize', [600 300],...
    'ListString',ad.sector_files);
if v == 0
    return;
end
[xlsfilename, xlspathname] = uiputfile('*.xls', 'Pick an Excel-file');
if isequal(xlsfilename,0) || isequal(xlspathname,0)
    disp('User pressed cancel');
    return;
else
    disp(['User selected ', fullfile(xlspathname, xlsfilename)])
end
stats = {'Directory', 'Image Name', 'Number of Sectors', 'Average Sector Area (pixels)', 'Variance of Sector Size', ...
    'Proportion of organ area', 'log_2(Prop. Organ Area)', 'Organ Area', };
stats_waitbar_handle = waitbar(0,'Calculating statistics, please wait...');
for i=1:length(s)
    waitbar(i/length(s),stats_waitbar_handle)
    filename = ad.sector_files{s(i)};
    [path, filename, ext, vers] = fileparts(filename);
    fprintf('Processing file: %s\n', filename);
    sectors_im = imread([path, filesep, filename, ext]);
    sectors_im = double(sectors_im);
    sectors_im = sectors_im./max(sectors_im(:));
    binim = imread([path, filesep, filename(1:end-8), '_organ.tif']);
    binim = double(binim);
    organ_size = sum(binim(:));
    clear binim;
    stats = get_sectors_stats(filename, path, sectors_im, organ_size, stats);
end
close(stats_waitbar_handle);
success = xlswrite([xlspathname, filesep, xlsfilename], stats);
return;
%%
%
function [stats] = get_sectors_stats(name, path,  I, organ_size, stats)
L = bwlabel(I);
props = regionprops(L);

log_percentage_covered = log2(mean([props.Area]/organ_size));
[n, x] = nhist(log_percentage_covered, .2);
ind = find(n == 0);
n(ind) = [];
x(ind) = [];
perc_pix = (2.^x).*n;
[v, p] = max(perc_pix);
gmode = x(p);
gmean = sum(x.*perc_pix)/sum(perc_pix);
stats{end+1, 1} = path;
stats{end, 2} = name;
stats{end, 3} = length(props);
stats{end, 4} = mean([props.Area]);
stats{end, 5} = var([props.Area]);
stats{end, 6} = mean([props.Area]/organ_size);
stats{end, 7} = log2(stats{end, 6});
stats{end, 8} = organ_size;
%stats{end, 9} = gmean;
return;
%%
%
function [f, d] = nhist(x, bs)
x = sort(x);
L = min(x); U = max(x);
Nbins = (U-L)/bs + 1;
[f, d] = hist(x, Nbins);
return;
%%
%
function doMoveEdgePoints(move_edge_pt_btn, evd)
ad =getappdata(0, 'SectorEditorToolData');
switch (get(move_edge_pt_btn, 'Value'))
    case 0
        set(move_edge_pt_btn, 'String', 'Move Edge Points');
        set(ad.figMain, 'Pointer', 'Arrow');
        set(ad.figMain, 'WindowButtonDownFcn', '', 'WindowButtonMotionFcn' , '', 'WindowButtonUpFcn', '', 'BackingStore','on');
        filename = get(ad.handles.SectorFilesPopup, 'string');
        filename = filename{get(ad.handles.SectorFilesPopup, 'value')};
        [pathname, filename, ext, vers] = fileparts(filename);
        E = ad.edge;
        save([pathname, filesep, 'edge_xy.mat'], 'E');
        binim = zeros(size(ad.currentImage(:,:,1)));
        binim = roipoly(binim, E(:,2), E(:,1));
        value = get(ad.handles.SectorFilesPopup, 'value');
        filename = ad.currentImageName;
        [pathname, filename, ext, vers] = fileparts(filename);
        imwrite(binim, [pathname, filesep, filename, '_organ.tif'], 'TIFF');
    case 1
        set(move_edge_pt_btn, 'String', 'Save new edge');
        set(ad.figMain, 'Pointer', 'crosshair');
        set(ad.handles.imageAxis, 'ButtonDownFcn', '');
        set(ad.figMain, 'BackingStore', 'off', 'WindowButtonDownFcn',  {@select_edge_pt});
end
setappdata(0, 'SectorEditorToolData', ad);
return;
%%
%
function select_edge_pt(fig, evd)
ad =getappdata(0, 'SectorEditorToolData');
cp = get(ad.handles.imageAxis, 'CurrentPoint');
cp = cp(1,1:2);
[val, ind] = min(sqrt(sum((fliplr(ad.edge) - ones(size(ad.edge,1),1)*cp).^2,2)));
ad.edge_pt_to_move = ind(1);
setappdata(0, 'SectorEditorToolData', ad);
set(fig, 'WindowButtonMotionFcn', {@move_edge_pt}, 'WindowButtonUpFcn',  {@drop_edge_pt});
return;
%%
%
function move_edge_pt(fig, evd)
ad =getappdata(0, 'SectorEditorToolData');
if isempty(ad.edge_pt_to_move)
    return
end
cp = get(ad.handles.imageAxis, 'CurrentPoint');
cp = cp(1,1:2);
ad.edge(ad.edge_pt_to_move(1),:) = fliplr(cp);
if isempty(ad.edge_handle)
    return
end
ad.edge_handle = ad.edge_handle(1);
xdata = get(ad.edge_handle, 'XData');
ydata = get(ad.edge_handle, 'YData');
if iscell(xdata)
    xdata = xdata{1};
    ydata = ydata{1};
end
xdata(ad.edge_pt_to_move(1)) = cp(1);
ydata(ad.edge_pt_to_move(1)) = cp(2);
set(ad.edge_handle, 'XData', xdata);
set(ad.edge_handle, 'YData', ydata);
set(ad.text_handle(ad.edge_pt_to_move(1)), 'Position', [cp, 0]);
setappdata(0, 'SectorEditorToolData', ad);
return;
%%
%
function drop_edge_pt(fig, evd)
ad =getappdata(0, 'SectorEditorToolData');
set(fig, 'WindowButtonMotionFcn' ,'','WindowButtonUpFcn','');
ad.ctrl_pt_to_move = [];
setappdata(0, 'SectorEditorToolData', ad);
return;

function doPrev(prev_btn, evd)
ad =getappdata(0, 'SectorEditorToolData');
if isempty(ad.sector_files); return; end;
value = get(ad.handles.SectorFilesPopup, 'value');
if value > 1
    value = value - 1;
    set(ad.handles.SectorFilesPopup, 'value', value);
    doSkipFile(ad.handles.SectorFilesPopup);
end
return;
%%
%
function doToggleSectors(toggle_sector_chk, evd)
ad =getappdata(0, 'SectorEditorToolData');
if get(toggle_sector_chk, 'value')
    set(ad.sectors_handle, 'Visible', 'on');
else
    set(ad.sectors_handle, 'Visible', 'off');
end
setappdata(0,'SectorEditorToolData',ad);
%%
%
function doAddSector(add_sector_btn, evd)
ad =getappdata(0, 'SectorEditorToolData');
zoom off; pan off;
set(ad.sectors_handle, 'Visible', 'off');
set(ad.edge_handle, 'Visible', 'off');

[bw, las_x, las_y] = roipoly;
ad.sector_im = (double(ad.sector_im) + double(bw))>=1;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0,'SectorEditorToolData',ad);
%value = get(ad.handles.SectorFilesPopup, 'value');
%imwrite(ad.sector_im, ad.sector_files{value}, 'TIFF');
set(ad.sectors_handle, 'Visible', 'on');
set(ad.edge_handle, 'Visible', 'on');
displaySectors();

% function doClickImageAxis(image_axis, evd)
% ad =getappdata(0, 'SectorEditorToolData');
% % normal = left
% % alt = right
% % extended = both
% % open = double left/right click
% if get(ad.handles.add_sector_btn, 'value')
%     add_sector;
% end
function doRemoveSector(remove_sector_btn, evd)
ad =getappdata(0, 'SectorEditorToolData');
zoom off; pan off;
[bw, las_x, las_y] = roipoly;
if max(ad.sector_im(:))>1
    ad.sector_im = ad.sector_im./max(ad.sector_im(:));
end
ad.sector_im = (double(ad.sector_im) - double(bw))>=1;
%ad.sector_im = minus(uint8(ad.sector_im), uint8(bw&ad.sector_im));
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0,'SectorEditorToolData',ad);
value = get(ad.handles.SectorFilesPopup, 'value');
%imwrite(ad.sector_im, ad.sector_files{value}, 'TIFF');
displaySectors();


function doToggleEdge(toggle_edge_chk, evd)
ad =getappdata(0, 'SectorEditorToolData');
if get(toggle_edge_chk, 'value')
    set(ad.edge_handle, 'Visible', 'on');
    set(ad.text_handle, 'Visible', 'on')
    set(ad.pri_handle, 'Visible', 'on');

else
    set(ad.edge_handle, 'Visible', 'off');
    set(ad.text_handle, 'Visible', 'off');
    set(ad.pri_handle, 'Visible', 'off');
end
setappdata(0,'SectorEditorToolData',ad);
%%
function sector_im = loadSectorImage(name)
sector_im = [];
if ~exist(name, 'file')
    fprintf('Sector file: %s does not exist\n', name);
    return
end
sector_im = imread(name);
return
%%
function im = loadRGBImage(name)
im = [];
if ~exist(name, 'file')
    fprintf('Sector file: %s does not exist\n', name);
    return
end
im = imread(name);
if size(im,3) == 1
    im = repmat(im, [1 1 3]);
end
return
%%
function loadImage(name)
ad =getappdata(0, 'SectorEditorToolData');
ad.sector_im = loadSectorImage(name);
[path, name, ext, vers] = fileparts(name);
[x, y] = find(ad.sector_im >0);
ad.sector.x = x;
ad.sector.y = y;
ad.currentImageName = [path, filesep, name(1:end-8), '.JPG'];
ad.currentImage = loadRGBImage(ad.currentImageName);
ad.edge = load([path, filesep, 'edge_xy.mat']);
ad.edge = ad.edge.E;

primariesname = [path, filesep, 'primary_landmarks.mat'];
if exist(primariesname, 'file')
    pri = load(primariesname);
    ad.primaries = pri.primaries;
    ind = ad.primaries>size(ad.edge,1);
    ad.primaries(ind) = [];
else
    ad.primaries = [];
end
%ad.primaries = [1 24];
setappdata(0,'SectorEditorToolData',ad);
return;

function displayImage()
ad =getappdata(0, 'SectorEditorToolData');
cla(ad.handles.imageAxis);
imagesc(ad.currentImage, 'Parent', ad.handles.imageAxis, 'HitTest', 'off');
hold(ad.handles.imageAxis, 'on');
axis(ad.handles.imageAxis, 'image', 'ij');
if isfield(ad, 'axisXlim')
    set(ad.handles.imageAxis,'XLim', ad.axisXlim);
    set(ad.handles.imageAxis,'YLim', ad.axisYlim);
end
%%
%
%
%%
function ad = deleteHandles(ad)
if ishandle(ad.sectors_handle); delete(ad.sectors_handle); end;
if ishandle(ad.edge_handle); delete(ad.edge_handle); end;
if ishandle(ad.text_handle); delete(ad.text_handle); end;
return
%%
function im = createSectorImage(im, x, y, sectorcol)
ind= sub2ind(size(im(:,:,1)), x, y);
for i=1:3
    c = im(:,:,i);
    c(ind) = sectorcol(i);
    im(:,:,i) = c;
end
return
%%
%
function displaySectors()
tic
ad =getappdata(0, 'SectorEditorToolData');
ad = deleteHandles(ad);
hold(ad.handles.imageAxis, 'on');
im = createSectorImage(ad.currentImage, ad.sector.x, ad.sector.y, ad.sectorcolor);
ad.sectors_handle = imagesc(im, 'Parent', ad.handles.imageAxis, 'HitTest', 'off');
%ad.sectors_handle =  plot(ad.handles.imageAxis, ad.sector.y, ad.sector.x, '.', 'HitTest', 'off');
ad.edge_handle = plotEdge(ad.edge, ad.handles.imageAxis);
ad.text_handle = plotText(ad.edge, ad.textcol, ad.handles.imageAxis);
ad.pri_handle = plotPrimaries(ad.edge, ad.primaries, ad.handles.imageAxis, ad.pri_handle);
set(ad.sectors_handle, 'Visible', 'on');
set(ad.handles.ShowSectorsChk, 'value', 1);
set(ad.handles.ShowEdgeChk, 'value', 1);
setappdata(0,'SectorEditorToolData',ad);
toc
%%
%

function [edge_handle] = plotEdge(edge, axis_h)
edge_handle =  plot(axis_h, edge(:,2), edge(:,1), '-o', 'MarkerSize', 5, 'Color', 'r', 'MarkerEdgeColor', 'r', 'MarkerFace', 'g', 'LineWidth', 2, 'HitTest', 'off');
%%
%
function [text_handle] = plotText(edge, textcol, axis_h)
s = cell(size(edge,1),1);
for i=1:size(edge,1); s{i} = num2str(i); end;
text_handle =  text(edge(:,2), edge(:,1)-2, s, 'Parent', axis_h, 'HitTest', 'off', 'Color', [1 0 1], 'FontWeight', 'bold');

%%
%
function [pri_handle] = plotPrimaries(edge, primaries, axis_h, pri_handle)
if ishandle(pri_handle); delete(pri_handle); end;
pri_handle =  plot(axis_h, edge(primaries,2), edge(primaries,1), 'o', 'MarkerSize', 5, 'Color', 'r', 'MarkerEdgeColor', 'y', 'MarkerFace', 'r', 'HitTest', 'off');
return

%%
%

function [pts]=smoothlandmarks(pts,pri)
if(length(pri) <= 1)
    uiwait(msgbox(sprintf('You need at leat two primary points')))
    return;
end
segments=find_segments_to_smooth(pts,pri);
for k = 1:length(segments) %SectionsToSmooth
    seg=segments{k};
    NptsThisSection=length(seg);
    x=pts(seg,1);
    y=pts(seg,2);
    % x,y are start and end points of the spline
    Nint = 50;
    t = 1:NptsThisSection;
    ts = 1:1/Nint:NptsThisSection;
    xfit = spline(t, x, ts); % x-coordinates of interpolating line
    yfit = spline(t, y, ts); % y-coordinates of interpolating line
    % Calculate the length of the line through the secondaries
    xfitS = xfit(2:length(xfit)) - xfit(1:length(xfit)-1);
    yfitS = yfit(2:length(yfit)) - yfit(1:length(yfit)-1);
    LineLength = cumsum(sqrt((xfitS.^2) + (yfitS.^2)));
    % Calculate what the spacing should be between the secondaries.
    DistanceBetweenPoints = LineLength(length(LineLength)) / (NptsThisSection - 1);
    % Clear from last iteration
    newx=[]; newy=[];
    % Find position of new points
    for n = 2:NptsThisSection-1
        idx = min(find(LineLength >= (n-1) * DistanceBetweenPoints)) + 1; %#ok<MXFND>
        newx(n-1) = xfit(idx);
        newy(n-1) = yfit(idx);
    end
    pts(seg(2:end-1),1) = newx';
    pts(seg(2:end-1),2) = newy';
end
return;
%%
%
function segments = find_segments_to_smooth(pts, pri)
pri = sort(pri);
N = length(pri)-1;
segments = cell(N+1,1);
for i=1:N
   segments{i} = pri(i):pri(i+1); 
end
segments{N+1} = [pri(end):size(pts,1), 1:pri(1)];
return;
%%
%
function doGrowRed(dilatebtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
if isempty(ad.morpharea)
    uiwait(msgbox('You must select an area to dilate first.','Area','modal'));
    return;
end
dilatesectorsim = ad.sector_im & ad.morpharea;
[r, c] = find(dilatesectorsim);
thr = get(ad.handles.redslider, 'value');
redchannel = ad.currentImage(:,:,1);
b = bwselect((redchannel<thr), c, r);
b = b & ad.morpharea;
b = b | dilatesectorsim;
ad.sector_im = ad.sector_im & ~ad.morpharea;
ad.sector_im = ad.sector_im | b ;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0, 'SectorEditorToolData', ad);
displaySectors();
fprintf('done.\n');
%%
%
function doGrowGreen(dilatebtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
if isempty(ad.morpharea)
    uiwait(msgbox('You must select an area to dilate first.','Area','modal'));
    return;
end
dilatesectorsim = ad.sector_im & ad.morpharea;
[r, c] = find(dilatesectorsim);
thr = get(ad.handles.greenslider, 'value');
redchannel = ad.currentImage(:,:,2);
b = bwselect((redchannel<thr), c, r);
b = b & ad.morpharea;
b = b | dilatesectorsim;
ad.sector_im = ad.sector_im & ~ad.morpharea;
ad.sector_im = ad.sector_im | b ;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0, 'SectorEditorToolData', ad);
displaySectors();
fprintf('done.\n');
%%
%
function doGrowBlue(dilatebtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
if isempty(ad.morpharea)
    uiwait(msgbox('You must select an area to dilate first.','Area','modal'));
    return;
end
dilatesectorsim = ad.sector_im & ad.morpharea;
[r, c] = find(dilatesectorsim);
thr = get(ad.handles.blueslider, 'value');
redchannel = ad.currentImage(:,:,3);
b = bwselect((redchannel<thr), c, r);
b = b & ad.morpharea;
b = b | dilatesectorsim;
ad.sector_im = ad.sector_im & ~ad.morpharea;
ad.sector_im = ad.sector_im | b ;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0, 'SectorEditorToolData', ad);
displaySectors();
fprintf('done.\n');
%%
%
function doDilateSectors(dilatebtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
if isempty(ad.morpharea)
    uiwait(msgbox('You must select an area to dilate first.','Area','modal'));
    return;
end
sz = get(ad.handles.strelsize, 'String');
sz = str2double(sz);
if ~isnumeric(sz)
    sz = 5;
end
dilatesectorsim = ad.sector_im & ad.morpharea;
dilatesectorsim = imdilate(dilatesectorsim, strel('disk', sz));
ad.sector_im = ad.sector_im & ~ad.morpharea;
ad.sector_im = ad.sector_im | dilatesectorsim;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0, 'SectorEditorToolData', ad);
displaySectors();
return
%%
%
function doErodeSectors(erodebtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
if isempty(ad.morpharea)
    uiwait(msgbox('You must select an area to dilate first.','Area','modal'));
    return;
end
sz = get(ad.handles.strelsize, 'String');
sz = str2double(sz);
if ~isnumeric(sz)
    sz = 5;
end
dilatesectorsim = ad.sector_im & ad.morpharea;
dilatesectorsim = imerode(dilatesectorsim, strel('disk', sz));
ad.sector_im = ad.sector_im & ~ad.morpharea;
ad.sector_im = ad.sector_im | dilatesectorsim;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0, 'SectorEditorToolData', ad);
displaySectors();
return
%%
%
function doSaveSectorsImage(savesectorsbtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
h = waitbar(0,'Saving...');
value = get(ad.handles.SectorFilesPopup, 'value');
imwrite(ad.sector_im, ad.sector_files{value}, 'TIFF');
waitbar(1,h);
setappdata(0, 'SectorEditorToolData', ad);
close(h);
return
%%
%
function doUndo(undobtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
doSkipFile(ad.handles.SectorFilesPopup);
%%
%
function doSelectMorphArea(selarea, evd)
ad = getappdata(0, 'SectorEditorToolData');
zoom off; pan off;

[bw, las_x, las_y] = roipoly;
ad.morpharea = bw;
ad.morphareaedge = [las_x, las_y];
setappdata(0, 'SectorEditorToolData', ad);
%%
%
function doUpdateRedSlider(slider, evd)
ad = getappdata(0, 'SectorEditorToolData');
set(ad.handles.redtxt, 'String', num2str(get(slider, 'Value')));
%%
%
function doUpdateGreenSlider(slider, evd)
ad = getappdata(0, 'SectorEditorToolData');
set(ad.handles.greentxt, 'String', num2str(get(slider, 'Value')));
%%
%
function doUpdateBlueSlider(slider, evd)
ad = getappdata(0, 'SectorEditorToolData');
set(ad.handles.bluetxt, 'String', num2str(get(slider, 'Value')));
%%
function doChangeSectorColour(col, evd)
ad = getappdata(0, 'SectorEditorToolData');
col = uisetcolor;
if col==0
    return;
end
ad.sectorcolor = col*255;
setappdata(0, 'SectorEditorToolData', ad);
displaySectors();
%%
%
function doMergeSectors(mergebtn, evd)
ad = getappdata(0, 'SectorEditorToolData');
zoom off; pan off;
ad.axisXlim = get(ad.handles.imageAxis,'XLim');
ad.axisYlim = get(ad.handles.imageAxis,'YLim');
bim = bwselect(ad.sector_im, 4);
bim = bwmergeregions(bim);
ad.sector_im = ad.sector_im | bim;
[x, y] = find(ad.sector_im == 1);
ad.sector.x = x;
ad.sector.y = y;
setappdata(0, 'SectorEditorToolData', ad);
displayImage();
displaySectors();
%%
%
function customtoolbar(figh)
hA = findall(figh);
openfileh=findobj(hA,'TooltipString','Open File');
newgridh=findobj(hA,'TooltipString','New Figure');
saveh=findobj(hA,'TooltipString','Save Figure');
set(saveh, 'ClickedCallback', {@doSaveSectorsImage});
set(saveh, 'TooltipString', 'Save Changes');
roth=findobj(hA,'TooltipString','Rotate 3D');
datah=findobj(hA,'TooltipString','Data Cursor');
colbarh=findobj(hA,'TooltipString','Insert Colorbar');
printh = findobj(hA, 'TooltipString', 'Print Figure');
legh=findobj(hA,'TooltipString','Insert Legend');
hideh=findobj(hA,'TooltipString','Hide Plot Tools');
showh=findobj(hA,'TooltipString','Show Plot Tools and Dock Figure');
delete([openfileh, newgridh, roth, datah, colbarh, legh, hideh, showh, printh]);
%%

function doClickControlPoints(image_axis, evd)

ad =getappdata(0, 'SectorEditorToolData');
 if strcmp(get(ad.figMain, 'SelectionType'), 'alt')
     doNext;
 else
    %c = get(image_axis, 'CurrentPoint');    
    %x = c(1,1); y = c(1, 2);
    
    [x,y] = ginput(1);
    d = sqrt((ad.edge(:,2) - x).^2 + (ad.edge(:,1) - y).^2);
    [v, i] = min(d);
    i = i(1);
    e_temp = ad.edge;
    ad.edge = [e_temp(i:end,:); e_temp(1:i-1,:)];
    E = ad.edge;
    value = get(ad.handles.SectorFilesPopup, 'value');
    disp(ad.sector_files{value});
    [path, name, ext, vers] = fileparts(ad.sector_files{value});
    save([path, filesep, 'edge_xy.mat'], 'E');
    setappdata(0,'SectorEditorToolData',ad);
    displayImage();
    displaySectors();
end