function GridEditorTool(varargin)
% function GridEditorTool(varargin)
%
% Notes: every region must have at least 4 control points so we can find an
% inverse transform for the strain matrix.
% Hanna, 2007

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.
fig = openfig(mfilename, 'reuse');
movegui(fig, 'center');
set(fig, 'Visible', 'on');
handles = guihandles(fig);
set(fig, 'Color', get(handles.uipanel10, 'BackgroundColor'));

% Set all the callback functions
set(handles.load_ungrown_shape_btn, 'callback', {@doLoadUngrownShape});

set(handles.warp_to_shape_btn, 'callback', {@doWarpToShape});
set(handles.calcregionstatsmenu, 'callback', {@doCalcRegionStats});
set(handles.edit_edge_pts_menu, 'callback', {@doEditEdgePoints});
set(handles.concavitychkmenu, 'callback', {@doConcavityCheck});
set(handles.save_grid_menu, 'callback', {@doSaveGrid});
set(handles.add_control_point_btn, 'callback', {@doAddCtrlPt});
set(handles.select_regions_btn, 'callback', {@doSelectRegions});
set(handles.move_control_point_btn, 'callback', {@doMoveCtrlPt});
set(handles.build_regions_menu, 'callback', {@doBuildRegions});
set(handles.del_control_point_btn, 'callback', {@doDelCtrlPt});
set(handles.new_grid_menu, 'callback', {@doNewGrid});
set(handles.open_grid_menu, 'callback', {@doOpenGrid});
set(handles.quit_menu, 'callback', {@doQuit});
set(handles.makespringsmenu, 'callback', {@doMakeSprings});
set(handles.fittrimesh, 'callback', {@doFitTriMesh});
set(handles.selectstages, 'callback', {@selectStagesForGrid});
set(handles.optimizegridsforstages, 'callback', {@doOptimizeGridForStages});
set(handles.paint_regs_btn, 'callback', {@doPaintRegions});
set(handles.use_base_grid_for_all_menu, 'callback', {@doUseBaseGridForAll});
set(handles.count_sectors_btn, 'callback', {@doCountSectorsperRegion});
set(handles.fitreggrid, 'callback', {@doFitGrid});
%set(handles.changeDSt_btn, 'callback', {@doChangeDeltaSt});
%set(handles.setallDSt_btn, 'callback', {@doChangeAllDeltaSt});

% Toggle Callbacks
set(handles.toggle_mean_shape, 'callback', {@doToggleMeanShape});
set(handles.toggle_springs, 'callback', {@doToggleSprings});
set(handles.toggle_centroids, 'callback', {@doToggleCentroids});
set(handles.toggle_grid, 'callback', {@doToggleGrid});

% Initialize the application data structure
ad.figMain = fig;
ad = init_ad_struct(ad);
ad.handles = handles;
set(ad.handles.area_thr, 'String', num2str(get_pixel_per_cell_value));
% Remove the save icon from the toolbar
customtoolbar(ad.figMain);
if ~exist(ad.MeanShapeName, 'file')
    fprintf('There is no mean shape to align a grid to, aborting!\n');
    delete(fig)
    return;
else
    ad.mean_shape = load(ad.MeanShapeName);
    ad.mean_shape = ad.mean_shape.mean_shape;
end
ad.regions.shape = fliplr(ad.mean_shape);
setappdata(0,'GridEditorToolData',ad);
try
    uiwait(fig);
catch
    if ishandle(fig)
        delete(fig)
    end
end
value = 0;
return;
%%%
%
%%%
function doQuit(quitmenu, evd)
ad =getappdata(0, 'GridEditorToolData');
delete(ad.figMain);
%%%
%
%%%
function ad = init_ad_struct(ad)
ad.StagedDirString = 'Staged';
ad.OriginalsDirString = 'Originals';
ad.ProcessedDirString = 'Processed';
ad.RegionDirName = 'RegionData';
ad.DataDir = [ad.StagedDirString, filesep, 'Data'];
ad.UngrowthDataDir = [ad.DataDir, filesep, 'UngrowthData'];
ad.GridDir = [ad.DataDir, filesep, 'Grids'];
ad.edge_margin = 20;
if ~exist(ad.GridDir, 'dir'); mkdir(ad.GridDir); end;
ad.MeanShapeName = [ad.DataDir, filesep, 'mean_shape.mat'];
ad.layers  = [];
ad.ctrl_pt_to_move = [];

ad.av_info = [];
ad.sector_region_info = [];
ad.region_size_threshold = 0.33;
ad.grid_plot_handle = [];
ad.vertex_plot_handle =[];
ad.mean_shape_plot_handle =[];
ad.edge_plot_handle = [];
ad.spring_marker_handle = [];
ad.spring_line_handle = [];
ad.spring_text_handle = [];
ad.shape_spring_handle = [];
ad.edge_marker_handle = [];
ad.grid_name = [];
ad.edge_line_handle = [];
ad.edge_text_handle = [];
ad.centroid_plot_handle = [];
ad.ctrl_pt_handle =[];
ad.ctrl_pt_handle =[];
ad.projectpath = pwd;
ad.value = 0;
ad.regions = init_regions_struct;
ad.stage_grids = {};
%%%
%
%%%
function I = shapepts2im(shape)
I = zeros(ceil(max(shape(:,1)))+ceil(min(shape(:,1))),ceil( max(shape(:,2)))+ceil( min(shape(:,2))));
I = roipoly(I, shape(:,2), shape(:,1));
return
%%%%
%
%
%
%%%%
function show_shape
ad =getappdata(0, 'GridEditorToolData');
I = shapepts2im(ad.mean_shape);
imagesc(I, 'Parent', ad.handles.imageAxis); hold(ad.handles.imageAxis, 'on');
axis(ad.handles.imageAxis, 'image', 'ij');
set(ad.figMain, 'Colormap', copper);
setappdata(0, 'GridEditorToolData', ad);
doPlotMeanShape;
set(ad.handles.imageAxis, 'Visible', 'off');
return;
%%%%
%
%
%
%%%%
function doToggleMeanShape(toggle_mean_shape, evd)
ad =getappdata(0, 'GridEditorToolData');
if ishandle(ad.mean_shape_plot_handle)
    if strcmp(get(toggle_mean_shape, 'Checked'), 'off')
        set(ad.mean_shape_plot_handle, 'Visible', 'on');
        set(toggle_mean_shape, 'Checked', 'on');
    else
        set(toggle_mean_shape, 'Checked', 'off');
        set(ad.mean_shape_plot_handle, 'Visible', 'off');
    end
end
setappdata(0, 'GridEditorToolData', ad);
%%%%
%
%
%
%%%%
function doNewGrid(newgridbtn, evd)
ad = getappdata(0, 'GridEditorToolData');
ad = init_ad_struct(ad);
if ~exist(ad.MeanShapeName, 'file')
    fprintf('There is no mean shape to align a grid to, aborting!\n');
    delete(fig)
    return;
