%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PlaceLandmarksSimple
%
% Uses the edge information of the binary image to place landmarks along
% the boundary
function [] = NonlinearOptimisationPlace(arg)
global AAMShapemodel_figure_handle
global AAMModelGenerator_handle
global AAMModelBuilder_handle
global AAMSetPicker_handle
global UpdateModel_handle
global PMTemplateBuilder_handle
global PDMWalk_handle
global ShapeSpaceTool_handle
global PreProcess_gui_handle;
global PlaceLandmarks_gui_handle;
global NonlinearOptimisationPlace_gui_handle;

if isa(arg, 'AAM')
    if exist('AAMShapemodel_figure_handle')
    if ishandle(AAMShapemodel_figure_handle)
        set(AAMShapemodel_figure_handle,'visible','off');
    end
end
    NonlinearOptimisationPlace_gui_handle = openfig(mfilename, 'reuse');
    Data.handles = guihandles(NonlinearOptimisationPlace_gui_handle);
    Data.handles.figMain = NonlinearOptimisationPlace_gui_handle;
    Data.handles.aam = arg;
    Data.handles.dat.npts = [];
    Data.handles = Init(Data.handles);
    Data.handles.dat.points_plot_handle = [];
    guidata(NonlinearOptimisationPlace_gui_handle, Data);
else
    Data = guidata(NonlinearOptimisationPlace_gui_handle);
    switch arg
        case 'ClickPrimaries'
            [Data.handles] = ClickPrimaries(Data.handles);
        case 'Next'
            [Data.handles] = Next(Data.handles);
        case 'Skip'
            [Data.handles] = Skip(Data.handles);
        case 'Prev'
            [Data.handles] = Prev(Data.handles);
        case 'Quit'
            if exist('AAMShapemodel_figure_handle')
                if ishandle(AAMShapemodel_figure_handle)
                    set(AAMShapemodel_figure_handle,'visible','on');
                end
            end
            [Data.handles] = Quit(Data.handles);       
        otherwise
            disp('Unknown option');
    end
    if isfield(Data.handles, 'figMain')
        guidata(NonlinearOptimisationPlace_gui_handle, Data);
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Quit
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Quit(handles)
delete(handles.figMain);
handles = rmfield(handles, 'figMain');
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Next
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Next(handles)
N = length(handles.dat.files);
v = get(handles.filenameList, 'value');
if (v < N)
    v = v +1;
    handles.dat.currentIndex =   handles.dat.currentIndex + 1;
else
    v = N;
end
set(handles.filenameList, 'value', v);
handles = Skip(handles);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Prev
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Prev(handles)
N = length(handles.dat.files);
v = get(handles.filenameList, 'value');
if (v > 1)
    v = v -1;
    handles.dat.currentIndex =   handles.dat.currentIndex + 1;
else
    v = 1;
