%Hanna, 2005

function [xyreg, order, value] = ConcavityCheck(varargin)
error(nargchk(0,inf,nargin));
ad.value = 0;
ad.Edgs = [];
ad.Spr = [];
ad.E = [];
ad.order = [];
ad.toremove = [];
ad.xyreg = [];
ad.R = [];
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 'springs'
            ad.Spr = varargin{i+1};
        case 'edgs'
            ad.Edgs = varargin{i+1};
        case 'e'
            ad.E = varargin{i+1};
        case 'order'
            ad.order = varargin{i+1};       
        case 'layers'
            ad.R = varargin{i+1};
        otherwise
            error(['Unknown parameter name passed to LISTDLG.  Name was ' varargin{i}])
    end
end
if isempty(ad.Spr)
    error('Springs parameter is required.')
end
if isempty(ad.Edgs)
    error('Edges parameter is required.')
end
if isempty(ad.E)
    error('E parameter is required.')
end

if isempty(ad.order)
    T = size(ad.Spr,1);
    Q = ad.Edgs;
    Q(ad.toremove,:) = [];
    NEdg = Q(:,1:T);
    for i=1:T
        indx=find(NEdg(:,i));
        ad.order{i} = indx;
    end
end
for i=1:length(ad.order)
   o = ad.order{i};
   ad.xyreg{i} = [ad.Edgs(o,end-1), ad.Edgs(o,end)];
end

% 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(handles.finished_btn, 'callback', {@doOk});
set(handles.cancel_btn, 'callback', {@doCancel});
set(handles.image_axis, 'ButtonDownFcn', {@doAxisClicked});
set(handles.region_list, 'callback', {@doChangeRegion});
set(handles.next_btn, 'callback', {@doNext});
set(handles.prev_btn, 'callback', {@doPrev});

% Initialize the application data structure
ad.figMain = fig;
ad.handles = handles;
ad.markerplot_handle = [];
ad.grid_handle = [];
ad.text_handle = [];

setappdata(0,'ConcavityCheckData',ad);
init_gui;

try
    uiwait(fig);
catch
    if ishandle(fig)
        delete(fig)
    end
end
if isappdata(0,'ConcavityCheckData')
    ad = getappdata(0,'ConcavityCheckData');
    xyreg = ad.xyreg;
    order = ad.order;
    value = ad.value;
    rmappdata(0,'ConcavityCheckData')
else
    % figure was deleted
    xyreg = [];
    order = [];
    value = 0;
end
return;

function init_gui()
ad =getappdata(0, 'ConcavityCheckData');
Spr = ad.Spr;
Edgs = ad.Edgs;
ad.nx=size(Edgs,2)-1;
ad.ny=size(Edgs,2);
imagesc(ad.R, 'Parent', ad.handles.image_axis, 'HitTest', 'off');
hold(ad.handles.image_axis, 'on');
set(ad.handles.image_axis, 'XTick', [], 'YTick', [], 'XTickLabel', [], 'YTickLabel', []);
%grid(ad.handles.image_axis, 'on');
%set(ad.handles.image_axis, 'Color', [0 0 0]);
for k=1:size(Edgs,1), 
   ad.markerplot_handle(end+1) = plot(ad.handles.image_axis, Edgs(k,ad.nx),Edgs(k,ad.ny),'o', 'MarkerFace', 'y', 'MarkerEdge', 'r', 'HitTest', 'off');
end;
ad.T=size(Spr,1);
ad.NEdg=Edgs(:,1:ad.T);
for i=1:ad.T; ad.liststring{i} = num2str(i); end;
set(ad.handles.region_list, 'String', ad.liststring);
setappdata(0, 'ConcavityCheckData', ad);
doChangeRegion;
return;

function doChangeRegion(region_list, evd)
ad =getappdata(0, 'ConcavityCheckData');
NEdg = ad.NEdg;
Edgs = ad.Edgs;
region_number = get(ad.handles.region_list, 'value');
indx=find(NEdg(:,region_number));
set(ad.markerplot_handle, 'MarkerFace', 'y', 'MarkerEdge', 'r');
set(ad.markerplot_handle(ad.order{region_number}), 'MarkerFace', 'b', 'MarkerEdge', 'y');
for i = 1:length(indx); s{i} = num2str(i); end;
if ishandle(ad.text_handle)
    delete(ad.text_handle);
end
if ishandle(ad.grid_handle)
    delete(ad.grid_handle);
end

if ~isempty(ad.order{region_number})
    x = Edgs(ad.order{region_number},ad.nx); x = [x; x(1)];
    y = Edgs(ad.order{region_number},ad.ny); y = [y; y(1)];
    ad.grid_handle = plot(ad.handles.image_axis, x, y, 'HitTest', 'off', 'LineWidth', 3, 'Color', 'r');
end
ad.text_handle = text(Edgs(indx,ad.nx), Edgs(indx,ad.ny), s, 'Background', 'w', 'Color', 'k', 'HitTest', 'off', 'FontWeight', 'bold', 'Clipping', 'on', 'FontSize', 12, 'Parent', ad.handles.image_axis);

axis(ad.handles.image_axis, 'image', 'xy');
setappdata(0, 'ConcavityCheckData', ad);


return;

function doOk(ok_btn, evd)
ad =getappdata(0, 'ConcavityCheckData');
ad.value = 1;
ad.Edgs(ad.toremove, :) = [];
setappdata(0, 'ConcavityCheckData', ad);
delete(gcbf);

function doNext(next_btn, evd)
ad =getappdata(0, 'ConcavityCheckData');
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, 'ConcavityCheckData', ad);
doChangeRegion;
function doPrev(prev_btn, evd)
ad =getappdata(0, 'ConcavityCheckData');
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, 'ConcavityCheckData', ad);
doChangeRegion;
function doCancel(cancel_btn, evd)
ad =getappdata(0, 'ConcavityCheckData');
ad.selection = [];
ad.value = 0;
setappdata(0, 'ConcavityCheckData', ad);
delete(gcbf);



function doAxisClicked(ok_btn, evd)
ad =getappdata(0, 'ConcavityCheckData');
click_type = get(ad.figMain, 'SelectionType');
switch click_type
    case 'normal'
        pt = get(ad.handles.image_axis, 'CurrentPoint');
        pt = pt(1,1:2);
        if ishandle(ad.text_handle)
            delete(ad.text_handle);
        end
        if ishandle(ad.grid_handle)
            delete(ad.grid_handle);
        end
        NEdg = ad.NEdg;
        Edgs = ad.Edgs;
        region_number = get(ad.handles.region_list, 'value');
        indx=find(NEdg(:,region_number));
        X = ad.Edgs(:, end-1);
        Y = ad.Edgs(:, end);
        pts = [X, Y];
        o = [];
        button = 1;
        while button == 1
            [xp, yp, button] = ginput(1);
            %for i=1:length(indx)
            p = [xp, yp];
            d = sqrt(sum((pts - ones(size(pts,1),1)*p).^2,2));
            [val, ind] = min(d);
            o(end+1) = ind;
        end
        ad.order{region_number} = o;
        ad.xyreg{region_number} = [ad.Edgs(o,end-1), ad.Edgs(o,end)];
        setappdata(0, 'ConcavityCheckData', ad);
        doChangeRegion;
    case 'alt'
        doNext;
    otherwise
        return;
end