else
    ad.mean_shape = load(ad.MeanShapeName);
    ad.mean_shape = ad.mean_shape.mean_shape;
end
ad.regions.shape = fliplr(ad.mean_shape);
setappdata(0,'GridEditorToolData',ad);
show_shape;
return;
%%%
%
%%%
function doFitTriMesh(trimesh_menu, evd)
ad = getappdata(0, 'GridEditorToolData');

% Uses mesh2d
hdata.hmax = str2double(get(ad.handles.element_area_txt, 'String'));
hdata.edgeh = [1, 280];
options.dhmax = 20;
options.maxit = 100;
options.output = false;
options.mlim = 0.001;
shape = ad.regions.shape;

shape = shape(1:2:end,:);
[pts, T] = mesh2d(shape, [], hdata, options);
fprintf(' - grid has %d elements\n', size(T,1));
% uses distmesh2d (Strang et. al.)
%[T, pts] = fitTriMesh(ad.regions.shape, ad.handles.imageAxis);
grid.tri_info.T = T;
grid.tri_info.pts = pts;
grid.shape = ad.regions.shape;
grid = init_region_tri_ind(grid);

fprintf('done\n');
ad.regions = grid;
setappdata(0, 'GridEditorToolData', ad);
doPlotAll;
return
%%%
%
function doFitGrid(grid_menu, evd)
ad = getappdata(0, 'GridEditorToolData');
% find dimensions of the mean shape
FitRegularGrid(ad.mean_shape, ad.GridDir);
setappdata(0, 'GridEditorToolData', ad);
return
%%%
% function [t, p] = fitTriMesh(shape, axish)
% bw = shapepts2im(shape);
% pfix = bwboundaries(bw);
% pfix = pfix{1};
% fd=inline('0.5 - inpolygon(p(:,1), p(:,2), epts(:,1), epts(:,2))','p', 'epts');
% [p,t]=distmesh2d(fd,@huniform, 200, [1 1; size(bw,1), size(bw,2)], shape, axish, pfix);
% return
%%%%
%
%
%
%%%%
function doToggleGrid(toggle_grid, evd)
ad =getappdata(0, 'GridEditorToolData');
if ishandle(ad.grid_plot_handle)
    if strcmp(get(toggle_grid, 'Checked'), 'off')
        set(ad.grid_plot_handle, 'Visible', 'on');
        set(toggle_grid, 'Checked', 'on')
    else
        set(ad.grid_plot_handle, 'Visible', 'off');
        set(toggle_grid, 'Checked', 'off')
    end
end
setappdata(0, 'GridEditorToolData', ad);
%%%%
%
%
%
%%%%
function doToggleSprings(toggle_internal, evd)
ad =getappdata(0, 'GridEditorToolData');
if ishandle(ad.spring_line_handle)

    if strcmp(get(toggle_internal, 'Checked'), 'off')
        set(ad.spring_line_handle, 'Visible', 'on');
        set(toggle_internal, 'Checked', 'on')
    else
        set(ad.spring_line_handle, 'Visible', 'off');
        set(toggle_internal, 'Checked', 'off')
    end
end
setappdata(0, 'GridEditorToolData', ad);
%%%%
%
%
%
%%%%
function doToggleCentroids(toggle_centroids, evd)
ad =getappdata(0, 'GridEditorToolData');
if ishandle(ad.centroid_plot_handle)
    if strcmp(get(toggle_centroids, 'Checked'), 'off')
        set(ad.centroid_plot_handle, 'Visible', 'on');
        set(toggle_centroids, 'Checked', 'on')
    else
        set(ad.centroid_plot_handle, 'Visible', 'off');
        set(toggle_centroids, 'Checked', 'off')
    end
end
setappdata(0, 'GridEditorToolData', ad);
%%%
%
%%%
function selectStagesForGrid(select_stages, evd)
ad =getappdata(0, 'GridEditorToolData');
StagedDirString = ad.StagedDirString;
FILES = dir(StagedDirString);
if isempty(FILES);
    return;
end;
FILES = {FILES.name};
FILES = cleanup_stage_list(FILES);
[FILES, value] = SelectOrderListDlg('liststring', FILES);
% [s,v] = listdlg('Name', 'Select Stages To Calc. Region Stats', 'PromptString','Select the stages you wish to calculate regional statistical for:', 'SelectionMode','multiple', 'ListString',FILES, 'ListSize', [300, 200]);
% if isempty(s)
%     return;
% end
% FILES = FILES(s);
ad.regions.stage_info.staged_dir = StagedDirString;
ad.regions.stage_info.stages = FILES;
setappdata(0, 'GridEditorToolData', ad);
return
%%%
%
%%%
function movePaint(e, evd)
ad = getappdata(0, 'GridEditorToolData');
base_grid = ad.regions;
pt = get(ad.handles.imageAxis, 'CurrentPoint');
pt = pt(1,1:2);
T = base_grid.tri_info.T;
pts = base_grid.tri_info.pts;
tind = tsearch(pts(:,1),pts(:,2), T, pt(1),pt(2));
if ~isnan(tind)
    if ~any(ad.data.current_painted_region==tind)
        ad.data.current_painted_region = cat(2, ad.data.current_painted_region, tind);

    end
    delete(ad.data.current_painted_region_ph );
    ad.data.current_painted_region_ph  = [];

    ad.data.current_painted_region_ph  = triplot(T(ad.data.current_painted_region,:), pts(:,1), pts(:,2), 'c', 'Parent', ad.handles.imageAxis);
end
setappdata(0, 'GridEditorToolData', ad);
%%%
%
%%%
function prepPaint(e, evd)
ad = getappdata(0, 'GridEditorToolData');
ad.data.current_painted_region = [];
ad.data.current_painted_region_ph = [];
setappdata(0, 'GridEditorToolData', ad);
set(ad.figMain, 'WindowButtonMotionFcn', {@movePaint});


%%%
%
%%%
function stopPaint(e, evd)
ad = getappdata(0, 'GridEditorToolData');
set(ad.figMain, 'WindowButtonMotionFcn', '');
ad.data.current_painted_region
base_grid = ad.regions;
movetype = get(ad.figMain,'SelectionType');

regions_ind = base_grid.region_tri_ind;
init_tri = ad.data.current_painted_region(1);
init_reg = unique(findRegionContainingTri(regions_ind, init_tri));
neighbours = unique(findRegionContainingTri(regions_ind, ad.data.current_painted_region));

switch lower(movetype)
    case 'alt'
        for i=1:length(ad.data.current_painted_region)
            tri_reg = findRegionContainingTri(regions_ind, ad.data.current_painted_region(i));
            regions_ind{tri_reg}(regions_ind{tri_reg}==ad.data.current_painted_region(i)) = [];
            if isempty(regions_ind{tri_reg})
                regions_ind(tri_reg) = [];
            end
        end
        regions_ind = cat(1, regions_ind, ad.data.current_painted_region);
    case 'normal'
        neighbours(neighbours==init_reg) = [];
        regions_ind{init_reg} = cat(2, regions_ind{init_reg}, regions_ind{neighbours});

        regions_ind(neighbours) = [];
