%%%%%%%%%%%%%%%%%%%%%
%
% Update Point Models
%
% Description: This tool asks the user for a revised template file and an
% old tempalte file, if the template files are similar, then the point
% models associated with the old template file are updated.
%
% Dr. A. I. Hanna (2005)
%
function [] = UpdatePointModels()
% Check to make sure that the toolbox is installed and them cd to the
% Models Directory
p = which ('AAMToolbox');
p = fileparts(fileparts(p));
if isempty( strfind(pwd, 'Models'))
    if ~exist([p, filesep, 'Models'])
        uiwait(warndlg(sprintf('You must have a directory called Models.\n i.e. C:\\...\\Shape_models\\Models\nSee Dummies Guide for more details.'), 'Directory Hierarchy Error!'));
        return;
    end
    cd([p, filesep, 'Models']);
end
% Load the new and improved template
[new_pmt, new_dir] = loadTemplate('Select the new template file');
if isempty(new_pmt)
    return;
end
% Select the old ready to be improved template (this gives us the path to
% the point models that we need to upate.
[old_pmt, old_dir] = loadTemplate('Select the old template file');
    prj_dir =  fileparts(old_dir(1:length(old_dir)-1));
if isempty(old_pmt)
    return;
end

new_pts = get(new_pmt, 'pts');
pts = get(old_pmt, 'pts');
if validateTemplates(new_pmt, old_pmt)
   diff_pts = diffPts(new_pmt, old_pmt);
   for i = 1:size(diff_pts, 2)
       x = diff_pts(1,i); y = diff_pts(2,i);
       d = sqrt((pts(1,:) - x).^2 + (pts(2,:) - y).^2);
       [Y,I] = sort(d);
       I = I(1:2);
       v1 = [x - pts(1, I(1)) , y - pts(2, I(1))];
       v2 = [pts(1, I(2)) - pts(1, I(1)), pts(2, I(2)) - pts(2, I(1))];
       theta = acos(dot(v1, v2)/(norm(v1)*norm(v2)));
       c1 = cos(theta)*norm(v1);
       c2 = norm(v2) - c1;
       k = c1/c2;
       v3 = (v2/norm(v2))*c1;
       v3 =[ pts(1, I(1)) pts(1, I(1))+v3(1)], [pts(2, I(1)) pts(2, I(1))+v3(2)];
       handles.dat.k = k;
       handles.dat.neighbours = I;
       v1 = [x - pts(1, I(2)) , y - pts(2, I(2))];
       v1 = [v1, 0]';
       v2 =[v2, 0]';
       c = cross(v1, v2);
       handles.dat.theta =-1*sign(c(3))*theta;
       handles = GlobalAdd(handles, prj_dir, old_pmt);
   end
end
PMTemplate = new_pmt;
save([old_dir, filesep, get(PMTemplate, 'name')], 'PMTemplate');
[path, templatename, ext, vers] = fileparts(get(PMTemplate, 'name'));
dirname=[prj_dir, filesep, 'StatisticalModels', filesep, templatename];
if exist(dirname)
    models = findfiles('aam_dat', dirname)
    for m = 1:length(models)
        aam = load(models{m}, '-mat');
        aam = aam.aam;
        aam = set(aam, 'PointModelTemplate', PMTemplate);
        save(models{m}, 'aam');
    end
    UpdateModelSaveNewSet(templatename,ext,old_dir(1:end-length('\Templates\')));
end
%%%%%%%%%%%%%%%%%%%%%%
%
%   Global Add
%
%%%%%%%%%%%%%%%%%%%%%%
function [handles] = GlobalAdd(handles, prj_dir, pmt)

templatename = get(pmt, 'name');
templatename = templatename(1:length(templatename)-9);
n = handles.dat.neighbours;
theta = handles.dat.theta;
k = handles.dat.k;
files = dir([prj_dir, filesep, 'PointModels', filesep, templatename, filesep, '*_pm.mat']);

for i=1:length(files)
    p = load([prj_dir, filesep, 'PointModels', filesep, templatename, filesep, files(i).name]);
    p = p.pts; p = reshape(p, 2, length(p)/2);
    V1 = [p(1, n(2)) - p(1, n(1)), p(2, n(2)) - p(2, n(1))];
    v1 = norm(V1);
    V1 = V1/v1;
    v1 = V1*(v1 - (v1/(k+1)));
    R = rotmat(theta);
    V2 = (R*V1')';
    o = tan(theta)*(norm(v1));
    v2 = sqrt(o^2 + (norm(v1))^2)*V2;
    new_p = [p(1, n(1))+v2(1); p(2, n(1))+v2(2)];
    p = [p, new_p];
    pts = p(:);
     save([prj_dir, filesep, 'PointModels', filesep, templatename, filesep, files(i).name], 'pts');
end
return
%%%%%%%%%%%%%%%%%%%%%
%
% Load Templates
%
%%%%%%%%%%%%%%%%%%%%%

function [pmt, pathname] = loadTemplate(s)
[filename, pathname] = uigetfile('*.temp_dat', s);
if isequal(filename,0) | isequal(pathname,0)
    disp('User pressed cancel')
    pmt=[];
    pathname=[];
else
    disp(['User selected ', fullfile(pathname, filename)])
    pmt = load([pathname, filesep, filename], '-mat');
    pmt = pmt.PMTemplate;
end
%%%%%%%%%%%%%%%%%%%%%
%
% ValidateTemplates
%
%%%%%%%%%%%%%%%%%%%%%
function [diff_pts] = diffPts(new_pmt, old_pmt)
new_pts = get(new_pmt, 'pts');
old_pts = get(old_pmt, 'pts');
    diff_pts = new_pts(:, size(old_pts, 2)+1:end);
%%%%%%%%%%%%%%%%%%%%%
%
% ValidateTemplates
%
%%%%%%%%%%%%%%%%%%%%%
function [flag] = validateTemplates(new_pmt, old_pmt)
new_pts = get(new_pmt, 'pts');
old_pts = get(old_pmt, 'pts');
flag = 1;
if size(new_pts, 2) > size(old_pts, 2)
    % There are some extra points, so need to add them
    error = new_pts(:, 1:size(old_pts,2)) - old_pts;
    error = sum(error(1,:).^2 - error(2,:).^2);
    % If the sum of the squared error between the old points is not zero,
    % then the templates do not match.
    if error > 0
        fprintf('There is a discrepency between points, templates do not match!!!\n');
        flag = 0;
        return;
    end
else
    flag = 0;
end