function ModelGeneratorTool(varargin)
%   Dr. A. I. Hanna (2005) CMP, UEA, 2006.
%   generates statistical models using PCA from point models
global AAMModelGenerator_handle
error(nargchk(0,inf,nargin));
ad.data.details = [];
ad.data.template = [];
ad.data.pointset = [];
if mod(length(varargin),2) ~= 0
    % input args have not com in pairs, woe is me
    error('Arguments to ModelGeneratorTool must come param/value in pairs.')
end
for i=1:2:length(varargin)
    switch lower(varargin{i})
        case 'template'
            ad.data.template = varargin{i+1};
            tempname = get(ad.data.template, 'name');
            [p, ad.data.templatename, ext] = fileparts(tempname);
        case 'pointset'
            ad.data.pointset = varargin{i+1};
            %ad.data.pointset = {'set_2'};
        case 'details'
            ad.data.details = varargin{i+1};
        otherwise
            error(['Unknown parameter name passed to ModelGeneratorTool.  Name was ' varargin{i}])
    end
end
if isempty(ad.data.template)
	error('TEMPLATE parameter is required.');
end
if isempty(ad.data.pointset)
	error('POINTSET parameter is required.');
end
% Open, move, and get the handles from the figure file.
fig = openfig(mfilename, 'reuse');
AAMModelGenerator_handle=fig;
% 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(fig, 'Color', get(handles.mainPanel, 'BackgroundColor'));
% Setup the callback handles

% General Callbacks
set(handles.imageList, 'callback', {@doChangeImageList});
set(handles.generateModelBtn, 'callback', {@doGenerateStatisticalModels});
set(handles.selectElementsBtn, 'callback', {@doCreateNewImageList});
set(handles.Exit, 'callback', {@doExit});
set(handles.ModelGenerator, 'CloseRequestFcn', {@doExit});

% Visual Callbacks
set(handles.landmarksChk, 'callback', {@doToggleLandmarks});
set(handles.labelingChk, 'callback', {@doToggleLabels});
set(handles.linesChk, 'callback', {@doToggleEdges});

% Menu Callbacks
set(handles.showalignedshapesmenu, 'callback', {@doShowAlignedShapes});
set(handles.showorigshapesmenu, 'callback', {@doShowOriginalShapes});
set(handles.deleteimagelistsmenu, 'callback', {@doDeleteImageLists});
set(handles.importlistmenu, 'callback', {@doImportImageList});
set(handles.createfromaugexcel_menu, 'callback', {@doCreateImageListFromAugExcelFile});
set(handles.scalePointModels, 'callback',{@doScalePointModels});

% Initialize the application data structure
ad.figMain = fig;
ad.handles = handles;

ad.dirs.pmdir = [pwd, filesep, 'PointModels'];
ad.dirs.groups = [pwd, filesep, 'Groups'];
ad.dirs.cropped = [pwd, filesep, 'Cropped'];
ad.dirs.statmodels = [pwd, filesep, 'StatisticalModels'];
ad.dirs.templates = [pwd, filesep, 'Templates'];
ad = plotTemplate(ad);
ad = updateImageList(ad);

setappdata(0,'ModelGeneratorToolData',ad);
ad = plotPointsToUse(ad);

setappdata(0,'ModelGeneratorToolData',ad);
doChangeImageList(ad.handles.imageList);

%setappdata(0,'ModelGeneratorToolData',ad);

% display some information
set(handles.Allpoints,'string',ad.data.pointset);
H=findobj(AAMModelGenerator_handle,'type','uicontrol');
set(H,'fontsize',12);
H=findobj(AAMModelGenerator_handle,'type','uipanel');
set(H,'fontsize',12);
%doChangeImageList(ad.handles.imageList);
ad = plotPointsToUse(ad);

% try
%     uiwait(fig);
% catch
%     if ishandle(fig)
%         delete(fig)
%     end
% end
return;
%%%
%
%%%
function doExit(chk, evd)
    global AAMShapemodel_figure_handle
    global AAMModelGenerator_handle % OK so this is somewhat dirty, but it is old code being revisited
    set(AAMShapemodel_figure_handle, 'Visible', 'on');
    delete(AAMModelGenerator_handle);
    AAMToolbox('RefreshGUI');% CHECK THIS

    disp('Exit')