end

base_grid.region_tri_ind = regions_ind;
ad.regions =  base_grid;
setappdata(0, 'GridEditorToolData', ad);
doPlotAll;
%%%
%
%%%
function doPaintRegions(paintbtn, evd)
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'tri_info')
    set(paintbtn, 'value', 0);
    uiwait(msgbox('There is no trianglation for this grid.','No Stages','modal'));
    return;
end
if get(paintbtn, 'value') ==1
    set(ad.figMain, 'WindowButtonDownFcn', {@prepPaint}, 'WindowButtonUpFcn', {@stopPaint});
else
    set(ad.figMain, 'WindowButtonDownFcn', '', 'WindowButtonUpFcn', '', 'WindowButtonMotionFcn', '');
end
setappdata(0, 'GridEditorToolData', ad);
return
%%
function doChangeAllDeltaSt(allbtn, evd)
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'stage_info')
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
if isempty(ad.regions.stage_info)
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
prompt={'Enter Delta_St in hours:'};
name='Input for Delta_St';
numlines=1;
defaultanswer={'20'};

answer=inputdlg(prompt,name,numlines,defaultanswer);
if isempty(answer)
    return;
end
for i=1:length(ad.stage_grids)
    ad.stage_grids{i}.deltaSt = str2double(answer{1});
end
setappdata(0, 'GridEditorToolData', ad);
%updateStageInfo();
return

%%
function doChangeDeltaSt(chgbtn, evd)
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'stage_info')
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
if isempty(ad.regions.stage_info)
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
str = get(ad.handles.stageinfo_txt, 'String');
val = get(ad.handles.stageinfo_txt, 'Value');

prompt={'Enter Delta_St in hours:'};
name='Input for Delta_St';
numlines=1;
defaultanswer={'20'};

answer=inputdlg(prompt,name,numlines,defaultanswer);
if isempty(answer)
    return;
end
ad.stage_grids{val}.deltaSt = str2double(answer{1});
setappdata(0, 'GridEditorToolData', ad);
%updateStageInfo();
return
%%%
%
%%%
function doUseBaseGridForAll(usebase, evd)
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'stage_info')
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
if isempty(ad.regions.stage_info)
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
stages = ad.regions.stage_info.stages;
num_stages = length(stages);
stagedir = ad.regions.stage_info.staged_dir;
base_grid = ad.regions;

stage_grids = cell(num_stages-1,1);

interpbtn = questdlg('Would you like to interpolate your growth data?', ...
                         'Interpolation?', 'Yes', 'No', 'Yes');
  
                     
arealim = str2double(get(ad.handles.area_thr, 'String'));
min_number_sectors = str2double(get(ad.handles.min_number_sectors, 'String'));
smooth_flag = get(ad.handles.smooth_chk, 'Value');
h = waitbar(0,'Applying based grid to all stages please wait...');
for i=1:num_stages-1
    waitbar(i/num_stages, h);
    % Get the names of the stages and the order they need to be processed

    stage_names.prev = [stages{i}];
    stage_names.post = [stages{i+1}];
    % load the sector data for each stage for this grid
    [sectors_pre] = load_stage_sector_info([stagedir, filesep, stage_names.prev], arealim);
    [sectors_post] = load_stage_sector_info([stagedir, filesep, stage_names.post], arealim);

    % optimize the grid for those stages and calculate the average sector
    % and the growth tensor for each region.
    [stage_grid] =  calcRegionalGrowthTensors(base_grid, sectors_pre, sectors_post, min_number_sectors, smooth_flag);
    stage_grid.stage_info = stage_names;
    if strcmpi(interpbtn, 'yes')
        fprintf(' - interpolating from %s to %s\n', stages{i}, stages{i+1});
        stage_grid = interpolateGrowthField(stage_grid);
    end
    % assign each spring to the appropriate region.
    stage_grid = makeSpringsFromTri(stage_grid);
    stage_grid.deltaSt = 20;
    stage_grids{i} = stage_grid;
end

close(h);
ad.regions = base_grid;
% figure(1); clf;
% plot_grid(base_grid, gca);
% plot_grid(stage_grids{1}, gca);
ad.stage_grids = stage_grids;
fprintf('done.\n');
setappdata(0, 'GridEditorToolData', ad);
%updateStageInfo;
return

%%%
%
%%%
function doOptimizeGridForStages(opt_menu, evd)
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'stage_info')
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
if isempty(ad.regions.stage_info)
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
stages = ad.regions.stage_info.stages;
num_stages = length(stages);
stagedir = ad.regions.stage_info.staged_dir;
base_grid = ad.regions;

stage_grids = cell(num_stages-1,1);

arealim = str2double(get(ad.handles.area_thr, 'String'));
smooth_flag = get(ad.handles.smooth_chk, 'Value');

min_number_sectors = str2double(get(ad.handles.min_number_sectors, 'String'));
h = waitbar(0,'Optimizing grid please wait...');
for i=1:num_stages-1
    waitbar(i/num_stages, h);
    % Get the names of the stages and the order they need to be processed

    stage_names.prev = [stages{i}];
    stage_names.post = [stages{i+1}];
    % load the sector data for each stage for this grid
    %Erika
    [sectors_pre] = load_stage_sector_info([stagedir, filesep, stage_names.prev], arealim);
    [sectors_post] = load_stage_sector_info([stagedir, filesep, stage_names.post], arealim);

    stage_grid = optimizeGridForStagePair(base_grid, sectors_pre, sectors_post, min_number_sectors);
    % optimize the grid for those stages and calculate the average sector
    % and the growth tensor for each region.
    [stage_grid] =  calcRegionalGrowthTensors(stage_grid, sectors_pre, sectors_post, min_number_sectors, smooth_flag);
    stage_grid.stage_info = stage_names;
    % assign each spring to the appropriate region.
    stage_grid = makeSpringsFromTri(stage_grid);
    stage_grid.deltaSt = 20;
    stage_grids{i} = stage_grid;
end
close(h);
ad.regions = base_grid;
% figure(1); clf;
% plot_grid(base_grid, gca);
% plot_grid(stage_grids{1}, gca);
ad.stage_grids = stage_grids;
fprintf('done');
setappdata(0, 'GridEditorToolData', ad);
%updateStageInfo;
return
%%%
function doCountSectorsperRegion(count_menu, evd)
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'stage_info')
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
if isempty(ad.regions.stage_info)
    uiwait(msgbox('There are no stages selected for this grid.','No Stages','modal'));
    return;
end
stages = ad.regions.stage_info.stages;
num_stages = length(stages);
stagedir = ad.regions.stage_info.staged_dir;
base_grid = ad.regions;

