%Hanna, 2005

function [grid_pts, value] = SelectGridPointsUtil(varargin)
error(nargchk(0,inf,nargin));
ad.value = 0;
ad.shape = [];
ad.warped_pts = [];
if (mod(length(varargin),2) ~= 0) & (length(varargin)<6)
    % input args have not com in pairs, woe is me
    error('Arguments to LISTDLG must come param/value in pairs.')
end
for i=1:2:length(varargin)
    switch lower(varargin{i})
        case 'shape'
            ad.shape = varargin{i+1};
        case 'warped_pts'
            ad.warped_pts = varargin{i+1};
        otherwise
            error(['Unknown parameter name passed to SelectGridPointsUtil.  Name was ' varargin{i}])
    end
end
if isempty(ad.shape)
    error('Shape parameter is required.')
end
if isempty(ad.warped_pts)
    error('warped_pts parameter is required.')
end
ad.all_pts = [ad.shape; ad.warped_pts];
% Open, move, and get the handles from the figure file.
fig = openfig(mfilename, 'reuse');
% Move the gui and then show it, rather than have it jump all over the
% place.
movegui(fig, 'center');
set(fig, 'visible', 'on');
handles = guihandles(fig);
% Set all the callback functions
%set(fig, 'WindowButtonDown', {@doMouseClicked});
%set(fig, 'WindowButtonUp', {@doMouseReleased});

set(handles.region_list, 'callback', {@doChangeRegion});
set(handles.image_axis, 'ButtonDownFcn', {@doAxisClicked});
set(handles.ok_btn, 'callback', {@doOk});


% Initialize the application data structure
% Initialize the application data structure
ad.figMain = fig;
ad.value = 0;
ad.handles = handles;
ad.region_pts_handle = [];
ad.grid_pts = [];
ad.grid_plot_handle = [];
ad.grid_edge_handle = [];
ad.curr_grid_edge_handle = [];
setappdata(0,'SelectGridPointsUtilData',ad);
init_gui;
doPlotRegions;
doChangeRegion(ad.handles.region_list);
try
    uiwait(fig);
catch
    if ishandle(fig)
        delete(fig)
    end
end
if isappdata(0,'SelectGridPointsUtilData')
    ad = getappdata(0,'SelectGridPointsUtilData');
    value = ad.value;
    grid_pts = ad.grid_pts;
    rmappdata(0,'SelectGridPointsUtilData')
else
    % figure was deleted
    grid_pts = [];
    value = 0;
end
return;
function init_gui()
ad =getappdata(0, 'SelectGridPointsUtilData');
num_regions = max(ad.shape(:,3));
for i=2:num_regions; s{i-1} = num2str(i-1); end;
set(ad.handles.region_list, 'String', s);


function doPlotRegions()
ad =getappdata(0, 'SelectGridPointsUtilData');
if isempty(ad.shape)
    return;
end
ad.region_pts_handle = [];
hold(ad.handles.image_axis, 'on'); 
for i=2:max(ad.all_pts(:,3))   
    ind = find(ad.all_pts(:,3) == i);
    ad.region_pts_handle(end+1) = plot(ad.handles.image_axis, ad.all_pts(ind,1), ad.all_pts(ind,2), 'o', 'HitTest', 'off');
end
axis(ad.handles.image_axis, 'image', 'ij');
setappdata(0, 'SelectGridPointsUtilData', ad);