return
    
% Added 17/06/11 by J Newman
function ad = plotPointsToUse(ad)
    tempAppData = getappdata(0,'ModelGeneratorToolData');
    pointindices = [];
    if isfield(tempAppData.data,'aam')
        % Grab the template set points
        pointindices = get(tempAppData.data.aam, 'pointindices');
    end
    % Plot the template set points as diamonds
    if ~isempty(pointindices)
        t = ad.data.template;
        axish = ad.handles.mainAxes;
        hold(axish, 'on');
        pts = get(t, 'pts');
        ad.data.plothandles.usepts = plot(axish, pts(1,pointindices), pts(2,pointindices), 'p', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'w','MarkerSize',12);
        hold(axish, 'off');
    end
return;

function ad = plotTemplate(ad)
if isempty(ad.data.template)
    return;
end
t = ad.data.template;
axish = ad.handles.mainAxes;
% Added 17/06/2011
ad.data.plothandles.usepts = '';
%set(axish,'CameraUpVector',[0,-1,0]);
hold(axish, 'on');
im = get(t, 'image');
pts = get(t, 'pts');
edges = get(t, 'loops'); 
if ~isempty(edges)
    edges = edges{1};
end
str = cell(size(pts,2),1);
for i=1:size(pts,2); str{i} = num2str(i); end;
if ~isempty(im)
    ad.data.plothandles.image = imagesc(im, 'Parent', axish);
    set(axish,'ydir','reverse');
else
    ad.data.plothandles.image = [];
end
ad.data.plothandles.edges = [];

if isProject3D(pwd)
    for i=1:size(edges,1)
        ad.data.plothandles.edges(end+1) = plot3(axish, [pts(1,edges(i,1)) pts(1,edges(i,2))], [pts(2,edges(i,1)) pts(2,edges(i,2))], [pts(3,edges(i,1)) pts(3,edges(i,2))], '-', 'Color', 'r', 'LineWidth', 2);
    end
else
    for i=1:size(edges,1)
        ad.data.plothandles.edges(end+1) = plot(axish, [pts(1,edges(i,1)) pts(1,edges(i,2))], [pts(2,edges(i,1)) pts(2,edges(i,2))], '-', 'Color', 'r', 'LineWidth', 2);
    end