stage_grids = cell(num_stages-1,1);

                     
h = waitbar(0,'Applying based grid to all stages please wait...');
for i=1:num_stages
    waitbar(i/num_stages, h);
    % Get the names of the stages and the order they need to be processed

    stage_names.prev = [stages{i}];
    % load the sector data for each stage for this grid
        [sectors_pre] = load_stage_info([stagedir, filesep, stage_names.prev]);
  
%     [sectors_pre] = load_stage_sector_xy([stagedir, filesep, stage_names.prev]);
%     [sectors_post] = load_stage_sector_xy([stagedir, filesep, stage_names.post]);
%     
    % optimize the grid for those stages and calculate the average sector
    % and the growth tensor for each region.
    [stage_grid] =  calcRegionalSectors(base_grid, sectors_pre);
    stage_grid.stage_info = stage_names;
     stage_grids{i} = stage_grid;
end
close(h);
ad.regions = base_grid;
% figure(1); clf;
% plot_grid(base_grid, gca);
% plot_grid(stage_grids{1}, gca);
ad.stage_grids = stage_grids;
fprintf('done.\n');
setappdata(0, 'GridEditorToolData', ad);
%updateStageInfo;
return

%%%
function grid = init_region_tri_ind(grid)
T = grid.tri_info.T;
ctrl_ind = cell(size(T,1),1);
tri_col = cell(size(T,1),1);
for i=1:size(T,1)
    ctrl_ind{i} = i;
    tri_col{i} = rand(1,3);
end
grid.region_tri_ind = ctrl_ind;
return
% %%%
% %
% %%%
% function xydata = loadDataForStage(stage, arealim)
% xydata = [];
% stage_files = findfiles('warped_sector_info.mat', stage);
% number_of_files_in_stage = length(stage_files);
% for ii = 1:number_of_files_in_stage
%     file = stage_files{ii};
%     sector_info = load(file);
%     sector_info = sector_info.warped_sector_info;
%     c = [sector_info.Centroid]';
%     area = [sector_info.ellipArea];
%     c = reshape(c, 2, length(c)/2);
% 
%     c(:, area<arealim) = [];
%     xydata = cat(2, xydata, c);
% end
% return