function doMouseClicked(fig, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
cp = get(ad.figMain, 'CurrentPoint');
cp = cp(1,1:2);
ad.PointToMove = [cp(1) cp(2)];
setappdata(0, 'SelectGridPointsUtilData', ad);
disp('clicked');

function doMouseReleased(fig, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
disp('released');

function doOk(ok_btn, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
ad.value = 1;
setappdata(0, 'SelectGridPointsUtilData', ad);
delete(gcbf);

function doNext(next_btn, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
str = get(ad.handles.region_list, 'string');
val = get(ad.handles.region_list, 'value');
if val<length(str)
    val = val+1;
end
set(ad.handles.region_list, 'value', val);
setappdata(0, 'SelectGridPointsUtilData', ad);
doChangeRegion;


function doPrev(prev_btn, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
str = get(ad.handles.region_list, 'string');
val = get(ad.handles.region_list, 'value');
if val>1
    val = val-1;
end
set(ad.handles.region_list, 'value', val);
setappdata(0, 'SelectGridPointsUtilData', ad);
doChangeRegion;


function doChangeRegion(region_list, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
shape = ad.shape;
warped_pts = ad.warped_pts;
allpts = ad.all_pts;
region_number = get(ad.handles.region_list, 'value');
indx=find(allpts(:,3) == region_number+1);
if ishandle(ad.grid_plot_handle); delete(ad.grid_plot_handle); end;
if ~isempty(ad.grid_pts)
    indg=find(ad.grid_pts(:,3) == region_number);
    ad.grid_plot_handle = plot(ad.handles.image_axis, ad.grid_pts(indg,1), ad.grid_pts(indg,2), 'bo', 'HitTest', 'off');
end
set(ad.region_pts_handle, 'MarkerFace', 'w', 'MarkerEdge', 'g');
set(ad.region_pts_handle(region_number), 'MarkerFace', 'y', 'MarkerEdge', 'r');
%ad.grid_pts = order_pts(ad.grid_pts);
setappdata(0, 'SelectGridPointsUtilData', ad);
plot_grid;
return;



function plot_grid
ad =getappdata(0, 'SelectGridPointsUtilData');
grid_pts = ad.grid_pts;
if isempty(grid_pts)
    return; 
end
if ishandle(ad.grid_edge_handle)
    delete(ad.grid_edge_handle);
end;
ad.grid_edge_handle = [];
for i=1:max(grid_pts(:,3))
   ind = find(grid_pts(:,3)==i);
   r = grid_pts(ind,1:2);
   if ~isempty(r)
    r = [r; r(1,:)];
    ad.grid_edge_handle(end+1) = plot(ad.handles.image_axis, r(:,1), r(:,2), '-', 'HitTest', 'off');
   end
end
region_number = get(ad.handles.region_list, 'value');
ind = find(grid_pts(:,3)==region_number);
if ishandle(ad.curr_grid_edge_handle)
    delete(ad.curr_grid_edge_handle);
end;
ad.curr_grid_edge_handle = plot(ad.handles.image_axis, grid_pts(ind,1), grid_pts(ind,2), 'r:', 'HitTest', 'off');

setappdata(0, 'SelectGridPointsUtilData', ad);

return;
function doAxisClicked(ok_btn, evd)
ad =getappdata(0, 'SelectGridPointsUtilData');
click_type = get(ad.figMain, 'SelectionType');
switch click_type
    case 'normal'
        pt = get(ad.handles.image_axis, 'CurrentPoint');
        pt = pt(1,1:2);
        shape = ad.shape;
        grid_pts = ad.grid_pts;
        all_pts = ad.all_pts;
        region_number = get(ad.handles.region_list, 'value');
        d = sqrt((all_pts(:,1) - pt(1)).^2 + (all_pts(:,2)- pt(2)).^2);
        [val, pos] = min(d);
        p = all_pts(pos,1:2);

        if isempty(grid_pts)
            grid_pts = [p, region_number];
        else
            ind = find(grid_pts(:,3)==region_number);
            if isempty(ind)
                    grid_pts = [grid_pts; [p, region_number]];
            else
                d = sqrt(sum((grid_pts(ind,1:2) - ones(size(grid_pts(ind,1:2),1),1)*p).^2,2));
                ind = find(d < 0.00001);

                if isempty(ind)
                    grid_pts = [grid_pts; [p, region_number]];
                else
                    ind = ind(1);
                    ind2 = find(grid_pts(:,3)==region_number);
                    ind = ind2(ind);
                    grid_pts(ind,:) = [];
                end
            end
        end
        ad.grid_pts = grid_pts;
        setappdata(0, 'SelectGridPointsUtilData', ad);
        plot_grid;
    case 'alt'
        doNext;
    otherwise
        return;
end