end
if isProject3D(pwd)
    ad.data.plothandles.pts = plot3(axish, pts(1,:), pts(2,:), pts(3,:), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    ad.data.plothandles.text = text(pts(1,:), pts(2,:), pts(3,:),str, 'Parent', axish, 'HorizontalAlignment', 'center');
   	axis(axish, 'image', 'xy');
	view(axish, 3);
else
    ad.data.plothandles.pts = plot(axish, pts(1,:), pts(2,:), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    ad.data.plothandles.text = text(pts(1,:), pts(2,:), str, 'Parent', axish, 'HorizontalAlignment', 'center');
	%axis(axish, 'image', 'xy');
    axis(axish, 'image');    
	view(axish, 2);
end

hold(axish, 'off');

toggleVisuals(ad);
return;
%%%
%
%%%
function toggleVisuals(ad)
toggleLabels(ad);
toggleLandmarks(ad);
toggleEdges(ad);
return;
%%%
%
%%%
function toggleLabels(ad)
str = 'off';
if get(ad.handles.labelingChk, 'value')
    str = 'on';
end
set(ad.data.plothandles.text, 'Visible', str);
return;
%%%
%
%%%
function toggleLandmarks(ad)
str = 'off';
if get(ad.handles.landmarksChk, 'value')
    str = 'on';
end
set(ad.data.plothandles.pts, 'Visible', str);
% Added 17/06/2011
set(ad.data.plothandles.usepts, 'Visible', str);
return;
%%%
%
%%%
function toggleEdges(ad)
str = 'off';
if get(ad.handles.linesChk, 'value')
    str = 'on';
end
set(ad.data.plothandles.edges, 'Visible', str);
return;
%%%
%
%%%
function doToggleLandmarks(chk, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
toggleLandmarks(ad);
setappdata(0,'ModelGeneratorToolData', ad);
%%%
%
%%%
function doToggleLabels(chk, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
toggleLabels(ad);
setappdata(0,'ModelGeneratorToolData', ad);
%%%
%
%%%
function doToggleEdges(chk, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
toggleEdges(ad);
setappdata(0,'ModelGeneratorToolData', ad);
%%%
%
%%%
function doChangeImageList(listbox, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData'); % CHECK THIS
set(ad.figMain, 'Pointer', 'watch');
drawnow;
imlist = ad.data.imagelists{get(ad.handles.imageList, 'value')};
direc = [ad.dirs.statmodels, filesep, ad.data.templatename, filesep, ad.data.pointset];
modelname=[direc, filesep, imlist, filesep, 'model.aam_dat'];
if exist(modelname, 'file')
    aam = load(modelname, '-mat');
    ad.data.aam = aam.aam;
	details = get(ad.data.aam, 'procrustesParams');
    ad = setDetails(ad, details);
    imagenames = get(ad.data.aam, 'am_imagenames');
    set(ad.handles.filenamesList, 'String', imagenames);
end
set(ad.figMain, 'Pointer', 'arrow');
setappdata(0,'ModelGeneratorToolData', ad);
doUpdateModelDirectoryString;
return;
%%%
%
%%%
function doUpdateModelDirectoryString
ad = getappdata(0,'ModelGeneratorToolData');
modelDirectory = get(ad.data.aam, 'modelDirec');
set(ad.handles.modeldirtxt, 'String', fullfile(pwd,modelDirectory));
setappdata(0,'ModelGeneratorToolData', ad);
return;
%%%
%
%%%
function ad = setDetails(ad, details)
set(ad.handles.translationChk, 'Value', details.translation);
set(ad.handles.rotationChk, 'Value', details.rotation);
set(ad.handles.scalingChk, 'Value', details.scaling);
return
%%%
%
%%%
function procrustesParams = getDetails(ad)
procrustesParams.translation = get(ad.handles.translationChk, 'Value');
procrustesParams.rotation = get(ad.handles.rotationChk, 'Value');
procrustesParams.scaling = get(ad.handles.scalingChk, 'Value');
return
%%%
%
%%%
function ad = updateImageList(ad)
    direc = [ad.dirs.statmodels, filesep, ad.data.templatename, filesep, ad.data.pointset];
    [imagelists,named] = getImageLists2(direc);% CHECK THIS
    ad.data.imagelists = imagelists;
    ad.data.imagelistsnames = named;
    val = get(ad.handles.imageList, 'Value');
    set(ad.handles.imageList, 'Value', min(val, length(ad.data.imagelistsnames)));
    set(ad.handles.imageList, 'String', ad.data.imagelistsnames);
    return
%%%
%
%%%
function ad = getImageLists(ad)
direc = [ad.dirs.statmodels, filesep, ad.data.templatename, filesep, ad.data.pointset];
[imagelists,named]=getImageLists2(direc)
ad.data.imagelists = imagelists;
ad.data.imagelistsnames = named;
return
%%%
%
%%%
function doGenerateStatisticalModels(genbtn, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
if isempty(get(ad.handles.filenamesList, 'String'))
    uiwait(msgbox(sprintf('There are no ''Active Images''. Cannot build model.\nTry Re-Choosing the Template.'),'Ooops','modal'));
    return;
end
ad = calculateShapeModel(ad);
if get(ad.handles.shape_app_radio_btn, 'value')==1
    ad = calculateAppearanceModel(ad);
else
    % Remove the appearance model if there is one already there.
    direc = get(ad.data.aam, 'modelDirec');
    sfamfilename = [direc, filesep, 'mod_sfam.mat'];
    if exist(sfamfilename, 'file')
        delete(sfamfilename);
    end
end
aam = ad.data.aam;
saveFilename=[get(aam, 'modelDirec'), filesep, 'model.aam_dat'];
save(saveFilename, 'aam');% CHECK THIS
fprintf(1,'Your AAM statistical model has been saved in %s\n',saveFilename);
setappdata(0,'ModelGeneratorToolData', ad);
string=sprintf('Your AAM statistical model has been saved in\n%s',saveFilename);
uiwait(msgbox(string,'Saved','modal'));

%AAMToolbox('RefreshGUI');% CHECK THIS
%%%
%
%%%
function ad = calculateAppearanceModel(ad)
aam = ad.data.aam;
numPix = str2double(get(ad.handles.numPixTxt, 'String'));
trithr = str2double(get(ad.handles.IgnoreTrianglesValue,'String'));
var_to_cover = str2double(get(ad.handles.FractionPCs,'String'));
verbose = get(ad.handles.verbose_chk, 'value');
imagelist = ad.data.imagelists{get(ad.handles.imageList, 'value')};
pointindices = get(aam, 'pointindices');
options = buildOptionsStructure(aam, var_to_cover, pointindices, ad.data.pointset, imagelist);

if get(ad.handles.usemaskchk, 'value')
    boundary_filename = [ad.dirs.templates, filesep, ad.data.templatename, '.boundary'];
    if exist(boundary_filename, 'file')
        boundary_index = load(boundary_filename, '-mat');
        boundary_index = boundary_index.boundary_index;
        fprintf(' - using boundary mask file\n');
    else
        fprintf(' - could not find a suitable boundary mask file\n');
        boundary_index = [];
    end
else
    boundary_index = [];
    fprintf(' - NOT using boundary mask file\n');
end

[sfam, options] = buildsfam(options, numPix, var_to_cover, trithr, ad.data.templatename, verbose, boundary_index);
sfam.critical_triangle_expansion = trithr;
direc = [pwd, filesep, get(aam, 'modelDirec')];
save([direc, filesep, 'mod_sfam.mat'], 'sfam');
return;
%%%
%
%%%
function options = buildOptionsStructure(aam, var_to_cover, pointindices, pointset, imagelist)
% We need to create the default list of options
p = pwd;
PMTDirec = get(get(aam, 'PointModelTemplate'),'direc');
PMTName = get(get(aam, 'PointModelTemplate'),'name');
ModelName = get(aam, 'modelName');
options.FractionPCs=var_to_cover;
options.Type = 'soptions';
options.CWD = pwd;
options.InputDirectory = [get(aam, 'imageDirectory'), filesep];
options.InputFilenames = get(aam, 'am_imagenames');
options.InputType = 0;
options.InputStartFrame = 1;
options.InputStartMovie = 1;
options.PointModelFile = PMTDirec(length(p)+2:end);
options.MeshFile = '';
options.MeshMappingFile = '';
options.PDMFile = [get(aam, 'modelDirec'), filesep, ModelName(1:length(ModelName)-10), '_pdm.mat'];
options.GLDMFile = '';
options.SFAMFile = '';
options.SAMFile = '';
options.LabelMode = 0;
options.FitterType = 0;
options.OutputDirectory = '';
options.Output3DVertices = '';
options.Output3DVerticesD = '';
options.OutputShapePCA = '';
options.OutputTexturePCA = '';
options.OutputCombinedPCA = '';
options.OutputType = 0;
options.ShowLandmarkSets = 0;
options.ShowPicture = 1;
options.TryFit = 1;
options.IncludeRotate = 0;
options.GLDMType = 1;
options.FITPOINTTYPE = 1;
options.subject = '';
options.Tryfit = 0;
%options.ProcrustesAlignment = handles.dat.ProcrustesAlignment;
options.img = get(get(aam, 'PointModelTemplate'),'imageName');
options.pdm = '';
options.sfam = '';
options.PMdirectory = ['PointModels', filesep, PMTName(1:length(PMTName)-9), filesep];
options.dat = '';
options.indices = pointindices;
[pointsetdirec, a, b] = fileparts(get(aam, 'modelDirec'));
if exist([pointsetdirec, filesep, 'context.mat'], 'file')
    context = load([pointsetdirec, filesep, 'context.mat']);
    options.indices = context.context;
end
PMTName = PMTName(1:length(PMTName)-9);
options.imagesDir = ['StatisticalModels', filesep, PMTName, filesep, pointset, filesep, imagelist];
return
%%%
%
%%%
function ad = calculateShapeModel(ad)
get(ad.data.aam,'modelDirec');
aam = ad.data.aam;
template = ad.data.template;
[dims, numpts] = size(get(template, 'pts'));
% Setup the procrustes parameters
procrustesParams = getDetails(ad);
aam = set(aam, 'procrustesParams', procrustesParams);
% Read in the point models
aam = read_in_pointmodels(aam, isProject3D(pwd), get(ad.handles.scaleptschk, 'Value'));

% Align pm's according to procrustes parameters
w = waitbar(0, 'Building shape models, please wait...');
waitbar(1/4, w);
project2tangent_space_flag = get(ad.handles.prjtangentchk, 'value');
[aam, Xm] = alignPointModels(aam, project2tangent_space_flag);
if isempty(Xm)
    fprintf('*** There were no point models to align\n');
    return
end
waitbar(2/4, w);
var_to_cover = str2num(get(ad.handles.FractionPCs,'String')); %#ok<ST2NM>
in_context_flag = get(ad.handles.context_chk, 'Value');
pdm = buildShapeModel(aam, Xm, var_to_cover, numpts, in_context_flag);
waitbar(3/4, w);
direc = [pwd, filesep, get(aam, 'modelDirec')];% CHECK THIS
saveFilename=[direc, filesep, 'mod_pdm.mat'];
fprintf(1,'Save model in %s\n',saveFilename);
save(saveFilename, 'pdm');
waitbar(4/4, w);
close(w);
ad.data.aam = aam;
return;
%%%
%
%%%
function pdm = buildShapeModel(aam, Xm, var_to_cover, numtemplatepts, in_context_flag)
elements = get(aam, 'elements');
X = [];
indices = get(aam, 'pointindices');
if isProject3D(pwd)
    dim = 3;
else
    dim =2;
end
Xm = reshape(Xm, dim, length(Xm)/dim);
ind = setdiff(1:size(Xm,2), indices); % ind indexes the points NOT in the set to be modelled
[pointsetdirec, a, b] = fileparts(get(aam, 'modelDirec'));
if in_context_flag
    context = 1:size(Xm,2);
    save([pointsetdirec, filesep, 'context.mat'], 'context');
else
    if exist([pointsetdirec, filesep, 'context.mat'], 'file')
        delete([pointsetdirec, filesep, 'context.mat']);
    end
end
% Take account of Sets (i.e. only model using points specified by indices)
for i=1:length(elements)
    e = elements{i};
    pts = get(e, 'alignedPts');
    if ~isempty(pts)
        if (size(pts,2)== numtemplatepts)
            if in_context_flag % replace points not in the set to be modelled (indices) by mean so they don't affect model
                pts(:, ind) = Xm(:, ind);
            else
                pts = pts(:, indices);
            end
            X(:,end+1) = pts(:); %#ok<AGROW>
        else
            fprintf('WARNING: %s has wrong number of points\n', get(e, 'imagefilename'));
        end
    end
end
[Xm, P, b, pca] = principal_component_analysis(X, var_to_cover);
if isempty(Xm)
	uiwait(msgbox('There are not point models to process. Exiting.','No Point Models','modal'));
end
pdm.Xm = Xm;
pdm.P = P;
pdm.b = b;
pdm.pca = pca;
pdm.FractionPCs=var_to_cover;
return
%%%
%
%%%
function [aam, Xm] = alignPointModels(aam, project2tangentspaceflag)
X = getaampointmodels(aam);
if isempty(X)
    Xm = [];
    return;
end
details = get(aam, 'procrustesParams');
%[X_aligned, proc_alignment] = pmalign(X, [details.scaling details.rotation details.translation], [], isProject3D(pwd));
if isProject3D(pwd)
    dim = 3;
else
    dim = 2;
end 
[X_aligned, template] = pcalib_GPA('data', X, 'opts', details, 'dimension', dim);
 
% figure(1); clf; hold on;
%     %plot3(template(1,:), template(2,:), template(3,:), 'gx');
%  for i=1:size(X_alignedgpa,2)
%     p = reshape(X_alignedgpa(:,i), dim, size(X_alignedgpa,1)/dim);
%     plot(p(1,:), p(2,:), 'ro');
%        p = reshape(X_aligned(:,i), dim, size(X_aligned,1)/dim);
%     plot(p(1,:), p(2,:), 'go');
%  end
  
 
%[X_aligned, template] = pcalib_GPA('data', X, 'opts', [details.scaling details.rotation details.translation]);
Xm = mean(X_aligned, 2);
elements = get(aam, 'elements');
for p=1:size(X_aligned,2)
    pts = X_aligned(:, p);
    if project2tangentspaceflag
        pts = project2tangentspace(pts, Xm);
    end
    pts = reshape(pts, dim, length(pts)/dim);
    elements{p} = set(elements{p}, 'alignedPts', pts);
end
aam = set(aam, 'elements', elements);
return;
%%%
%
%%%
function X = getaampointmodels(aam)
X = [];
elements = get(aam, 'elements');
for e =1:length(elements)
    pts = get(elements{e}, 'pts');
    if size(pts, 2) >0
        X(:, e) = pts(:);
    end
end
return;
%%%
%
%%%
function doShowAlignedShapes(showmenu, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
aam = ad.data.aam;
if isempty(aam)
    return;
end
if isProject3D(pwd)
    dim = 3;
else
    dim = 2;
end
edges = get(ad.data.template, 'loops');
if ~isempty(edges)
    edges = edges{1};
else
    edges = [];
end
elements = get(aam, 'elements');
figh = figure;
axish = gca;
hold(axish, 'on');
set(ad.figMain, 'Pointer', 'watch');
drawnow;
M = min(20, length(elements));
for k=1:M
    e = elements{k};
    pts = get(e, 'alignedPts');
    if dim ==3
        if ~isempty(edges)
            for i=1:size(edges,1)
                plot3(axish, [pts(1,edges(i,1)) pts(1,edges(i,2))], [pts(2,edges(i,1)) pts(2,edges(i,2))], [pts(3,edges(i,1)) pts(3,edges(i,2))], '-', 'Color', 'r', 'LineWidth', 2);
            end
        end
        plot3(axish, pts(1,:), pts(2,:), pts(3,:), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y', 'MarkerSize', 3);
    else

        if ~isempty(pts)
            for i=1:size(edges,1)
                plot(axish, [pts(1,edges(i,1)) pts(1,edges(i,2))], [pts(2,edges(i,1)) pts(2,edges(i,2))], '-', 'Color', 'r', 'LineWidth', 2);
            end
        end
        plot(axish, pts(1,:), pts(2,:), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y', 'MarkerSize', 3);
    end
end

axis(axish, 'image', 'xy');
grid(axish, 'on');
title(axish, 'Aligned Shapes');
set(figh, 'Name', 'Aligned Shapes Figure');
set(ad.figMain, 'Pointer', 'arrow');
setappdata(0,'ModelGeneratorToolData', ad);
return
%%%
%
%%%
function doDeleteImageLists(delmenu, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
names = ad.data.imagelistsnames;
imagelists = ad.data.imagelists;

[s,v] = listdlg('PromptString','Select a list to delete:', 'SelectionMode','multiple', 'ListString',names);
if isempty(s)
    return;
end
for i=1:length(s)
    list = imagelists{s(i)};
    direc = ['StatisticalModels', filesep, ad.data.templatename, filesep, ad.data.pointset, filesep, list];
    [succ, msg, msgid] = rmdir([pwd, filesep, direc], 's');
end
ad = updateImageList(ad);
setappdata(0,'ModelGeneratorToolData',ad);
doChangeImageList(ad.handles.imageList);
%%%
%
%%%
function doShowOriginalShapes(showmenu, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
aam = ad.data.aam;
if isempty(aam)
    return;
end
if isProject3D(pwd)
    dim = 3;
else
    dim = 2;
end
edges = get(ad.data.template, 'loops');
if ~isempty(edges)
    edges = edges{1};
else
    edges = [];
end
elements = get(aam, 'elements');
figh = figure;
axish = gca;
hold(axish, 'on');
set(ad.figMain, 'Pointer', 'watch');
drawnow;
M = min(20, length(elements));
for i=1:M
    e = elements{i};
    pts = get(e, 'pts');
    if ~isempty(edges)
        if dim==3
            for ii=1:size(edges,1)
                plot3(axish, [pts(1,edges(ii,1)) pts(1,edges(ii,2))], [pts(2,edges(ii,1)) pts(2,edges(ii,2))], [pts(3,edges(ii,1)) pts(3,edges(ii,2))], '-', 'Color', 'r', 'LineWidth', 2);
            end
        else
            for ii=1:size(edges,1)
                plot(axish, [pts(1,edges(ii,1)) pts(1,edges(ii,2))], [pts(2,edges(ii,1)) pts(2,edges(ii,2))], '-', 'Color', 'r', 'LineWidth', 2);
            end
        end
    end
    if dim==3
        plot3(axish, pts(1,:), pts(2,:), pts(3,:), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y', 'MarkerSize', 3);
    else
        plot(axish, pts(1,:), pts(2,:), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y', 'MarkerSize', 3);
    end
end
axis(axish, 'image', 'xy');
grid(axish, 'on');
title(axish, 'Original Shapes');
set(figh, 'Name', 'Original Shapes Figure');
set(ad.figMain, 'Pointer', 'arrow');
setappdata(0,'ModelGeneratorToolData', ad);
return

%%%
%
%%%
function doCreateNewImageList(createbtn, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');% CHECK THIS

% Begin change by js, 070705
% Begin original code
 
% str = dir([ad.dirs.cropped, filesep, '*.jpg']);
% str = {str.name};
 
% End original code
% Begin replacement code
 
[projectPath, filename, ext] = fileparts(ad.dirs.cropped);
 
if ~isProject3D(projectPath)
    str = dir([ad.dirs.cropped, filesep, '*.jpg']);
    str = {str.name};
else
    volumeDirs = getCroppedVolumeDirs(ad.dirs.cropped);
    str = {volumeDirs.name};
end
 
% End replacement code
% End change by js, 070705



if isempty(str)
    warndlg(sprintf('There are no images in the appropriate directory.'))
    return;
end
[s, v] = CustomListDlg(str);
if isempty(s)
    return;
end
ad = makeNewImageListDirectories(ad, s);
%ad = updateImageList(ad); % CHECK THIS  Not needed since previous statement made the call implicitly
setappdata(0,'ModelGeneratorToolData', ad);
doChangeImageList(ad.handles.imageList);
%%%
%
%%%
function ad = makeNewImageListDirectories(ad, s)
set(ad.handles.filenamesList, 'String', s);
aam = ad.data.aam;
aam = set(aam, 'am_imagenames', s);
% Make the directory for the model
imagedirroot = ['StatisticalModels', filesep, ad.data.templatename, filesep, ad.data.pointset];
dirs = dir([imagedirroot, filesep, 'ImageList*']);
ndirs = {dirs.name};
maxdir = 0;
for i=1:length(ndirs)
    num = str2double(ndirs{i}(11:end));
    if num>maxdir
        maxdir = num;
    end
end
modelDirec = [imagedirroot, filesep, 'ImageList_', num2str(maxdir+1)];
mkdir(modelDirec);
% This asks the user for a logical name to associate with the image
% list
prompt={'Enter the logical name of the new image list:'};
name='Name';
numlines=1;
defaultanswer={'LEAF'};
answer=inputdlg(prompt,name,numlines,defaultanswer);
if ~isempty(answer)
    d =0;
    save([modelDirec ,filesep, 'LN_', answer{1}], 'd');
else
    save([modelDirec ,filesep, 'LN_LEAF'], 'd');
end
imageList = get(ad.handles.imageList, 'String');
imageList{end+1} = ['ImageList_', num2str(maxdir+1)];
aam  = set(aam, 'imageset', maxdir+1);
aam  = set(aam, 'modelDirec', modelDirec);
aam  = set(aam, 'pdmDirec', modelDirec);
aam  = set(aam, 'sfamDirec', modelDirec);
aam = set(aam, 'imageFilenames', {});
aam = set(aam, 'elements', {});
saveFilename=[modelDirec, filesep, 'model.aam_dat'];
ad.data.aam = aam;
save(saveFilename, 'aam'); % CHECK THIS
[imagelists,named]=getImageLists2(imagedirroot)
%%ad = getImageLists2(ad); % this sorts the names into date order, last at the top
fprintf(1,'Saved empty model in %s with logical name %s\n',imagelists{1},named{1});
ad.data.imagelistsnames=named;
ad.data.imagelists=imagelists;
set(ad.handles.imageList, 'String', named);
set(ad.handles.imageList, 'value', 1);
%set(ad.handles.imageList, 'String', ad.data.imagelistsnames);
%set(ad.handles.imageList, 'value', 1);
%%%
%
%%% 
function doCreateImageListFromAugExcelFile(createfromexcel, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
[ordered_pmfiles, N] = getAugmentedOrderedPMFiles([pwd, filesep, 'Data']);
if isempty(ordered_pmfiles)
    warndlg(sprintf('There are no images in the appropriate directory.'))
    return;
end
str = ordered_pmfiles{1};
s = {str{1:N}};
% just take of the extension and the _pm part
for i=1:length(s)
    [pathname, s{i}] = fileparts(s{i});
    s{i} = s{i}(1:end-3);
end
ad = makeNewImageListDirectories(ad, s);
ad = updateImageList(ad);
setappdata(0,'ModelGeneratorToolData', ad);
doChangeImageList(ad.handles.imageList);
return
%%%
%
%%%
function doImportImageList(importmenu, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ModelGeneratorToolData');
rootdir = uigetdir(pwd, 'Please select the root directory to search for image lists');
imagelists = finddirs('ImageList', rootdir);
[s,v] = listdlg('PromptString','Select an image list to import:', 'ListSize', [500 160], 'SelectionMode','single', 'ListString', imagelists);
if isempty(s)
    return;
end
newlist = imagelists{s};
modelname = [newlist, filesep, 'model.aam_dat'];
if ~exist(modelname, 'file')
    return;
end
aam = load(modelname, '-mat');
aam = aam.aam;
s = get(aam, 'am_imagenames');
ad = makeNewImageListDirectories(ad, s);
ad = updateImageList(ad);
setappdata(0,'ModelGeneratorToolData', ad);
doChangeImageList(ad.handles.imageList);
return

function doScalePointModels(scalePointModels,evd)
ad = getappdata(0,'ModelGeneratorToolData');
%select point models
[filename, pathname, filterindex] = uigetfile( ...
{  '*.mat','MAT-files (*.mat)'}, ...
   'Pick a file', ...
   'MultiSelect', 'on');
%enter scale parameter
scaleParam = inputdlg('enter scale parameter');
if ~isempty(isempty)
    scaleParam = str2num(scaleParam{1});
    %check to see if user select multiple files
    if(isa(filename,'char')) %true if only one file selected
        %change to cell
        tmp = filename;
        filename = cell(1);
        filename{1} = tmp;
    end
end

%loop through and scale the models
for i = 1:length(filename)
    fname = filename{i};
    load([pathname,fname]);
    
    
%     %variable pts is loaded in from pointmodel.mat
%     pts = pts .* scaleParam;
%     %save the scaled models
%     idx = strfind(fname,'.');
%     filenameMinusExtention = fname(1:idx-1);
%     [token, remain] = strtok(num2str(scaleParam), '.');
%     scaleParamMinusDot = [token,remain(2:end)];
%     save([pathname,filenameMinusExtention,'_Scaled',scaleParamMinusDot,'.mat'], 'pts')

    scale = scaleParam;
    idx = strfind(fname,'.');
    filenameMinusExtention = fname(1:idx-1);
    save([pathname,filenameMinusExtention,'.mat'], 'pts','scale');

    
end

return