%%%%
%
%
%%%%
function doCalcRegionStats(region_stats_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
%R = ad.regions.R;
area_thr = get(ad.handles.area_thr, 'String');
area_thr = str2double(area_thr);

%centroids = ad.regions.centroids;
%if isempty(centroids)
%    return;
%end
if ~isfield(ad.regions, 'stage_info')
    uiwait(msgbox('You must select some stages to process first.','No Stages','modal'));
    return

end
if isempty(ad.regions.stage_info)
    uiwait(msgbox('You must select some stages to process first.','No Stages','modal'));
    return
end
FILES = ad.regions.stage_info.stages;
StagedDirString = ad.regions.stage_info.staged_dir;
fprintf('Calculating sector info for stages:\n');
for i=1:length(FILES)
    fprintf('%s\n', [StagedDirString, filesep, FILES{i}]);
end
av_info = cell(length(FILES), 1);
waitbar_h = waitbar(0, 'Calculating region statistics, please wait...');

grid = ad.regions;
T = grid.tri_info.T;
tri_pts = grid.tri_info.pts;


for i=1:length(FILES)
    stage = [StagedDirString, filesep, FILES{i}];
    [region_info, areas] = calc_stage_sector_info_for_trimesh(stage, T, tri_pts, grid.stage_tri_ind{i}, area_thr);
    %[region_info, areas] = calc_stage_sector_info(stage, R, centroids, area_thr);

    [av_info{i}.average_stage_sector_info] = calc_average_stage_sector_info(region_info);
    av_info{i}.stage = stage;
    av_info{i}.mean_area = mean(areas);
    %av_info{i}.median_area = median(areas);
    %av_info{i}.mode_area = mode(areas);
    waitbar(i/length(FILES), waitbar_h);
end
close(waitbar_h);
ad.av_info = av_info;
%ad.sector_region_info = sector_region_info;
setappdata(0, 'GridEditorToolData', ad);
%plotRegionInfo
% %%%%
% %
% %
% %%%%
% function doCalcRegionStats(region_stats_btn, evd)
% ad =getappdata(0, 'GridEditorToolData');
% R = ad.regions.R;
% area_thr = get(ad.handles.area_thr, 'String');
% area_thr = str2double(area_thr);
%
% centroids = ad.regions.centroids;
% if isempty(centroids)
%     return;
% end
% StagedDirString = ad.StagedDirString;
% FILES = dir(StagedDirString);
% if isempty(FILES);
%     return;
% end;
% FILES = {FILES.name};
% FILES = cleanup_stage_list(FILES);
% [s,v] = listdlg('Name', 'Select Stages To Calc. Region Stats', 'PromptString','Select the stages you wish to calculate regional statistical for:', 'SelectionMode','multiple', 'ListString',FILES, 'ListSize', [300, 200]);
% if isempty(s)
%     return;
% end
% pause(.01);
% FILES = FILES(s);
%
% number_of_regions = size(R,3)-1;
% av_info = cell(length(FILES), 1);
% allregionsgood = 0;
%             grid = ad.regions;
% while allregionsgood==0
%
%     waitbar_h = waitbar(0, 'Calculating region statistics, please wait...');
%     for i=1:length(FILES)
%         stage = [StagedDirString, filesep, FILES{i}];
%         [region_info, areas] = calc_stage_sector_info(stage, R, centroids, area_thr);
%
%         [av_info{i}.average_stage_sector_info, empty_reg_ind{i}, region_density{i}] = calc_average_stage_sector_info(region_info);
%         av_info{i}.stage = stage;
%         av_info{i}.mean_area = mean(areas);
%         %av_info{i}.median_area = median(areas);
%         %av_info{i}.mode_area = mode(areas);
%         waitbar(i/length(FILES), waitbar_h);
%     end
%     close(waitbar_h);
%     allregionsgood = 1;
%     regs = [];
%     for i=1:length(region_density)
%         stage_reg_density = region_density{i};
%         regs = cat(2, regs, find(stage_reg_density==0));
%     end
%     regs = unique(regs);
%     to_delete_ind = []
%     for i=1:length(regs)
%         mergeregs = setdiff(find(grid.region_adj_mat(regs(i),:)), regs);
%         grid.region_ctrl_pt_ind{regs(i)} = cat(2, grid.region_ctrl_pt_ind{regs(i)}, grid.region_ctrl_pt_ind{mergeregs(1)});
%
%         vertices = grid.control_pts(grid.region_ctrl_pt_ind{regs(i)},:);
%         [sctrlpts, ind] = order_xy_pts(vertices);
%         grid.region_ctrl_pt_ind{regs(i)} = grid.region_ctrl_pt_ind{regs(i)}(ind);
%
%         to_delete_ind = cat(2, to_delete_ind, mergeregs(1));
%     end
%     grid.region_ctrl_pt_ind(to_delete_ind) = [];
%
%     grid = build_regions(grid);
%     R = grid.R;
%     show_layers(grid.R, gca);
% end
% ad.av_info = av_info;
% ad.regions = grid;
% %ad.sector_region_info = sector_region_info;
% setappdata(0, 'GridEditorToolData', ad);
% plotRegionInfo
%%%
%
%
%%%
% function plotRegionInfo
% ad = getappdata(0, 'GridEditorToolData');
% centroids = ad.regions.centroids;
% if isempty(ad.av_info);
%     return;
% end
% av_info = ad.av_info{length(ad.av_info)}.average_stage_sector_info;
% av_info = ad.av_info{1}.average_stage_sector_info;
% 
% scale = 1;
% cla(ad.handles.thumb_axes);
% hold(ad.handles.thumb_axes, 'on');
% imagesc(ad.regions.R, 'Parent',ad.handles.thumb_axes);
% for ii=1:size(av_info,3)
%     eh = gtlib_plotGrowthTensor('growth_tensor', av_info(:,:,ii), 'offset', centroids(ii,:), 'Colour', [1 1 1], 'Parent', ad.handles.thumb_axes);
% end
% hold(ad.handles.thumb_axes, 'off');
% axis(ad.handles.thumb_axes, 'image', 'ij');
% set(ad.handles.thumb_axes, 'visible', 'off');
% setappdata(0, 'GridEditorToolData', ad);
%%%
%
%
%%%
function doLoadUngrownShape(load_ungrown_shape_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
[filename, pathname] = uigetfile('*.mat', 'Pick an Ungrowth File', [ad.UngrowthDataDir, filesep]);
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel')
else
    f = load([pathname, filesep, filename]);
    f = f.ungrown_grid;
    % We need to align and scale the ungrown shape to the mean shape
    templ.marks = double(ad.regions.shape(:,1:2)');
    data.marks = double(f(length(f)).shape(:,1:2)');
    [procdata,theta,templ] = procrustes(data,templ);
    N = length(f);
    S = f(N).S;
    GD = adjust_grid_data(f(N), theta);
    ad.regions.Springs.S = GD.S;
    ad.regions.Springs.Edgs = GD.Edgs;
    ad.regions.Springs.order = GD.order;
    ad.regions.control_pts = GD.control_pts;
    ad.regions.orig_control_pts = GD.control_pts;
    ad.regions.shape = GD.shape;
    ad.regions.REGS = GD.REGS;
    ad.mean_shape = (GD.shape);
    [ad.regions.xy_regions] = Edgs2xy_regions(ad.regions.Springs.Edgs, ad.regions.Springs.order);
end
setappdata(0, 'GridEditorToolData', ad);
cla(ad.handles.imageAxis);
doPlotAll;
return;
%%%
%
%
%%%
function [grid_data] = adjust_grid_data(grid_data, theta)
if nargin<2
    return;
end
grid_data.shape = align_vector(grid_data.shape, theta);
grid_data.S(:,end-1:end) = align_vector(grid_data.S(:,end-1:end), theta);
grid_data.Edgs(:,end-1:end) = align_vector(grid_data.Edgs(:,end-1:end), theta);
grid_data.edge_petal(:,1:2) = align_vector(grid_data.edge_petal(:,1:2), theta);
grid_data.control_pts = align_vector(grid_data.control_pts, theta);
return;
%%%
%
%
%%%
function v = align_vector(v, theta)
p = size(v,1);
v = double(v);
v = transpose(((1/theta.scale)*rotmat(theta.phi)')*(v' - theta.transl*ones(1,p)));
return;
%%%%
%
%
%
%%%%
function doOpenGrid(load_menu, evd)
ad =getappdata(0, 'GridEditorToolData');
[filename, pathname] = uigetfile('*.mat', 'Open a Grid File', [ad.GridDir, filesep]);
if isequal(filename,0) || isequal(pathname,0)
    disp('Cancel open grid');
    return
end
file = [pathname, filesep, filename];
if exist(file, 'file')
    region_info = load(file);
    ad.regions = region_info.base_grid;
    if isfield(region_info, 'stage_grids')
        ad.stage_grids = region_info.stage_grids;
        
    else
        ad.stage_grids = {};
    end
else
    ad.regions = init_regions_struct();
end
fprintf(' - grid has %d elements\n', size(ad.regions.tri_info.T,1));
ad.stage_grids
for i=1:length(ad.stage_grids)
    if ~isfield(ad.stage_grids{i}, 'deltaSt')
        ad.stage_grids{i}.deltaSt = 20;
    end
end
setappdata(0, 'GridEditorToolData', ad);
%updateStageInfo;
doPlotAll;
%plotRegionInfo;
%%%
%
%%%
function doConcavityCheck(concavity_check_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
if isempty(ad.regions)
    return;
end
if isempty(ad.regions.control_pts)
    return;
end
[xyreg, order, value] = ConcavityCheck('Springs', ad.regions.Springs.S, 'Edgs', ad.regions.Springs.Edgs, 'E',ad.regions.Springs.E, 'Order', ad.regions.order, 'Layers', ad.regions.layers); %
ad.regions.xy_regions = xyreg;
ad.regions.order = order;
grid_name = 'Untitled.mat';
setappdata(0, 'GridEditorToolData', ad);
doPlotAll;
%%%%
%
%
%
%%%%
function doWarpToShape(warp2shape_btn, evd)
ad = getappdata(0, 'GridEditorToolData');
[filename, pathname] = uigetfile('*.mat', 'Pick grown grid', [ad.GridDir, filesep]);
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel');
    return;
else
    grown_grid = load([pathname, filesep, filename]);
    grown_grid = grown_grid.region_info;
end
[filename, pathname] = uigetfile('*.mat', 'Pick grid to warp', [ad.GridDir, filesep]);
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel');
    return;
else
    new_grid = load([pathname, filesep, filename]);
    new_grid = new_grid.region_info;
end
grown_grid.control_pts = [];
gshape = grown_grid.shape;
nshape = new_grid.shape;
ctrlpts = new_grid.control_pts;
[wpts] = TPS_pts_warp(ctrlpts, nshape, gshape);
grown_grid.control_pts = wpts;
grown_grid = align_edge_vertices2edge(grown_grid, ad.edge_margin);
ad.regions = grown_grid;
setappdata(0, 'GridEditorToolData', ad);
%doUpdateGridList;
doPlotAll;
%%%
%
%%%
function [regions] = init_regions_struct
regions.R = [];
%regions.layers = [];
%regions.vertex = [];
%regions.edge = [];
regions.control_pts = [];
regions.shape = [];
regions.stage_info = [];
%regions.neighbours = [];
%regions.grid_xy = [];
regions.centroids = [];
%regions.order = [];
%regions.REGS = [];
regions.vert = [];
regions.region_vertices = [];
regions.region_vertices_ind = [];
regions.region_ctrl_pt_ind = [];

return;


%%%%
%
%
%
%%%%
% function doPlotCentroids()
% ad = getappdata(0, 'GridEditorToolData');
% cen = ad.regions.centroids;
% if ishandle(ad.centroid_plot_handle)
%     delete(ad.centroid_plot_handle);
%     ad.centroid_plot_handle = [];
% end
% if ~isempty(cen)
%     ad.centroid_plot_handle = plot(ad.handles.imageAxis, cen(:,1), cen(:,2), 'o', 'MarkerEdgeColor', 'y', 'MarkerFaceColor', 'y');
% end
% setappdata(0, 'GridEditorToolData', ad);
% return;


%%%%
%
%
%
%%%%
function doPlotSprings()
ad = getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'vert')
    return;
end
if isempty(ad.regions.vert)
    return;
end
if ishandle(ad.spring_line_handle)
    delete(ad.spring_line_handle);
    ad.spring_line_handle = [];
end
ad.spring_line_handle = plot_springs(ad.regions, ad.handles.imageAxis);
setappdata(0, 'GridEditorToolData', ad);
return

%%%
%
%%%
function doMakeSprings(springs_btn, evd)
ad = getappdata(0, 'GridEditorToolData');
%if isempty(ad.regions.region_vertices)
%    fprintf('You must select your region vertices first\n');
%    return;
%end
grid = ad.regions;
%grid = init_grid(grid);

[grid] = makeSpringsFromTri(grid);


%grid = interp_region_pts(grid);

%[grid] = makeInternalSprings(grid);
%[grid] = makeShapeSprings(grid);
%[grid] = makeExternalSprings(grid);
%[grid] = makeRegionSprings(grid);

ad.regions = grid;
setappdata(0, 'GridEditorToolData', ad);
doPlotAll;
return;
%%%
%
%%%
function doBuildRegions(auto_grid_btn, evd)

ad = getappdata(0, 'GridEditorToolData');
if isempty(ad.regions.control_pts)
    uiwait(msgbox('You must select your region vertices first','Error','modal'));
    return;
end
%ad.regions = divideRegionsByLongestEdge(ad.regions);
%ad.regions = divideRegionsByCentroid(ad.regions);
ad.regions = ad.stage_grids{1};
grid = ad.regions;
grid = build_regions(ad.regions);
show_layers(grid.R, ad.handles.thumb_axes);
set(ad.handles.thumb_axes, 'visible', 'off');
ad.regions = grid;
setappdata(0, 'GridEditorToolData', ad);
doPlotAll;
%%%
%
%%%
function shape = getmeanshape(ad)
shape = [];
if ~isfield(ad, 'mean_shape')
    fprintf(' - no field ad.mean_shape\n');
end
if isempty(ad.mean_shape)
    return;
end
shape = ad.mean_shape;
return;
%%%
%
%%%
function pts = getctrlpoints(ad)
shape = [];
if ~isfield(ad.regions, 'control_pts')
    fprintf(' - no field ad.regions.control_pts\n');
end
if isempty(ad.regions.control_pts)
    return;
end
pts = ad.regions.control_pts;
return;
%%%
%
%%%
function plotShape(ad)
shape = getmeanshape(ad);
if isempty(shape)
    return;
end
plot(ad.handles.imageAxis, shape(:,2), shape(:,1), 'go');
return
%%%
%
%%%
function plotCtrlPoints(ad)
pts = getctrlpoints(ad);
if isempty(pts)
    return;
end
plot(ad.handles.imageAxis, pts(:,1), pts(:,2), 's', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'y');
return
%%%
%
%%%
function drawOrganImage(ad)
shape = getmeanshape(ad);
if isempty(shape)
    return;
end
image_axis = ad.handles.imageAxis;
R = pts2binim(shape);
imagesc(R, 'Parent', image_axis); hold(image_axis, 'on');

return
%%%%
%
%%%%
function doSelectRegions(select_region_btn, evd)
ad = getappdata(0, 'GridEditorToolData');
fprintf('Entering Manual Grid Editing Mode.\n');
set(ad.figMain, 'WindowButtonDownFcn', '', 'WindowButtonMotionFcn' , '', 'WindowButtonUpFcn', '', 'BackingStore','on');
set(ad.handles.move_control_point_btn, 'Value', 0);
set(ad.handles.add_control_point_btn, 'Value', 0);
set(ad.handles.del_control_point_btn, 'Value', 0);

ad.regions.R = [];
ad.regions.centroids = [];
ad.regions.region_vertices = [];
ad.regions.region_vertices_ind = [];
ad.regions.adj_mat = [];
ad.regions.len_mat = [];
ad.regions.vert = [];

% Draw the organ image, the shape points and the control points
image_axis = ad.handles.imageAxis;
cla(image_axis);
drawOrganImage(ad);
plotShape(ad);
plotCtrlPoints(ad);
axis(image_axis, 'image');
colormap(image_axis, 'copper');
hold(image_axis, 'on');
% end of drawing

ctrl_pts = ad.regions.control_pts;
ad.regions.num_ctrl_pts = size(ctrl_pts,1);
pts = [ad.regions.shape; ctrl_pts];
pts = double(pts);
region_vertices_ind = {};
region_ctrl_pt_ind = {};
[xi,yi] = getline(image_axis, 'closed'); % Get rect info from the user.
while ~isempty(xi)
    if length(xi)>=3
        in = find(inpolygon(pts(:,1), pts(:,2), xi,yi));
        [rpts, ind] = order_xy_pts(pts(in,:));
        region_vertices_ind = cat(1, region_vertices_ind, in(ind));
        in = find(inpolygon(ctrl_pts(:,1), ctrl_pts(:,2), xi,yi));
        [sctrlpts, ind] = order_xy_pts(ctrl_pts(in,:));
        region_ctrl_pt_ind = cat(1, region_ctrl_pt_ind, in(ind));
        rpts = [rpts; rpts(1,:)];
        plot(image_axis, rpts(:,1), rpts(:,2), 'o-', 'Color', rand(1,3));
    end
    [xi,yi] = getline(image_axis, 'closed'); % Get rect info from the user.
end

ad.regions.region_vertices = pts;
ad.regions.region_vertices_ind = region_vertices_ind;
ad.regions.region_ctrl_pt_ind = region_ctrl_pt_ind;
setappdata(0, 'GridEditorToolData', ad);
return;
%%%
%
%%%
function doMoveCtrlPt(move_ctrl_pt_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'region_vertices_ind')
    return;
end
if isempty(ad.regions.control_pts)
    set(move_ctrl_pt_btn, 'Value', 0);
    return;
end
ad.regions = align_edge_vertices2edge(ad.regions, ad.edge_margin);
switch (get(move_ctrl_pt_btn, 'Value'))
    case 0
        ad.regions = align_edge_vertices2edge(ad.regions, ad.edge_margin);
        set(ad.figMain, 'Pointer', 'Arrow');
        set(ad.figMain, 'WindowButtonDownFcn', '', 'WindowButtonMotionFcn' , '', 'WindowButtonUpFcn', '', 'BackingStore','on');
        ad.ctrl_pt_handle = plot_grid(ad.regions,ad.handles.imageAxis) ;
    case 1
        fprintf('Entering Move Point Mode.\n');
        clear_view;
        ad = getappdata(0, 'GridEditorToolData');
        ad.ctrl_pt_handle = plot(ad.handles.imageAxis, ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 'o', 'MarkerEdgeColor', 'c', 'MarkerFaceColor', 'm');
        %ad.ctrl_pt_handle = plot_grid(ad.regions,ad.handles.imageAxis) ;
        setappdata(0, 'GridEditorToolData', ad);
        set(ad.figMain, 'Pointer', 'crosshair');
        set(ad.figMain, 'BackingStore', 'on', 'WindowButtonDownFcn',  {@select_ctrl_pt});
end
setappdata(0, 'GridEditorToolData', ad);
%%%%
%
%%%%
function select_ctrl_pt(fig, evd)
ad =getappdata(0, 'GridEditorToolData');
cp = get(ad.handles.imageAxis, 'CurrentPoint');
cp = cp(1,1:2);
ctrl_pts = [ad.regions.control_pts];
d = sqrt(sum((ctrl_pts - ones(size(ctrl_pts,1),1)*cp).^2,2));
[val, ind] = min(d);
ad.ctrl_pt_to_move = ind(1);
setappdata(0, 'GridEditorToolData', ad);
set(fig, 'WindowButtonMotionFcn', {@move_ctrl_pt}, 'WindowButtonUpFcn',  {@drop_ctrl_pt});
return;
%%%%
%
%
%
%%%%
function move_ctrl_pt(fig, evd)
ad =getappdata(0, 'GridEditorToolData');
if isempty(ad.ctrl_pt_to_move)
    return;
end
cp = get(ad.handles.imageAxis, 'CurrentPoint');
cp = cp(1,1:2);
pt2move = ad.ctrl_pt_to_move;
ad.regions.control_pts(pt2move,:) = cp;
ad.regions.region_vertices = [ad.regions.shape; ad.regions.control_pts];
setappdata(0, 'GridEditorToolData', ad);
clear_view;
ad.ctrl_pt_handle = plot(ad.handles.imageAxis, ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 'o', 'MarkerEdgeColor', 'c', 'MarkerFaceColor', 'm');
%ad.ctrl_pt_handle = plot_grid(ad.regions,ad.handles.imageAxis) ;
%ad.ctrl_pt_handle = plot_control_pts;
%doPlotRegions;
return;
%%%%
%
%
%
%%%%
function drop_ctrl_pt(fig, evd)
ad =getappdata(0, 'GridEditorToolData');
set(fig, 'WindowButtonMotionFcn' ,'','WindowButtonUpFcn','');
ad.ctrl_pt_to_move = [];
setappdata(0, 'GridEditorToolData', ad);
return;
%%%
%
%%%
function doDelCtrlPt(move_ctrl_pt_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
if ~isfield(ad.regions, 'region_vertices_ind')
    return;
end

if isempty(ad.regions.control_pts)
    set(move_ctrl_pt_btn, 'Value', 0);
    return;
end
switch (get(move_ctrl_pt_btn, 'Value'))
    case 0
        set(ad.figMain, 'Pointer', 'Arrow');
        set(ad.figMain, 'WindowButtonDownFcn', '', 'WindowButtonMotionFcn' , '', 'WindowButtonUpFcn', '', 'BackingStore','on');
        ad.ctrl_pt_handle = plot(ad.handles.imageAxis, ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 'o', 'MarkerEdgeColor', 'c', 'MarkerFaceColor', 'm');
    case 1
        fprintf('Entering Delete Point Mode.\n');
        clear_view;
        ad = getappdata(0, 'GridEditorToolData');
        ad.ctrl_pt_handle = plot(ad.handles.imageAxis, ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 'o', 'MarkerEdgeColor', 'c', 'MarkerFaceColor', 'm');
        setappdata(0, 'GridEditorToolData', ad);
        set(ad.figMain, 'Pointer', 'crosshair');
        set(ad.figMain, 'BackingStore', 'on', 'WindowButtonDownFcn',  {@delete_ctrl_pt});
end
setappdata(0, 'GridEditorToolData', ad);
%%%%
%
%%%%
function delete_ctrl_pt(fig, evd)
ad =getappdata(0, 'GridEditorToolData');
cp = get(ad.handles.imageAxis, 'CurrentPoint');
cp = cp(1,1:2);
ctrl_pts = [ad.regions.control_pts];
d = sqrt(sum((ctrl_pts - ones(size(ctrl_pts,1),1)*cp).^2,2));
[val, ind] = min(d);


ad.regions.control_pts(ind(1),:) = [];
ad.regions = init_grid(ad.regions);
grid.region_vertices = [];
grid.region_vertices_ind = [];
grid.region_ctrl_pt_ind = [];
grid.centroids = [];
N = size(ad.regions.shape,1);


regs_ctrl_ind = ad.regions.region_ctrl_pt_ind;
for i=1:length(regs_ctrl_ind)
    reg_ind = regs_ctrl_ind{i};
    reg_ind(reg_ind==ind(1)) = [];
    reg_ind(reg_ind>ind(1)) = reg_ind(reg_ind>ind(1))-1;
    regs_ctrl_ind{i} = reg_ind;
end
ad.regions.region_ctrl_pt_ind = regs_ctrl_ind;

clear_view;
ad.ctrl_pt_handle = plot(ad.handles.imageAxis, ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 'o', 'MarkerEdgeColor', 'c', 'MarkerFaceColor', 'm');
setappdata(0, 'GridEditorToolData', ad);
return;


% function delete_ctrl_pt(fig, evd)
% ad =getappdata(0, 'GridEditorToolData');
% ad.regions.region_vertices = [];
% cp = get(ad.handles.imageAxis, 'CurrentPoint');
% cp = cp(1,1:2);
% ctrl_pts = ad.regions.control_pts;
% [val, ind] = min(sqrt(sum((ctrl_pts - ones(size(ctrl_pts,1),1)*cp).^2,2)));
% ad.regions.control_pts(ind(1), :) = [];
% % We must also update the indices in REGS
% for i=2:length(ad.regions.REGS)
%     r = ad.regions.REGS{i}.vertex;
%     r(r == ind(1)) = [];
%     indx = find(r > ind(1));
%     r(indx) = r(indx) - 1;
%     ad.regions.REGS{i}.vertex = r;
% end
% setappdata(0, 'GridEditorToolData', ad);
% clear_view;
% if ~isempty(ad.regions.control_pts)
%     plot(ad.handles.imageAxis,ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 's', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'y');
% end
% return;
%%%%
%
%
%
%%%%
function doAddCtrlPt(add_ctrl_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
switch (get(add_ctrl_btn, 'Value'))
    case 0
        ad.regions = align_edge_vertices2edge(ad.regions, ad.edge_margin);
        clear_view;
        if ~isempty(ad.regions.control_pts)
            plot(ad.handles.imageAxis, ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 's', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'y');
        end
        set(ad.figMain, 'Pointer', 'Arrow');
        set(ad.figMain, 'WindowButtonDownFcn', '', 'WindowButtonMotionFcn' , '', 'WindowButtonUpFcn', '', 'BackingStore','on');
    case 1
        fprintf('Entering Manual Control Point Placing Mode.\n');
        clear_view;
        if ~isempty(ad.regions.control_pts)
            plot(ad.handles.imageAxis,ad.regions.control_pts(:,1), ad.regions.control_pts(:,2), 's', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'y');
        end
        colormap copper;
        fprintf('Place Control Points\n');
        set(ad.figMain, 'Pointer', 'crosshair');
        set(ad.figMain, 'BackingStore', 'off', 'WindowButtonDownFcn',  {@place_ctrl_pt});
end
setappdata(0, 'GridEditorToolData', ad);

%%%%
%
%
%
%%%%
function place_ctrl_pt(fig, evd)
ad =getappdata(0, 'GridEditorToolData');
ad.regions.region_vertices = [];
cp = get(ad.handles.imageAxis, 'CurrentPoint');
cp = cp(1,1:2);
fprintf(' - x: %4.2f, y: %4.2f.\n', cp(1), cp(2));
hold(ad.handles.imageAxis, 'on');
plot(ad.handles.imageAxis,cp(1), cp(2), 's-', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'y');
ad.regions.control_pts = [ad.regions.control_pts; cp];
setappdata(0, 'GridEditorToolData', ad);
return;
%%%%
%
%
%
%%%%
function clear_view()
ad = getappdata(0, 'GridEditorToolData');
shape = fliplr(ad.regions.shape(:,1:2));
ad.mean_shape = shape;
image_axis = ad.handles.imageAxis;
R = pts2binim(shape);
shape = fliplr(shape);
cla(image_axis);
imagesc(R, 'Parent', image_axis); hold(image_axis, 'on');
axis(image_axis, 'image');
ad.mean_shape_plot_handle = plot(image_axis, shape(:,1), shape(:,2), 'go');
colormap(image_axis, 'copper');
setappdata(0, 'GridEditorToolData', ad);
return
%%%%
%
%
%
%%%%
function doPlotMeanShape
ad = getappdata(0, 'GridEditorToolData');
if ishandle(ad.mean_shape_plot_handle)
    delete(ad.mean_shape_plot_handle);
    ad.mean_shape_plot_handle = [];
end
ad.mean_shape_plot_handle = plot(ad.handles.imageAxis, ad.mean_shape(:,2), ad.mean_shape(:,1), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y', 'Color', 'b');
setappdata(0, 'GridEditorToolData', ad);
return;
%%%
%
%%%
function doPlotGrid
ad = getappdata(0, 'GridEditorToolData');
if ishandle(ad.grid_plot_handle)
    delete(ad.grid_plot_handle);
    ad.grid_plot_handle = [];
end
ad.grid_plot_handle = plot_grid(ad.regions, ad.handles.imageAxis);
setappdata(0, 'GridEditorToolData', ad);
return;
%%%
%
%%%
function doEditEdgePoints(edit_edge_btn, evd)
ad =getappdata(0, 'GridEditorToolData');
if isempty(ad.regions.control_pts)
    return;
end
Edgs = ad.regions.Springs.Edgs_All;
Spr = ad.regions.Springs.S;
xyreg = ad.regions.xy_regions;
removed_ind = ad.regions.Springs.edges_removed_ind;
[ad.regions.Springs.Edgs, ad.regions.Springs.edges_removed_ind, ad.regions.order, value] = EditEdgePoints('Springs', Spr, 'Edges', Edgs, 'xyregs', xyreg, 'removed_indices', removed_ind, 'order', ad.regions.order, 'Layers', ad.regions.layers);
ad.regions.order = makeorder(ad.regions.Springs.S, ad.regions.Springs.Edgs);
setappdata(0, 'GridEditorToolData', ad);
region_info = ad.regions;
doPlotAll;
return;
%%%
%
%%%
function doSaveGrid(save_grid_btn, evd)
ad = getappdata(0, 'GridEditorToolData');
set(ad.figMain, 'Pointer', 'watch');

fprintf('Saving grid data...\n');
grid_name = 'Untitled.mat';
[filename, pathname] = uiputfile(grid_name, 'Pick an Grid Filename', [ad.GridDir, filesep, grid_name]);
if isequal(filename,0) || isequal(pathname,0)
    disp('Cancelled grid save.')
    set(ad.figMain, 'Pointer', 'arrow');
    return;
end
base_grid = ad.regions;
stage_grids = ad.stage_grids;
save([pathname, filename], 'base_grid', 'stage_grids', '-mat');
fprintf('done.\n');
uiwait(msgbox('Finished saving your grid data.','Save Done','modal'));
set(ad.figMain, 'Pointer', 'arrow');
ad.grid_name = [pathname,filesep, filename];
setappdata(0, 'GridEditorToolData', ad);
return;
%%%
%
%%%
function doPlotAll
ad =getappdata(0, 'GridEditorToolData');
clear_view;
doPlotGrid;
doPlotMeanShape;
%doPlotCentroids;
doPlotSprings;
axis(ad.handles.imageAxis, 'image', 'ij');

%%%
%
%%%
function customtoolbar(figh)
hA = findall(figh);
openfileh=findobj(hA,'TooltipString','Open File');
set(openfileh, 'ClickedCallback', {@doOpenGrid});
set(openfileh, 'TooltipString', 'Open Grid File');
newgridh=findobj(hA,'TooltipString','New Figure');
set(newgridh, 'ClickedCallback', {@doNewGrid});
set(newgridh, 'TooltipString', 'New Grid');
saveh=findobj(hA,'TooltipString','Save Figure');
set(saveh, 'ClickedCallback', {@doSaveGrid});
set(saveh, 'TooltipString', 'Save Grid');
roth=findobj(hA,'TooltipString','Rotate 3D');
datah=findobj(hA,'TooltipString','Data Cursor');
colbarh=findobj(hA,'TooltipString','Insert Colorbar');
legh=findobj(hA,'TooltipString','Insert Legend');
hideh=findobj(hA,'TooltipString','Hide Plot Tools');
showh=findobj(hA,'TooltipString','Show Plot Tools and Dock Figure');
delete([roth, datah, colbarh, legh, hideh, showh]);