end
set(handles.filenameList, 'value', v);
handles = Skip(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Skip
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Skip(handles)

handles.dat.npts = [];
handles.dat.currentIndex = get(handles.filenameList, 'value');
I = imread([handles.dat.directoryname, filesep,handles.dat.files{handles.dat.currentIndex}]);
I = double(I);
handles.dat.CurrentImage = I./max(I(:));
handles.dat.CurrentImageName = handles.dat.files{handles.dat.currentIndex};
handles.dat.CurrentImageDir = handles.dat.directoryname;
[path, filename, ext, vers] = fileparts(handles.dat.CurrentImageName);
handles.dat.CurrentImageName
handles.dat.edge_filename = [handles.dat.directoryname, filesep,'Binary', filesep, 'edge_', filename, '.edge_dat'];
if exist(handles.dat.edge_filename)
    handles.dat.edge = load(handles.dat.edge_filename, '-mat');
    handles.dat.pts = double(handles.dat.edge.sorted_edge)';
    handles.dat.pts = flipud(handles.dat.pts);
end
[path, templatename, ext, vers] = fileparts(get(handles.PMT, 'name'));

 if exist(['PointModels', filesep, templatename, filesep, filename, '_pm.mat'])
     pts = load(['PointModels', filesep, templatename, filesep, filename, '_pm.mat']);
     pts = pts.pts;
     pts = reshape(pts, 2, length(pts)/2);
     handles.dat.npts = pts;
 end
handles = UpdateImage(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Update Image
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = UpdateImage(handles)
cla(handles.targetAxis);
npts = handles.dat.npts;
temp_pri = sort(get(handles.PMT, 'primaries'));

imagesc(handles.dat.CurrentImage, 'Parent', handles.targetAxis, 'HitTest', 'off');
axis(handles.targetAxis, 'image');
hold(handles.targetAxis, 'on');

%     temp_pri = temp_pri(1:end-1);
%
handles.dat.points_plot_handle = [];
if size(npts,1)>0
    handles.dat.points_plot_handle(end+1) = plot(handles.targetAxis, npts(1,:), npts(2,:), 'o', 'MarkerFaceColor', 'y', 'MarkerEdgeColor', 'b');
    handles.dat.points_plot_handle(end+1) = plot(handles.targetAxis, npts(1,temp_pri), npts(2,temp_pri), 'o', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'b');

 s = {num2str(transpose(1:size(npts,2)))};

 text_h =  text(npts(1,:), npts(2,:), s, 'parent', handles.targetAxis, 'Color', 'w');
 handles.dat.points_plot_handle = [handles.dat.points_plot_handle, text_h'];
 end
%     drawnow;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ClickPrimaries
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = ClickPrimaries(handles)
cla(handles.targetAxis);
imagesc(handles.dat.CurrentImage, 'Parent', handles.targetAxis, 'HitTest', 'off');
axis(handles.targetAxis, 'image');
temp_pts = get(handles.PMT, 'pts');
temp_pri = sort(get(handles.PMT, 'primaries'));
pts = handles.dat.pts;
if(size(pts,1)>2)
    return;
end
X = [];
Y = [];
for i=1:length(temp_pri)
    [x, y] = ginput(1);
    X(end+1) = x;
    Y(end+1) = y;
    plot(handles.targetAxis, X, Y, 'o', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'b');
end
cla(handles.targetAxis);
temp_pri
X
Y
size(X)
size(Y)
pts = NonlinearOptimisationFit([temp_pts(1,:); temp_pts(2,:)], [X; Y], temp_pri);

pts
 handles.dat.npts = pts;
 [handles] = UpdateImage(handles);
% 
% %[X,Y] = ginput(length(temp_pri));
% 
% distances = sqrt((pts(1,:) - X(1)).^2 + (pts(2,:) - Y(1)).^2);
% dist = find(distances == min(distances));
% pts = [pts(:, dist:end), pts(:, 1:dist-1)];
% for p = 1:length(X)
%     distances = sqrt((pts(1,:) - X(p)).^2 + (pts(2,:) - Y(p)).^2);
%     dist(p) = find(distances == min(distances));
% end
% if length(dist)>2
%     if dist(3) < dist(2)
%         pts = fliplr(pts);
%         distances = sqrt((pts(1,:) - X(1)).^2 + (pts(2,:) - Y(1)).^2);
%         dist = find(distances == min(distances));
%         pts = [pts(:, dist:end), pts(:, 1:dist-1)];
%     end
% end
% for p = 1:length(X)
%     distances = sqrt((pts(1,:) - X(p)).^2 + (pts(2,:) - Y(p)).^2);
%     dist(p) = find(distances == min(distances));
% end
% num_points = size(temp_pts, 2);
% npts = zeros(size(temp_pts));
% npts(:, temp_pri) = pts(:, dist);
% dist = [dist, size(pts, 2)];
% temp_pri = [temp_pri(:); size(temp_pts, 2)+1];
% for i=2:length(dist)
%     side_pts  = temp_pri(i) - temp_pri(i-1)-1;
%     e1 = dist(i-1); e2 = dist(i);
%     ind = round((e2-e1)/(side_pts+1));
%     ptstemp = dist(i-1)+ind:ind:dist(i-1)+side_pts*ind;
%     npts(:, temp_pri(i-1)+1:temp_pri(i)-1) = pts(:, ptstemp);
% end
% pts = npts(:);
% [path, templatename, ext, vers] = fileparts(get(handles.PMT, 'name'));
% [path, filename, ext, vers] = fileparts(handles.dat.CurrentImageName);
% 
% save(['PointModels', filesep, templatename, filesep, filename, '_pm.mat'], 'pts');
% handles.dat.npts = npts;
% [handles] = UpdateImage(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Init
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Init(handles)
[filename, pathname] = uigetfile('*.temp_dat', 'Pick Template File');
if isequal(filename,0) | isequal(pathname,0)
    disp('User pressed cancel')
    handles.PMT = PointModelTemplate;
    return;
else
    PMT = load([pathname, filesep, filename], '-mat');
    handles.PMT = PMT.PMTemplate;
    disp(['User selected ', fullfile(pathname, filename)])
end
temp_pts = get(handles.PMT, 'pts');
temp_pri = sort(get(handles.PMT, 'primaries'));
if (length(temp_pri)<1)
    error('Need at least 1 primary point to determine direction of flow');
    return;
end
handles.dat.directoryname = 'Cropped';
if ~exist(handles.dat.directoryname, 'dir')
    uiwait(warndlg('Cannot find the ''Cropped'' directory, exiting.'));
    return;
end
handles.dat.files = dir([handles.dat.directoryname, filesep, '*.jpg']);
handles.dat.files = {handles.dat.files.name};
 
 if length(handles.dat.files)>0
    set(handles.filenameList, 'String', handles.dat.files);
    set(handles.filenameList, 'value', 1);
    handles.dat.currentIndex = 1;
    handles = Skip(handles);
    handles = UpdateImage(handles);
else
    set(handles.filenameList, 'String', 'No images');
    set(handles.filenameList, 'value', 1);
    handles.dat.currentIndex = 1;
 end
 % Now we must plot the template and its points with labels
 handles.N = size(temp_pts,2);
[path, templatename, ext, vers] = fileparts(get(handles.PMT, 'name'));
 if ~exist(['PointModels', filesep, templatename], 'dir')
     mkdir(['PointModels', filesep, templatename]);
 end
 imagesc(get(handles.PMT, 'image'), 'parent', handles.templateAxis); 
 axis(handles.templateAxis, 'image'); 
 hold(handles.templateAxis, 'on');
 plot(handles.templateAxis, temp_pts(1,:), temp_pts(2,:), 'o', 'MarkerFaceColor', 'y', 'MarkerEdgeColor', 'b');
 plot(handles.templateAxis, temp_pts(1,temp_pri), temp_pts(2,temp_pri), 'o', 'MarkerFaceColor', 'g', 'MarkerEdgeColor', 'b');
 s = {num2str(transpose(1:size(temp_pts,2)))};
 text(temp_pts(1,:), temp_pts(2,:), s, 'parent', handles.templateAxis, 'Color', 'w');
 return;
