function figno=pdmwalk(action,option)
%PDMWALK GUI to 'walk' a PDM through each mode of variation
%  PDMWALK(1,'MODEL_PDM') will read from a PDM the file 'MODEL_PDM',
%  PDMWALK(1,pdm) will use the PDM struct (pdm.Xm, pdm.P and pdm.b),
%  PDMWALK will prompt for a file.
%
%cd 'C:\Documents and Settings\ab\My Documents\Matlab2004\Nicolas\Images\Modigliani2\ModelData'
%See also
%  buildpdm
%
%Iain Matthews, UEA, Norwich
%J. Andrew Bangham, UEA 2005

% $Id: pdmwalk.m,v 0.1 1998/02/28 23:11:06 iam Exp $

% Check args

global AAMShapemodel_figure_handle
global PMTemplateBuilder_handle
global AAMSetPicker_handle
global AAMModelBuilder_handle
global AAMModelGenerator_handle
global UpdateModel_handle
global PDMWalk_handle

%
if nargin<2
    inp1 = '';
    option=0;
end
if nargin<1
    action = 'initialise';
    d=dir('..\..\..\april_modigliani4.mat');
    if ~isempty(d)
        load('..\..\..\april_modigliani4.mat');
        option=options;
    else
        [fname pname] = uigetfile('*.mat', 'Load options');
        if(~any(fname))
            opts = [];
            msg = 'Cancelled by user';
            return;
        end
        options_filename = strcat(pname, fname);
        load(options_filename);
        option=options;
    end
    d=dir(option.SFAMFile);
    if ~isempty(d)
        load(option.SFAMFile);
    else
        [fname pname] = uigetfile('*_sfam.mat', 'Load *_sfam');
        if(~any(fname))
            opts = [];
            msg = 'Cancelled by user';
            return;
        end
        options_filename = strcat(pname, fname);
        load(options_filename);
    end
    aam=sfam;
    inp1=aam.pdm;
end
if isstruct(action)
    %if isempty(action.sfam)
    option=action;
    if ~isempty(action.sfam)
        aam  = action.sfam;
        inp1 = action.pdm;
    else
        aam  = [];
        inp1 = action.pdm;
    end
    action = 'initialise';
end

% Load data from the calling figure
Data = LoadUserData(gcbf);

% Main function
if ~strcmp(action,'initialise')
    set(gcf,'Pointer','watch');
end
switch action
    case 'initialise'
        Data = Initialise(inp1,aam,option);
        PDMWalk_handle=Data.ui.fH;
        SaveUserData(Data.ui.fH, Data);
    case 'moveslider' %PlotModel()
        Data = MoveSlider(Data);
        SaveUserData(Data.ui.fH, Data);
    case 'movesliderA' %ShowModel()
        Data = MoveSliderA(Data);
        SaveUserData(Data.ui.fH, Data);
    case 'walk'
        Data = Walk(Data,[]);
        SaveUserData(Data.ui.fH, Data);
    case 'fullwalk'
        Data = FullWalk(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'walkA'
        Data = WalkA(Data,[]);
        SaveUserData(Data.ui.fH, Data);
    case 'fullwalkA'
        Data = FullWalkA(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'ShowLines'
        ShowLines(Data);
    case 'pmLines'
        Data=pmLines(Data);
        SaveUserData(Data.ui.fH, Data);
    case 'ShowImage'
        Data=ShowImage(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'reset'
        Data = ResetSliders(Data,0);
        if ~isempty(Data.options.sfam)
            Data = ResetSlidersA(Data,0);
        end
        SaveUserData(Data.ui.fH, Data);
    case 'ZeroslidersA'
        Data = ZeroslidersA(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'Zerosliders'
        Data = Zerosliders(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'SetPlaySpeed' 
        Data = SetPlaySpeed(Data);
        SaveUserData(Data.ui.fH, Data);
    case 'StepSize' 
        Data = StepSize(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'NumModes' 
        Data = NumberModes4Movie(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'multiplier' 
        Data = multiplier(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'threshold' 
        Data = threshold(Data,option);
        SaveUserData(Data.ui.fH, Data);
%     case 'SetupdateSpeed' Data.ui.multiH=multiH;
%         Data = SetupdateSpeed(Data);
%         SaveUserData(Data.ui.fH, Data);
    case 'loadimage'
        Data = loadimage(Data,option);
        SaveUserData(Data.ui.fH, Data);
    case 'loadimage2'
        Data = loadimage2(Data,option);
        SaveUserData(Data.ui.fH, Data);
        string=['Data=',mfilename,'(''ShowImage'',4);'];
        eval(string); %Data=mfilename('ShowImage',4);
     case 'pdm2weights' %Data.ui.pbImage
        Data = pdm2weights(Data,option);
        SaveUserData(Data.ui.fH, Data);
     case 'quantisation' %Data.ui.pbImage
        Data = quantisation(Data,option);
        SaveUserData(Data.ui.fH, Data);
%      case 'all_aam2weights' %Data.ui.pbImage
%          set(gcf,'Pointer','watch');
%          d=dir([Data.options.PMdirectory,'*_pm.mat']);
%          for i=1:length(d)
%              name=d(i).name;
%              disp(sprintf('working on %s',name));
%              Data = loadimage(Data,name);
%              Data = pdm2weights(Data,option);
%              drawnow
%          end
%         set(gcf,'Pointer','arrow');
%         SaveUserData(Data.ui.fH, Data);
     case 'MaxWeight' %Data.ui.pbAtoImage 
        Data = MaxWeight(Data,option);
        SaveUserData(Data.ui.fH, Data);
     case 'Movie' %Data.ui.pbAtoImage 
        Data = MakeMovie(Data,option);
        SaveUserData(Data.ui.fH, Data);
     case 'ImageSize' %Data.ui.pbAtoImage 
        Data = ImageSize(Data,option);
        SaveUserData(Data.ui.fH, Data);
   case 'quit'
        Quit(Data.ui.fH);
    otherwise
        disp(['ERROR: Unknown action (',action,')'])
end
set(gcf,'Pointer','arrow');
figno=gcf;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                      GUI Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=ImageSize(Data,option)
for i=1:length(Data.ui.menu7.image_stepsize)
    h=Data.ui.menu7.image_stepsize(i);
    set(h,'Checked','off');
end
set(gcbo, 'Checked', 'on');
Data.oversize_by=option;
if ishandle(Data.ui.lHA)
    delete(Data.ui.lHA);
end
Data.ui.lHA=[];
if isfield(Data.ui,'handlelHAP')
    if ishandle(Data.ui.handlelHAP)
        delete(Data.ui.handlelHAP);
    end
    Data.ui.handlelHAP=[];
end
Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.pdm.bW);
Data = MoveSliderA(Data,1:length(Data.aam.bWA),0,Data.aam.bWA,1);
set(Data.ui.ax,'Visible','off');
if get(Data.ui.linesH,'Value')
    set(Data.ui.lH,'visible','on')
else
    set(Data.ui.lH,'visible','off')
end


function Data=StepSize(Data,option)
for i=1:length(Data.ui.menu5.sd_stepsize)
    h=Data.ui.menu5.sd_stepsize(i);
    set(h,'Checked','off');
end
set(gcbo, 'Checked', 'on');
Data.sd_stepsize=option;

function Data=NumberModes4Movie(Data,option)
for i=1:length(Data.ui.menu6.NumModes)
    h=Data.ui.menu6.NumModes(i);
    set(h,'Checked','off');
end
set(gcbo, 'Checked', 'on');
Data.NumModes=option;

function Data = MakeMovie(Data,option)
if option==0 %stop
    Data.movieflag=0;
    set(Data.ui.menu4.movie(2),'Checked','on');
    set(Data.ui.menu4.movie(1),'Checked','off');
    set(Data.ui.menu4.movie(3),'Checked','off');
    [filename,pathname]=uiputfile([Data.options.OutputDirectory,'*.avi'],'Choose movie filename');
    if length(filename)>0 & ~isempty(Data.Movie)
        Data.MovieName=fullfile(pathname,filename);
        mov=avifile(Data.MovieName,'fps',15,'Compression','Cinepak','keyframe',5);
        set(gcf,'Pointer','watch');
        for i=1:length(Data.Movie)
            mov=addframe(mov,Data.Movie(i));
        end
        mov=close(mov);
        Data.Movie=[];
        set(gcf,'Pointer','arrow');
    end
elseif option==1 %start image only
    Data.movieflag=1;
    Data.movie_imageonly=1;
    set(Data.ui.menu4.movie(2),'Checked','off');
    set(Data.ui.menu4.movie(1),'Checked','on');
    set(Data.ui.menu4.movie(3),'Checked','off');
elseif option==2
    Data.movieflag=1;
    Data.movie_imageonly=0;
    set(Data.ui.menu4.movie(2),'Checked','off');
    set(Data.ui.menu4.movie(1),'Checked','off');
    set(Data.ui.menu4.movie(3),'Checked','on');
elseif option==3
    if isfield(Data,'MovieName')
        movifile=Data.MovieName;
    else
        [filename,pathname]=uigetfile('*.avi','Choose movie');
        movifile=fullfile(pathname,filename);
    end
    m=figure;
    h=actxcontrol('MediaPlayer.MediaPlayer.1', get(m,'Position'), m);
    set(h, 'filename', movifile);
    invoke(h,'play');
    disp('Press a key to continue');
    pause
end

function Data = MaxWeight(Data,option)
if ~isempty(Data.options.sfam)
   Data.aam.bW=Data.aam.bWbackup;
   Data.aam.bWA=Data.aam.bWAbackup;
   Data = MoveSlider(Data,(1:length(Data.pdm.bW))',0,Data.aam.bWbackup);
   Data = MoveSliderA(Data,(1:length(Data.aam.bWA))',0,Data.aam.bWAbackup,1);
else
   Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.aam.bWbackup);
end

function Data=threshold(Data,options)
ind=get(Data.ui.thresholdH,'value');
if ind==1
    value=0;
elseif ind==2
    value=0.5;
elseif ind==3
    value=1.0;
elseif ind==4
    value=1.5;
elseif ind==5
    value=2.0;
else
    value=2.5;
end
indA=get(Data.ui.thresholdHA,'value');
if indA==1
    valueA=0;
elseif indA==2
    valueA=0.5;
elseif indA==3
    valueA=1.0;
elseif indA==4
    valueA=1.5;
elseif indA==5
    valueA=2.0;
else
    valueA=2.5;
end
Data.pdm.threshold=value;
Data.aam.threshold=valueA;
%Data = pdm2weights(Data,options);
Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.pdm.bW);
Data = MoveSliderA(Data,1:length(Data.aam.bWA),0,Data.aam.bWA,1);

function Data=quantisation(Data,options)
if options==0
    Data.pdm.quantisation=get(gcbo, 'Value');
else
    Data.aam.quantisationA=get(gcbo, 'Value');
end
Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.pdm.bW);
Data = MoveSliderA(Data,1:length(Data.aam.bWA),0,Data.aam.bWA,1);

function Data=multiplier(Data,options)
ind=get(Data.ui.multiH,'value');
if ind==1
    value=0;
elseif ind==2
    value=0.5;
elseif ind==3
    value=1.0;
elseif ind==4
    value=1.5;
else
    value=2.0;
end
indA=get(Data.ui.multiHA,'value');
if indA==1
    valueA=0;
elseif indA==2
    valueA=0.5;
elseif indA==3
    valueA=1.0;
elseif indA==4
    valueA=1.5;
else
    valueA=2.0;
end
%if options==0
Data.pdm.multi=value;
%else
Data.aam.multi=valueA;
%end
Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.pdm.bW);
Data = MoveSliderA(Data,1:length(Data.aam.bWA),0,Data.aam.bWA,1);
return

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=pmLines(Data)
value=get(Data.ui.pmlinesH,'value');
disp('Click around, or double click on, a point of interest')
%[x,y]=ginput(1);
%mask=roipoly;
% the following achieves the same as roipoly but for current axis
[xi,yi] = getline(gca,'closed');
im=getimage(Data.ui.lHA);
mask=roipoly(im,yi,xi);
if ~any(mask(:))
    c=get(gca,'CurrentPoint');
    x=c(1,1);
    y=c(1,2);
else
    c=regionprops(bwlabel(mask),'Centroid');
    y=c.Centroid(1);
    x=c.Centroid(2);
end
[h,model]=PlotModel(Data.plot_pdm);
xp=model(1:2:end)+Data.net_offset_xy(1);
yp=model(2:2:end)+Data.net_offset_xy(2);
dist=((xp-x).^2)+((yp-y).^2);
ind=find(min(dist)==dist);
% hold on;
% plot(x,y,'Oc');
% plot(model(1:2:end)+Data.net_offset_xy(1),model(2:2:end)+Data.net_offset_xy(2),'.b');
% plot(xp(ind),yp(ind),'*y');
% hold off
% we now have the closest index in modelled, warped image
% need to find the index into the original template pointlist
IND=Data.options.indices(ind);
% and can be compared directly with the template
pts=get(Data.pmt,'pts');
xtemplate=pts(1:2:end)+Data.net_offset_xy(1);
ytemplate=pts(2:2:end)+Data.net_offset_xy(2);

pmtname=get(Data.pmt,'name');
pmtname=pmtname(1:findstr(pmtname,'.temp_dat')-1);
d=dir(fullfile('StatisticalModels',pmtname,'Set*'));
possible_sets=[]; %zeros(1:length(d));
counter=0;
for i=1:length(d)
    setnumber=d(i).name;
    d2=dir(fullfile('StatisticalModels',pmtname,setnumber,'LN_*'));
    temp=load(fullfile('StatisticalModels',pmtname,setnumber,d2.name));
    if isfield(temp,'setnames')
        setname=cell2mat(temp.setnames{1});
    end
    tempind=load(fullfile('StatisticalModels',pmtname,setnumber,'indices.mat'),'-mat');
    if isfield(tempind,'indices')
        templist=tempind.indices;
        tempname='All';
    else
        templist=tempind.setlist{1};
        tempname=setname;
    end
    if intersect(templist,IND)
        counter=counter+1;
        possible_sets(counter).indices=templist;
        possible_sets(counter).setname=tempname;
        possible_sets(counter).i=i;
    end
end
k=1;
len=length(possible_sets(k).indices);
for i=1:length(possible_sets)
    if length(possible_sets(i).indices)<len
        k=i;
        len=length(possible_sets(i).indices);
    end
end
disp(sprintf('Link to %s data',possible_sets(k).setname));
templist=possible_sets(k).indices;
% hold on
% ph=plot(xtemplate(templist),ytemplate(templist),'.c');
% hold off
uiwait(helpdlg(sprintf('Link to %s data',possible_sets(k).setname)));
%delete(ph);
% if isfield(Data.ui,'imagepmH')
%     if value==1
%         if get(Data.ui.pictureH(5),'Value')
%             set(Data.ui.imagepmH2,'visible','on');
%         elseif get(Data.ui.pictureH(3),'Value')
%             set(Data.ui.imagepmH,'visible','on');
%         end
%     else
%         set(Data.ui.imagepmH,'visible','off');
%         if isfield(Data.ui,'imagepmH2')
%             set(Data.ui.imagepmH2,'visible','off');
%         end
%     end
% end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function sfimg=warp_image(img,pts,meanshape)
npix=6000;
% Get the mean points
mpts = reshape(meanshape, 2, length(meanshape)/2)';
% Ensure mean model is zero centred
mpts = mpts - ((sum(mpts) / size(mpts,1))' * ones(1,size(mpts,1)))';
% Offset to (0,0) min for warping
ompts = mpts - (min(mpts)' * ones(1,size(mpts,1)))';
pts2=reshape(pts,2,length(pts)/2)';
sfimg = triwarp(img, pts2, ompts);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function pc=GetProcrustes(pct_name)
p=load(pct_name);
pc=p.proc_data;

function Data=pdm2weights(Data,option)
%b=P'*xxx; model = pdm.Xm + pdm.P * pdm.bW;
% On loading the image the following were computed
% Data.image.meansize_img
% Data.image.meansize_pm
% Data.image.img
% Data.image.pts
if ~isempty(Data.options.sfam)
    set(Data.ui.multiH,'value',3); % set scaling back to 1.0
    Data.pdm.multi=1;
    Data.aam.multi=1;
    P=Data.aam.pdm.P; % extract the pointmodel
    Data.pdm.P=P;     % and make it consistent over the two copies
    Data.aam.pdm.bW=P'*(Data.image.meansize_pm-Data.aam.pdm.Xm); %Data.aam.pdm.Xm;
    Data.pdm.bW=Data.aam.pdm.bW; % just to ensure aam and pdm are consistent
    Data.pdm.b=Data.aam.pdm.b; % just to ensure aam and pdm are consistent
    % extract the appearance model
    PA=Data.aam.P;
    Data.aam.bWA=PA'*(double(Data.image.meansize_img(:))-Data.aam.Am);
    Data.aam.bWbackup=Data.aam.bW;
    Data.aam.bWAbackup=Data.aam.bWA;
    Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.pdm.bW);
    Data = MoveSliderA(Data,1:length(Data.aam.bWA),0,Data.aam.bWA,1);
    %         results.sfam=Data.options.SFAMFile;
    %         results.bA=Data.aam.b;
    %         results.b=Data.aam.pdm.b;
    %         results.bW=Data.aam.pdm.bW;
    %         results.bWA=Data.aam.bWA;
    %         model_directory=Data.options.SFAMFile(1:findstr(Data.options.SFAMFile,'.mat')-1);
    %         d=dir(model_directory);
    %         if isempty(d)
    %             mkdir(model_directory);
    %         end
    %         fitfilename=[model_directory,'\FIT_',img_name(1:findstr(img_name,'.jpg')-1),'.mat'];
    %         save(fitfilename,'results')
else
    P=Data.pdm.P;
    Data.pdm.bW=P'*(Data.image.meansize_pm-Data.pdm.Xm); %Data.aam.pdm.Xm;
    Data.aam.bWbackup=Data.aam.bW;
    Data = MoveSlider(Data,1:length(Data.pdm.bW),0,Data.pdm.bW);
end
set(Data.ui.pictureH(4),'visible','on')

%set(Data.ui.pbAtoImage,'Visible','on');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Data=loadimage(Data,option)
%[imgfilename,pathname]=uigetfile('Cropped\*.jpg','Pick an image file');
% The following should allow an image to be loaded from any project
% with a cognate template ... see loadimage2
if isempty(option)%| option==0
    [pointmodel_filename,pathname]=uigetfile([Data.options.PMdirectory,'*_pm.mat'],'Pick an image file');
else
    pointmodel_filename=option;
end
s=pointmodel_filename(1:strfind(pointmodel_filename,'_pm.mat')-1);
n=regexp(Data.options.InputFilenames,s);
for i=1:size(n,2)
    if ~isempty(n{i})
        ind=i;
    end
end
% for i=1:size(Data.options.InputFilenames,1)
%     if findstr(Data.options.InputFilenames(i,:),s)
%         ind=i;
%     end
% end
if isfield(Data.ui,'pictureH')
    set(Data.ui.pictureH(3),'string',s);
end
imagename=['Cropped\',s,'.jpg'];
img=imread(imagename);
Data.options.image.img=img;
Data.image.index=ind; %option;
Data.options.image.name=pointmodel_filename;
file=pointmodel_filename(1:strfind(pointmodel_filename,'.jpg')-1);
% now check that a model exists
%modelname=[file,'_pm.mat'];
%filename=[Data.options.PMdirectory, modelname];
filename=[Data.options.PMdirectory,pointmodel_filename];
% warp image into mean shape
%mean_img = uint8(reshape(Data.aam.Am, [Data.aam.siz(2), Data.aam.siz(1), 3]));
[DummyH,model]=PlotModel(Data.pdm); % get model
%load(modelname);
load(filename);
if length(Data.options.indices(:))*2<length(pts)
    xypts=reshape(pts,2,length(pts)/2);
    pts2=xypts(:,Data.options.indices); % just take the current subset
    pts=pts2(:);
    indices_flag=1;
else
    indices_flag=0;
end
Data.image.pts=pts; % just the subset where needed
set(Data.ui.pbImage,'visible','on');
ax=axis;
% find a procrustes transform and apply to new image points to align them
% with the mean model
M2 = calctrm(model(:), pts, ones(length(pts)/2, 1));
Data.image.meansize_pm=applytrm(pts, M2);
% warp the appearance into the mean shape
rpts2=reshape(pts',2,length(model)/2)';
Data.image.meansize_img=triwarp(img,rpts2,Data.aam.ompts); %warped image
if indices_flag
    % and slide them over to sit next to the zero/zero axis
    picture_rmodel2=reshape(Data.image.meansize_pm',2,length(model)/2)'; %realigned image pm
    zrmodel2(:,1)=picture_rmodel2(:,1)-min(picture_rmodel2(:,1));
    zrmodel2(:,2)=picture_rmodel2(:,2)-min(picture_rmodel2(:,2));
    % finally warp the new image down to the mean position and size
    rmodel=reshape(model',2,length(model)/2)'; %model pm
    %Data.image.meansize_img=triwarp(img,rpts2,picture_rmodel2); %warped image
    Data.image.img=triwarp(img,rpts2,zrmodel2); %warped image
else
    Data.image.img=img;
end
img=Data.image.img;
% The result of all this is an image and pointmodel scaled and offset to be
% equivalent to the current mean
% Data.image.meansize_img
% Data.image.meansize_pm
% Data.image.img
% Data.image.pts
Data.image.pixel_indexes=[];
if ~isfield(Data.ui,'imageH')
    hold on
    Data.ui.imageH=image(img);
    Data.ui.imagepmH=plot(rpts2(:,1),rpts2(:,2),'*r');
    hold off
else
    set(Data.ui.imageH,'CData',img);
    set(Data.ui.imagepmH,'Xdata',rpts2(:,1));
    set(Data.ui.imagepmH,'Ydata',rpts2(:,2));
end
axis(ax);
% set visibility according to radiobutton
if isfield(Data.ui,'pictureH')
    value=get(Data.ui.pictureH(3),'value');
else
    value=0;
end
if value==1
    set(Data.ui.imageH,'visible','on');
else
    set(Data.ui.imageH,'visible','off');
end
if isfield(Data.ui,'pmlinesH')
    value=get(Data.ui.pmlinesH,'value');
else
    value=1;
end
if value==1
    set(Data.ui.imagepmH,'visible','on');
else
    set(Data.ui.imagepmH,'visible','off');
end
set(Data.ui.pictureH(3),'visible','on')

function Data=loadimage2(Data,option)
%[pointmodel_filename,pathname]=uigetfile('Cropped\*.jpg','Pick an image file');
%if isempty(option)
if isempty(option)%| option==0
    templatename=Data.options.pdm(findstr(Data.options.pdm,'StatisticalModels')+length('StatisticalModels')+1:end);
    templatename=templatename(1:findstr(templatename,'\Set_')-1);
    string2=sprintf('Pick a PointModel\\%s\\*_pm file',templatename);
    string1=sprintf('..\\PRJ_*\\PointModel\\%s\\*_pm.mat',templatename);
    [pointmodel_filename,pathname]=uigetfile(string1,string2);
else
    pointmodel_filename=option;
end
s=pointmodel_filename(1:strfind(pointmodel_filename,'_pm.mat')-1);
% n=regexp(Data.options.InputFilenames,s);
% for i=1:size(n,2)
%     if ~isempty(n{i})
%         ind=i;
%     end
% end

%     pts = get(elements{e}, 'pts');
%     if size(pts, 2) >0
%         % data(e).marks = pts(:, handles.dat.indices);
%         pts = pts(:, handles.dat.indices);
%         pointmodels(:, e) = pts(:);
%     end
if isfield(Data.ui,'pictureH')
    set(Data.ui.pictureH(5),'string',s);
end
imagename=['Cropped\',s,'.jpg'];
imagepathname=pathname(1:findstr(pathname,'PointModels')-1);
imagefullname=fullfile(imagepathname,imagename);
img=imread(imagefullname);
Data.options.image2.img=img;
Data.options.image2.name=imagefullname;
Data.options.image2.pathname = imagepathname;
filename=fullfile(imagepathname,'PointModels',templatename,pointmodel_filename);%[Data.options.PMdirectory,pointmodel_filename];
load(filename);
xypts=reshape(pts,2,length(pts)/2);
pts2=xypts(:,Data.options.indices); % just take the current subset
pts=pts2(:);
Data.image2.pts=pts; %(1:size(Data.pdm.Xm,1));
ax=axis;
Data.image2.meansize_pm=pts; %applytrm(pts, M2);
rpts=reshape(pts',2,length(pts)/2)';
Data.image2.w_img=triwarp(img,rpts,Data.aam.ompts);
Data.image2.meansize_img = double(Data.image2.w_img); %imresize(Data.image2.w_img, [Data.aam.siz(2),Data.aam.siz(1)]);
Data.image2.pixel_indexes=[];
x=pts(1:2:end);
y=pts(2:2:end);
if ~isfield(Data.ui,'imageH2')
    hold on
    Data.ui.imageH2=image(img);
    Data.ui.imagepmH2=plot(x,y,'.r');
    hold off
else
    set(Data.ui.imageH2,'CData',img);
    set(Data.ui.imagepmH2,'Xdata',x);
    set(Data.ui.imagepmH2,'Ydata',y);
end
axis(ax);
% set visibility according to radiobutton
if isfield(Data.ui,'pictureH')
    value=get(Data.ui.pictureH(5),'value');
else
    value=0;
end
if value==1
    set(Data.ui.imageH2,'visible','on');
else
    set(Data.ui.imageH2,'visible','off');
end
if isfield(Data.ui,'pmlinesH')
    value=get(Data.ui.pmlinesH,'value');
else
    value=1;
end
if value==1
    set(Data.ui.imagepmH2,'visible','on');
else
    set(Data.ui.imagepmH2,'visible','off');
end
set(Data.ui.pictureH(5),'visible','on')


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function ShowLines(Data,value)
if nargin<2
    value=get(gcbo,'Value');
end
if value>0
    set(Data.ui.lH,'visible','on')
else
    set(Data.ui.lH,'visible','off')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=ShowImage(Data,option)
set(Data.ui.pmlinesH,'value',0);
%Data=pmLines(Data);
for i=1:length(Data.ui.pictureH)
    set(Data.ui.pictureH(i),'value',0);
end
switch option
    case 0
        set(Data.ui.pictureH(1),'value',1);
        set(Data.ui.lHA,'visible','off');
        if isfield(Data.ui,'imageH')
            if ishandle(Data.ui.imageH)
                set(Data.ui.imageH,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP')
            if ishandle(Data.ui.handlelHAP)
                set(Data.ui.handlelHAP,'visible','off');
            end
        end
        if isfield(Data.ui,'imageH2')
            if ishandle(Data.ui.imageH2)
                set(Data.ui.imageH2,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP2')
            if ishandle(Data.ui.handlelHAP2)
                set(Data.ui.handlelHAP2,'visible','off');
            end
        end
    case 1
        if isfield(Data,'temporary')
            if Data.temporary.flag==1 % load them all back
                Data.temporary.flag=0; % set when we are importing the mean
                Data.ui.lHA=Data.temporary.lHA; %handle to image axis
                Data.pdm.Xm=Data.temporary.Xm; % mean shape
                Data.aam.pdm.Xm=Data.temporary.pdm.Xm; % in two places
                Data.aam.Am=Data.temporary.Am; % mean appearance
                %Data.aam.ompts=Data.temporary.ompts; % zero offset
                %update sliders and replot
                Data = MoveSlider(Data);
                Data = MoveSliderA(Data);
            end
        end
        set(Data.ui.pictureH(2),'value',1);
        set(Data.ui.lHA,'visible','on');
        if isfield(Data.ui,'imageH')
            if ishandle(Data.ui.imageH)
                set(Data.ui.imageH,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP')
            if ishandle(Data.ui.handlelHAP)
                set(Data.ui.handlelHAP,'visible','off');
            end
        end
        if isfield(Data.ui,'imageH2')
            if ishandle(Data.ui.imageH2)
                set(Data.ui.imageH2,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP2')
            if ishandle(Data.ui.handlelHAP2)
                set(Data.ui.handlelHAP2,'visible','off');
            end
        end
    case 2
        set(Data.ui.pictureH(3),'value',1);
        set(Data.ui.lHA,'visible','off');
        if isfield(Data.ui,'imageH')
            if ishandle(Data.ui.imageH)
                set(Data.ui.imageH,'visible','on');
            end
        end
        if isfield(Data.ui,'handlelHAP')
            if ishandle(Data.ui.handlelHAP)
                set(Data.ui.handlelHAP,'visible','off');
            end
        end
        if isfield(Data.ui,'imageH2')
            if ishandle(Data.ui.imageH2)
                set(Data.ui.imageH2,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP2')
            if ishandle(Data.ui.handlelHAP2)
                set(Data.ui.handlelHAP2,'visible','off');
            end
        end
    case 3
        set(Data.ui.pictureH(4),'value',1);
        set(Data.ui.lHA,'visible','off');
        if isfield(Data.ui,'imageH')
            if ishandle(Data.ui.imageH)
                set(Data.ui.imageH,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP')
            if ishandle(Data.ui.handlelHAP)
                set(Data.ui.handlelHAP,'visible','on');
            end
        end
        if isfield(Data.ui,'imageH2')
            if ishandle(Data.ui.imageH2)
                set(Data.ui.imageH2,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP2')
            if ishandle(Data.ui.handlelHAP2)
                set(Data.ui.handlelHAP2,'visible','off');
            end
        end
    case 4 % use an external image as the origin
        set(Data.ui.pictureH(5),'value',1); % set button
        % exchange all pointers and mean values with original
        % but if it is the first time, store the actual means
        if ~isfield(Data,'temporary')
            %update sliders and replot
            Data = MoveSlider(Data);
            Data = MoveSliderA(Data);
            Data.temporary.lHA=Data.ui.lHA; %handle to image axis
            Data.temporary.Xm=Data.pdm.Xm; % mean shape
            Data.temporary.pdm.Xm=Data.aam.pdm.Xm; % in two places
            Data.temporary.Am=Data.aam.Am; % mean appearance
            %Data.temporary.ompts=Data.aam.ompts; % zero offset
        end
        Data.temporary.flag=1; % set when we are importing the mean
        %set(Data.ui.lHA,'visible','off'); % temporally hide mean
        %set(Data.ui.imageH2,'visible','on'); % temporally show image2
        %        pause(1);
        Data.pdm.Xm=Data.image2.meansize_pm; %pts; % substitute image2 pointmodel for mean shape
        Data.aam.pdm.Xm=Data.image2.meansize_pm; % in two places
        %Data.aam.ompts=Data.image2.ompts; %
        % resize the image
        if any(size(Data.image2.meansize_img(:))~=size(Data.aam.Am))
            disp('Attempting to substitute the mean appearance model with an alternative of the wrong size')
        end
        Data.aam.Am=Data.image2.meansize_img(:);
        %Data.aam.Am=imresize(Data.image2.meansize_img,[aam.siz(2),aam.siz(1)]);
        %Data.aam.Am=Data.image2.meansize_img(:)'; % substitute image2 for mean aam
        %update sliders and replot
        Data = MoveSlider(Data);
        Data = MoveSliderA(Data);
        set(Data.ui.lHA,'visible','on'); % temporally hide mean
        set(Data.ui.imageH2,'visible','off'); % temporally show image2
        % set all the other buttons off
        if isfield(Data.ui,'imageH')
            if ishandle(Data.ui.imageH)
                set(Data.ui.imageH,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP')
            if ishandle(Data.ui.handlelHAP)
                set(Data.ui.handlelHAP,'visible','off');
            end
        end
        if isfield(Data.ui,'imageH2')
            if ishandle(Data.ui.imageH2)
                set(Data.ui.imageH2,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP2')
            if ishandle(Data.ui.handlelHAP2)
                set(Data.ui.handlelHAP2,'visible','off');
            end
        end
    otherwise
        set(Data.ui.pictureH(5),'value',1);
        set(Data.ui.lHA,'visible','off');
        if isfield(Data.ui,'imageH')
            if ishandle(Data.ui.imageH)
                set(Data.ui.imageH,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP')
            if ishandle(Data.ui.handlelHAP)
                set(Data.ui.handlelHAP,'visible','off');
            end
        end
        if isfield(Data.ui,'imageH2')
            if ishandle(Data.ui.imageH2)
                set(Data.ui.imageH2,'visible','off');
            end
        end
        if isfield(Data.ui,'handlelHAP2')
            if ishandle(Data.ui.handlelHAP2)
                set(Data.ui.handlelHAP2,'visible','on');
            end
        end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = LoadUserData(figH)
% Load UserData stored in figure

Data = get(figH,'UserData');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function SaveUserData(figH, Data)
% Save UserData into figure

set(figH,'UserData',Data);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=SetPlaySpeed(Data)
% Save UserData into figure
menuhandle=Data.ui.menu.speed;
if strcmp(get(menuhandle, 'Checked'),'off')
    set(menuhandle, 'Checked', 'on');
    Data.preference.speed=0.03;
    Data.preference.speed2=0;
else
    set(menuhandle, 'Checked', 'off');
    Data.preference.speed=0;
    Data.preference.speed2=1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% function Data=SetupdateSpeed(Data)
% % Save UserData into figure
% menuhandle=Data.ui.menu.speed2;
% if strcmp(get(menuhandle, 'Checked'),'off')
%     set(menuhandle, 'Checked', 'off');
%     Data.preference.speed2=0;
% else
%     set(menuhandle, 'Checked', 'on');
%     Data.preference.speed2=1;
% end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function menu2handles=create_images_menu(menu2,guiname,...
    InputFilenames,OutputDirectory);
%for i=1:1%length(InputFilenames)
%     filename=InputFilenames(i,:);
%     file=filename(1:strfind(filename,'.jpg')-1);
%     % now check that a model exists
%     modelname=[file,'_pm.mat'];
%     d=dir([OutputDirectory, modelname]);
%     if ~isempty(d)
menu2handles = uimenu(menu2,...
    'Label','Select pointmodel (image) for the statistical model to approximate',...
    'Checked','off',...
    'Callback',[guiname, sprintf('(''loadimage'',[]);')]);
%     end
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%create_secondary_imagesize_menu
function imagesize7handles=create_secondary_imagesize_menu(imagesizehandle,...
    guiname,OutputDirectory)
step=0.1;
stepsize=0.4;
for i=1:20
    stepsize=stepsize+step;
    if stepsize==1.2
        imagesize7handles(i) = uimenu(imagesizehandle,...
            'Label',sprintf('%3.3f',stepsize),...
            'Checked','on',...
            'Callback',[guiname, sprintf('(''ImageSize'',%f);',stepsize)]);
    else
        imagesize7handles(i) = uimenu(imagesizehandle,...
            'Label',sprintf('%3.3f',stepsize),...
            'Checked','off',...
            'Callback',[guiname, sprintf('(''ImageSize'',%f);',stepsize)]);
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function stepsize5handles=create_secondary_stepsize_menu(stepsizehandle,...
    guiname,OutputDirectory)
step=0.125;
stepsize=0;
for i=1:7
    stepsize=stepsize+step;
    if stepsize==0.5
        stepsize5handles(i) = uimenu(stepsizehandle,...
            'Label',sprintf('%3.3f',stepsize),...
            'Checked','on',...
            'Callback',[guiname, sprintf('(''StepSize'',%f);',stepsize)]);
    else
        stepsize5handles(i) = uimenu(stepsizehandle,...
            'Label',sprintf('%3.3f',stepsize),...
            'Checked','off',...
            'Callback',[guiname, sprintf('(''StepSize'',%f);',stepsize)]);
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function NumModes=create_secondary_nummodes_menu(nummodeshandle,...
    guiname,OutputDirectory)
for i=1:10
    if i==1
        NumModes(i) = uimenu(nummodeshandle,...
            'Label',sprintf('Max Number Components'),...
            'Checked','on',...
            'Callback',[guiname, sprintf('(''NumModes'',%d);',i)]);
    else
        NumModes(i) = uimenu(nummodeshandle,...
            'Label',sprintf('Number Components %d',i),...
            'Checked','off',...
            'Callback',[guiname, sprintf('(''NumModes'',%d);',i)]);
    end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function movie3handles=create_secondary_movie_menu(moviehandle,...
    guiname,OutputDirectory)
movie3handles(1) = uimenu(moviehandle,...
    'Label','Start recording Movie of image only',...
    'Checked','off',...
    'Callback',[guiname, sprintf('(''Movie'',1);')]);
movie3handles(2) = uimenu(moviehandle,...
    'Label','Stop Movie and save as an .avi',...
    'Checked','on',...
    'Callback',[guiname, sprintf('(''Movie'',0);')]);
movie3handles(3) = uimenu(moviehandle,...
    'Label','Start recording Movie with Sliders',...
    'Checked','off',...
    'Callback',[guiname, sprintf('(''Movie'',2);')]);
movie3handles(4) = uimenu(moviehandle,...
    'Label','Playback movie using MS Media Player',...
    'Separator','on',...
    'Checked','off',...
    'Callback',[guiname, sprintf('(''Movie'',3);')]);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function menu2handles=create_secondary_images_menu(menu2,guiname,...
    InputFilenames,OutputDirectory);
menu2handles = uimenu(menu2,...
    'Label','Select pointmodel (image) to replace the mean',...
    'Checked','off',...
    'Callback',[guiname, sprintf('(''loadimage2'',[]);')]);
%     end
%end


function Data=Initialise_GUI(pdm,aam,options)
% Initialise the GUI
if nargin<2
    aam=[];
end
% Load data
if isstr(pdm)		% First value is a file name - load it
    if isempty(pdm)
        [filespec pname] = uigetfile('*_pdm.mat','Locate PDM');
        if ~any(filespec) return; end
        eval(['load ',pname,filespec]);
    else
        eval(['load ',pdm]);
    end
    if exist('pdm') ~= 1
        error('PDM file must contain ''pdm''')
    end
    % replaced string pdm with structure
end
if isstr(aam)		% First value is a file name - load it
    if isempty(aam)
        [filespec pname] = uigetfile('*_sfam.mat','Locate AAM');
        if ~any(filespec) return; end
        eval(['load ',pname,filespec]);
    else
        eval(['load ',aam]);
    end
    if exist('aam') ~= 1
        error('aam file must contain ''aam''')
    end
    % replace string aam with structure
    aam=sfam;
end
Data.pdm=pdm;
Data.pdm.Nmodes = length(pdm.b);
Data.pdm.Nvals = length(pdm.Xm);
Data.pdm.rotate_flag = pdm.rotate_flag;
Data.pdm.bWflag=zeros(size(Data.pdm.b));
Data.pdm.multi=1.0;
Data.pdm.threshold=0;
Data.pdm.quantisation=0;
Data.pdm.bW=zeros(size(Data.pdm.b));
Data.plot_pdm=Data.pdm;
Data.aam=aam;
Data.aam.multi=1.0;
if isfield(Data.aam,'b')
    Data.aam.bWAflag=zeros(size(Data.aam.b));
else
    Data.aam.bWAflag=0;
end
Data.plot_aam=Data.aam;
Data.options=options;
Data.movieflag=0;
% Setup screen
screen_size=get(0,'ScreenSize');
fig_width=screen_size(1,3);
fig_height=screen_size(1,4);
cmap = gray(256);
Data.ui.fH = figure(...
    'Name','PDM Walk',...
    'NumberTitle','off',...
    'ColorMap',cmap,...
    'Position',[50 200 fig_width-300 fig_height-300],...
    'BackingStore','off',...
    'Visible','off');
set(Data.ui.fH,'Visible','on')

% Setup preferences on menu
Data.ui.menu.label = uimenu('Label','Preferences');
Data.preference.speed=0;
Data.preference.speed2=1;
%
Data.ui.menu.speed = uimenu(Data.ui.menu.label,...
    'Label','Fast walk speed',...
    'Checked','on',...
    'Callback',[mfilename, '(''SetPlaySpeed'');']);

% Data.preference.speed2=0; %
% Data.ui.menu.speed2 = uimenu(Data.ui.menu,...
%     'Label','Fast update speed',...
%     'Checked','on',...
%     'Callback',[mfilename, '(''SetupdateSpeed'')']);

Data.ui.menu2.label = uimenu('Label','Sample-Image');
Data.ui.menu2.loadimage=create_images_menu(Data.ui.menu2.label,...
    mfilename,Data.options.InputFilenames,options.PMdirectory);
Data.ui.menu3.label = uimenu('Label','Reference-Image');
Data.ui.menu3.loadimage=create_secondary_images_menu(Data.ui.menu3.label,...
    mfilename,Data.options.InputFilenames,options.PMdirectory);
Data.ui.menu4.label = uimenu('Label','Movie');
Data.ui.menu4.movie=create_secondary_movie_menu(Data.ui.menu4.label,...
    mfilename,Data.options.OutputDirectory);
Data.Movie=[];
Data.ui.menu5.label = uimenu('Label','Walk_stepsize');
Data.ui.menu5.sd_stepsize=create_secondary_stepsize_menu(Data.ui.menu5.label,...
    mfilename,Data.options.OutputDirectory);
Data.ui.menu6.label = uimenu('Label','Walk_components');
Data.ui.menu6.NumModes=create_secondary_nummodes_menu(Data.ui.menu6.label,...
    mfilename,Data.options.OutputDirectory);
Data.ui.menu7.label = uimenu('Label','Image_size');
Data.ui.menu7.image_stepsize=create_secondary_imagesize_menu(Data.ui.menu7.label,...
    mfilename,Data.options.OutputDirectory);

% Setup vertical controls
% Default values - CHANGE HERE!
minVal   = -5;
maxVal   = 5;
stVal    = 0;
% Save walk limits
Data.ui.minVal = minVal;
Data.ui.maxVal = maxVal;
% Setup vertical controls
% shape coefficients
Data.ui.slH = zeros(Data.pdm.Nmodes,1);
Data.ui.teH = zeros(Data.pdm.Nmodes,1);
Data.ui.pbH = zeros(Data.pdm.Nmodes,1);
YST   = 0.56;										% Main Y offset
XST   = 0.7;										% Main X offset
HT    = 0.38;%(1.0 - YST)/2 - 0.01;					% Main height
[fH,pbH,teH,slH,sdH,pbzerosH,pbzero1H,dis_ptsH,multiH,thresholdH,quantisationH]=Setup_vertical_controls(...
    0,XST,YST,HT,Data,Data.ui.fH,minVal,maxVal,stVal,min(25,Data.pdm.Nmodes),'Shape Model Weights');
Data.ui.fH=fH;
Data.ui.pbH=pbH;
Data.ui.teH=teH;
Data.ui.slH=slH;
Data.ui.sdH=sdH;
Data.ui.pbzerosH=pbzerosH;
Data.ui.pbzero1H=pbzero1H;
Data.ui.dist_ptsH=dis_ptsH;
Data.ui.multiH=multiH;
Data.ui.thresholdH=thresholdH;
Data.ui.quantisationH=quantisationH;
if ~isempty(aam)
    % appearance coefficients
    Data.ui.slHA = zeros(Data.pdm.Nmodes,1);
    Data.ui.teHA = zeros(Data.pdm.Nmodes,1);
    Data.ui.pbHA = zeros(Data.pdm.Nmodes,1);
    YSTA   = 0.08;										% Main Y offset
    XSTA   = 0.7;										% Main X offset
    HTA    = HT; %(1.0 - YST)/2 - 0.01;						% Main height
    [fHA,pbHA,teHA,slHA,sdH,pbzerosH,pbzero1H,dis_ptsH,multiH,thresholdHA,quantisationHA]=Setup_vertical_controls(...
        1,XSTA,YSTA,HTA,Data,Data.ui.fH,minVal,maxVal,stVal,min(25,length(Data.aam.b)),'Appearance Model Weights');
    Data.ui.fHA=fHA;
    Data.ui.pbHA=pbHA;
    Data.ui.teHA=teHA;
    Data.ui.slHA=slHA;
    Data.ui.sdHA=sdH;
    Data.ui.pbzerosHA=pbzerosH;
    Data.ui.pbzero1HA=pbzero1H;
    Data.ui.dist_aamH=dis_ptsH;
    Data.ui.multiHA=multiH;
    Data.ui.thresholdHA=thresholdHA;
    Data.ui.quantisationHA=quantisationHA;
end
% Setup horizontal controls Bottom bank
YST   = 0.01;										% Main Y offset
XST   = 0.01;										% Main X offset
HT    = 0.12 - YST - 0.01;							% Main height
HT    = 0.08 - YST - 0.01;							% Main height
WID   = 0.6 - XST - 0.01; 							% Main width

nc    = 8;											% no. controls
yoff  = 0.01;										% control y offset
xoff  = 0.01;										% control x offset
extra = 0;											% extra yoffs (spacing)

xst   = XST + xoff;									% horz. start
yst   = YST + yoff;									% vert. start
ht    = HT - (yoff * 2);							% control width
wid   = (WID - (nc+1+extra)*xoff) / nc;				% control height

uicontrol(Data.ui.fH,'Style','frame',...
    'Units','Normalized',...
    'Position',[XST YST WID HT],...
    'BackgroundColor',[0.6 0.6 0.6]);

% Setup other buttons
uicontrol(Data.ui.fH,'Style','frame',...
    'Units','Normalized',...
    'Position',[XST YST WID HT]);

uicontrol(Data.ui.fH,'Style','PushButton',...
    'Units','Normalized',...
    'Position',[xst+0*(wid+xoff)+(0*xoff) yst wid ht],...
    'String','Quit',...
    'CallBack',[mfilename, '(''quit'');']);

uicontrol(Data.ui.fH,'Style','PushButton',...
    'Units','Normalized',...
    'Position',[xst+1*(wid+xoff)+(0*xoff) yst wid ht],...
    'String','Reset sliders',...
    'CallBack',[mfilename, '(''reset'',1);']);

Data.ui.pbWalk = uicontrol(Data.ui.fH,'Style','PushButton',...
    'Units','Normalized',...
    'Position',[xst+2*(wid+xoff)+(0*xoff) yst wid ht],...
    'String','Full walk',...
    'CallBack',[mfilename,'(''fullwalk'',0);']);

Data.ui.pbImage = uicontrol(Data.ui.fH,'Style','PushButton',...
    'Units','Normalized',...
    'Position',[xst+3*(wid+xoff)+(0*xoff) yst wid ht],...
    'String','sm2weights',...
    'Visible','off',...
    'CallBack',[mfilename,'(''pdm2weights'',0);']);
set(Data.ui.pbImage,'visible','off');

if ~isempty(aam)
    Data.ui.pbWalkA = uicontrol(Data.ui.fH,'Style','PushButton',...
        'Units','Normalized',...
        'Position',[xst+4*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Full walk A',...
        'CallBack',[mfilename,'(''fullwalkA'',0);']);
    %     Data.ui.pbAImage = uicontrol(Data.ui.fH,'Style','PushButton',...
    %         'Units','Normalized',...
    %         'Position',[xst+5*(wid+xoff)+(0*xoff) yst wid ht],...
    %         'String','aam2weights',...
    %         'CallBack',[mfilename,'(''aam2weights'',0);']);
    %     set(Data.ui.pbAImage,'visible','off');
    %     Data.ui.pbImage2 = uicontrol(Data.ui.fH,'Style','PushButton',...
    %         'Units','Normalized',...
    %         'Position',[xst+5*(wid+xoff)+(0*xoff) yst wid ht],...
    %         'String','pdm2weights',...
    %         'CallBack',[mfilename,'(''pdm2weights'',1);']);
    %     set(Data.ui.pbImage2,'visible','off');
end
Data.ui.pbAtoImage = uicontrol(Data.ui.fH,'Style','PushButton',...
    'Units','Normalized',...
    'Position',[xst+6*(wid+xoff)+(0*xoff) yst wid ht],...
    'String','All_wts',...
    'CallBack',[mfilename,'(''Weights'',0);']);
set(Data.ui.pbAtoImage,'visible','off');
% Data.ui.all_pbAtoImage = uicontrol(Data.ui.fH,'Style','PushButton',...
%     'Units','Normalized',...
%     'Position',[xst+6*(wid+xoff)+(0*xoff) yst wid ht],...
%     'String','Weights',...
%     'CallBack',[mfilename,'(''all_aam2weights'',0);']);
% set(Data.ui.all_pbAtoImage,'visible','on');

% Setup horizontal controls Top bank
YST   = 0.01;										% Main Y offset
XST   = 0.01;										% Main X offset
HT    = 0.12 - YST - 0.01;							% Main height
HT    = 0.08 - YST - 0.01;							% Main height
WID   = 0.6 - XST - 0.01; 							% Main width

nc    = 8;											% no. controls
yoff  = 0.01;										% control y offset
xoff  = 0.01;										% control x offset
extra = 0;											% extra yoffs (spacing)

top   = 0.06;
xst   = XST + xoff;									% horz. start
yst   = YST + yoff + top;									% vert. start
ht    = HT - (yoff * 2);							% control width
wid   = (WID - (nc+1+extra)*xoff) / nc;				% control height

uicontrol(Data.ui.fH,'Style','frame',...
    'Units','Normalized',...
    'Position',[XST YST+top WID HT],...
    'BackgroundColor',[0.6 0.6 0.6]);

% Setup other buttons
uicontrol(Data.ui.fH,'Style','frame',...
    'Units','Normalized',...
    'Position',[XST YST+top WID HT]);


%'CallBack',[mfilename, ' fullwalk']);

if ~isempty(aam)
    Data.ui.linesH = uicontrol(Data.ui.fH,'Style','toggle',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+0*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Points',...
        'CallBack',[mfilename,'(''ShowLines'',0);']);
    Data.ui.pictureH(1) = uicontrol(Data.ui.fH,'Style','radiobutton',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+1*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','No image',...
        'CallBack',[mfilename,'(''ShowImage'',0);']);
    Data.ui.pictureH(2) = uicontrol(Data.ui.fH,'Style','radiobutton',...
        'Units','Normalized',...
        'Value',1,...
        'Position',[xst+2*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Result',...
        'CallBack',[mfilename,'(''ShowImage'',1);']);
    Data.ui.pictureH(3) = uicontrol(Data.ui.fH,'Style','radiobutton',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+3*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Image1',...
        'Visible','off',...
        'CallBack',[mfilename,'(''ShowImage'',2);']);
    Data.ui.pictureH(4) = uicontrol(Data.ui.fH,'Style','radiobutton',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+4*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Model1',...
        'Visible','off',...
        'CallBack',[mfilename,'(''ShowImage'',3);']);
    Data.ui.pictureH(5) = uicontrol(Data.ui.fH,'Style','radiobutton',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+5*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Image2',...
        'Visible','off',...
        'CallBack',[mfilename,'(''ShowImage'',4);']);
    Data.ui.pictureH(6) = uicontrol(Data.ui.fH,'Style','radiobutton',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+6*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Model2',...
        'Visible','off',...
        'CallBack',[mfilename,'(''ShowImage'',5);']);
    Data.ui.pmlinesH = uicontrol(Data.ui.fH,'Style','pushbutton',...
        'Units','Normalized',...
        'Value',0,...
        'Position',[xst+7*(wid+xoff)+(0*xoff) yst wid ht],...
        'String','Click-on',...
        'CallBack',[mfilename,'(''pmLines'',0);']);
end
% Setup axes
%ax = axes('Position',[0.025 0.15 0.65 0.825],'DrawMode','Fast');
Data.ui.ax = axes('Position',[0.025 0.18 0.7 0.81],'DrawMode','Fast');
% Display window
set(Data.ui.fH,'Visible','on')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = Initialise(pdm,aam,options)

Data=Initialise_GUI(pdm,aam,options);
Data.sd_stepsize=0.5;
Data.NumModes=1;
Data.oversize_by=1.2;
% Plot model
Data.pdm.bW = zeros(Data.pdm.Nmodes,1);
% first plot and create the model
if ~isempty(aam)
    templatename=aam(findstr(aam,'StatisticalModels')+length('StatisticalModels')+1:end);
    templatename=templatename(1:findstr(templatename,'Set_')-2);
    templatename=fullfile('Templates',[templatename,'.temp_dat']);
    temppmt=load(templatename,'-mat');
    Data.pmt=temppmt.PMTemplate;
    % since the weights are zero, the model becomes the mean shape
    [DummyH,model]=PlotModel(Data.pdm);
    Data.aam.bWA = zeros(size(Data.aam.b));
    [Data.ui.lHA,wimg,net_offset]=ShowModel(Data.aam,model,Data.oversize_by);
    % now plot the lines over the top of the image
    hold on
    loops=get(Data.pmt,'loops');
    Data.edges=loops{1};
    Data.ui.lH=PlotModel(Data.pdm,DummyH,net_offset,get(Data.ui.linesH,'value'),Data.edges);
    Data.net_offset_xy=net_offset;
    set( Data.ui.lH,'Visible','off');
    hold off
    Data.aam.bW = zeros(length(Data.aam.b),1);
else
    Data.ui.lH=PlotModel(Data.pdm);
    Data.ui.lHA=[];
    Data.aam.bW=[];
end
ax = axis;
nx = round((ax(2) - ax(1))/4);
ny = round((ax(4) - ax(3))/4);
%axis([ax(1)-nx/2 ax(2)+nx/2 ax(3)-ny/2 ax(4)+ny/2])
axis('off')
Data.pdm.axis=axis;%/1.2;
set(gca,'FontSize',8)

% Global for animation interupt
global gInterrupt gAnimate gInterruptA gAnimateA ;
gInterrupt = 0;
gAnimate = 0;
gInterruptA = 0;
gAnimateA = 0;

% Initialise
Data.ui.lastpb = 0;

% Display window
set(Data.ui.fH,'Visible','on')


function [fH,pbH,teH,slH,sdH,pbzerosH,pbzero1H,dis_ptsH,multiH,thresholdH,quantisationH]=...
    Setup_vertical_controls(aam_flag,XST,YST,HT,Data,fH,minVal,maxVal,stVal,nmodes,title)
%XST   = 0.7;										% Main X offset
%HT    = 1.0 - YST - 0.01;							% Main height
%HT    = (1.0 - YST)/2 - 0.01;							% Main height
WID   = 1.0 - XST - 0.01; 							% Main width
LWID  = WID/6;										% Total label width
AWID  = WID/6;										% Total animate pb width
SWID  = WID - (2 * LWID) - AWID;					% Total slider width

nc    = nmodes; %Data.pdm.Nmodes;							% no. vert controls
%yoff  = 0.01;										% control y offset
yoff  = 0.00;										% control y offset
xoff  = 0.01;										% control x offset

xst   = XST;										% horz. start
yst   = YST + yoff +0.1;									% vert. start
%yst   = 0.5 + YST + yoff;									% vert. start

lwid  = LWID - (xoff * 2);							% label width
awid  = (AWID - xoff)/2;							% animate button width
swid  = SWID;										% slider width
lst1  = xst + xoff;									% label 1 start
lst2  = xst + LWID + SWID + xoff;					% label 2 start
sst   = xst + AWID+AWID/4; %+ LWID;					% slider start
ast   = xst + LWID + SWID + LWID/2;					% animate pb start

ht    = 0.85*(HT - (nc+1)*yoff) / nc;	 				% main control height
ht1   = 2*2 * (ht / 4);								% normal height
ht2   = 2*ht / 3;										% text height


uicontrol(fH,'Style','text',...
    'String',title,...
    'Units','Normalized',...
    'Position',[XST yst-0.11 .15 0.02]);
%    'Position',[XST yst WID HT]);
%	'Position',[XST YST WID HT]);

if aam_flag
    thresholdH=uicontrol(fH,'Style','popupmenu',...
        'String',[{'>0.0 SD'},{'>0.5 SD'},{'>1.0 SD'},{'>1.5 SD'},{'>2.0 SD'},{'>2.5 SD'}],...
        'value',1,...
        'Units','Normalized',...
        'Position',[XST+swid yst-0.11 swid 2*ht1],...
        'Callback',[mfilename, '(''threshold'',0);']);
    quantisationH=uicontrol(fH,'Style','popupmenu',...
        'String',[{'No quantisation'},{'2 bit quantisation'},{'3 bit quantisation'},...
        {'4 bit quantisation'},{'5 bit quantisation'}],...
        'value',1,...
        'Units','Normalized',...
        'Position',[XST+swid yst-0.14 swid 2*ht1],...
        'Callback',[mfilename, '(''quantisation'',0);']);
    multiH = uicontrol(Data.ui.fH,'Style','popupmenu',...
        'Units','Normalized',...
        'String',[{'0%'},{'50%'},{'100%'},{'150%'},{'200%'}],...
        'value',3,...
        'Position',[XST+swid yst-0.08 swid 2*ht1],...
        'Callback',[mfilename, '(''multiplier'',1);']);
%     dis_ptsH = uicontrol(Data.ui.fH,'Style','text',...
%         'Units','Normalized',...
%         'String','pix distance',...
%         'HorizontalAlignment','left',...
%         'Position',[XST yst-0.08 swid 2*ht1]);
dis_ptsH=[];
else
    thresholdH=uicontrol(fH,'Style','popupmenu',...
        'String',[{'>0.0 SD'},{'>0.5 SD'},{'>1.0 SD'},{'>1.5 SD'},{'>2.0 SD'},{'>2.5 SD'}],...
        'value',1,...
        'Units','Normalized',...
        'Position',[XST+swid yst-0.11 swid 2*ht1],...
        'Callback',[mfilename, '(''threshold'',1);']);
    quantisationH=uicontrol(fH,'Style','popupmenu',...
        'String',[{'No quantisation'},{'2 bit quantisation'},{'3 bit quantisation'},...
        {'4 bit quantisation'},{'5 bit quantisation'}],...
        'value',1,...
        'Units','Normalized',...
        'Position',[XST+swid yst-0.14 swid 2*ht1],...
        'Callback',[mfilename, '(''quantisation'',1);']);
    multiH = uicontrol(Data.ui.fH,'Style','popupmenu',...
        'Units','Normalized',...
        'String',[{'0%'},{'50%'},{'100%'},{'150%'},{'200%'}],...
        'value',3,...
        'Position',[XST+swid yst-0.08 swid 2*ht1],...
        'Callback',[mfilename, '(''multiplier'',0);']);
%     dis_ptsH = uicontrol(Data.ui.fH,'Style','text',...
%         'Units','Normalized',...
%         'String','pts distance',...
%         'HorizontalAlignment','left',...
%         'Position',[XST yst-0.08 swid 2*ht1]);
dis_ptsH=[];
end


for k=1:nmodes %Data.pdm.Nmodes
    uival = nmodes-k+1; %Data.pdm.Nmodes - k + 1;

    if aam_flag
        % Sliders
        slH(uival)=uicontrol(fH,...
            'Style','Slider',...
            'Units','Normalized',...
            'Position',[sst yst+(k-1)*(ht+yoff) swid ht1],...
            'Min',minVal,...
            'Max',maxVal,...
            'Value',stVal,...
            'Callback',[mfilename,'(''movesliderA'');']);
    else
        % Sliders
        slH(uival)=uicontrol(fH,...
            'Style','Slider',...
            'Units','Normalized',...
            'Position',[sst yst+(k-1)*(ht+yoff) swid ht1],...
            'Min',minVal,...
            'Max',maxVal,...
            'Value',stVal,...
            'Callback',[mfilename,'(''moveslider'');']);
    end
    if aam_flag
        sdH(uival) = uicontrol(Data.ui.fH,'Style','text',...
            'Units','Normalized',...
            'Value',0,...
            'HorizontalAlignment','left',...
            'Position',[lst1 yst+(k-1)*(ht+yoff) lwid ht1]);
    else
        sdH(uival) = uicontrol(Data.ui.fH,'Style','text',...
            'Units','Normalized',...
            'Value',0,...
            'HorizontalAlignment','left',...
            'Position',[lst1 yst+(k-1)*(ht+yoff) lwid ht1]);
    end
    % Slider labels
    teH(uival)=uicontrol(fH,...
        'Style','text',...
        'Units','Normalized',...
        'Background','y',...
        'Position',[ast+3*(awid+0.001) yst+(k-1)*(ht+yoff) swid/4 ht1],...
        'HorizontalAlignment','left',...
        'Visible','on',...
        'String',num2str(uival));
    %         teH(uival)=uicontrol(fH,...
    %             'Style','text',...
    %             'Units','Normalized',...
    %             'Position',[sst yst+(k-1)*(ht+yoff)+ht1 swid ht2],...
    %             'HorizontalAlignment','center',...
    %             'Visible','off',...
    %             'String',['Mode ', num2str(uival), '  0.00']);
    if aam_flag
        % Animate buttons
        pbH(uival)=uicontrol(fH,...
            'Style','PushButton',...
            'Units','Normalized',...
            'Position',[ast yst+(k-1)*(ht+yoff) awid ht1],...
            'Interruptible','on',...
            'Callback',[mfilename,'(''walkA'');']);
        % Zero buttons
        pbzerosH = uicontrol(Data.ui.fH,'Style','PushButton',...
            'Units','Normalized',...
            'Value',0,...
            'Position',[ast+awid+0.001 yst+(k-1)*(ht+yoff) awid ht1],...
            'Backgroundcolor','b',...
            'CallBack',[mfilename,sprintf('(''ZeroslidersA'',%d);',uival)]);
        pbzero1H(uival) = uicontrol(Data.ui.fH,'Style','PushButton',...
            'Units','Normalized',...
            'Value',0,...
            'Position',[ast+2*(awid+0.001) yst+(k-1)*(ht+yoff) awid ht1],...
            'Backgroundcolor','c',...
            'CallBack',[mfilename,sprintf('(''ZeroslidersA'',%d);',-uival)]);
    else
        % Animate buttons
        pbH(uival)=uicontrol(fH,...
            'Style','PushButton',...
            'Units','Normalized',...
            'Position',[ast yst+(k-1)*(ht+yoff) awid ht1],...
            'Interruptible','on',...
            'Callback',[mfilename,'(''walk'');']);
        % Zero buttons
        pbzerosH = uicontrol(Data.ui.fH,'Style','PushButton',...
            'Units','Normalized',...
            'Value',0,...
            'Position',[ast+awid+0.001 yst+(k-1)*(ht+yoff) awid ht1],...
            'Backgroundcolor','b',...
            'CallBack',[mfilename,sprintf('(''Zerosliders'',%d);',uival)]);
        pbzero1H(uival) = uicontrol(Data.ui.fH,'Style','PushButton',...
            'Units','Normalized',...
            'Value',0,...
            'Position',[ast+2*(awid+0.001) yst+(k-1)*(ht+yoff) awid ht1],...
            'Backgroundcolor','c',...
            'CallBack',[mfilename,sprintf('(''Zerosliders'',%d);',-uival)]);
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                     Plot Functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [pdmout,bW,sd]=modify_weights(pdm,bW,sd,mode)
if nargin<2
    bW=pdm.bW;
end
if nargin<3
    sd=0;
end
bW=bW*pdm.multi;
if isfield(pdm,'threshold')
    sd = bW./sqrt(pdm.b);
    if pdm.threshold>0 %& (abs(sd)<pdm.threshold)
        ind=find(abs(sd)<pdm.threshold);
        bW(ind)=0;
    end
end
sd = bW./sqrt(pdm.b);
if isfield(pdm,'quantisation')
    if pdm.quantisation>1 
        q=pdm.quantisation-1;
        % 2 then 2 bits. 1 bit for sign and 1 per 1.5 sd's
        % 3 then 3 bits. 1 bit for sign and 2 per 1.5 sd's
        sd = bW./sqrt(pdm.b);
        sdq = round(1.5*sd*2^q)/1.5;
        bW=sdq*sqrt(pdm.b);
    end
end
pdmout=pdm;
pdmout.bW=bW;

function [pdm,bW,sd]=modify_weightsA(pdm,bW,sd,mode)
if nargin<2
    bW=aam.bW;
end
if nargin<3
    sd=0;
end
if nargin<4
    if isfield(pdm,'threshold')
        sd = bW./sqrt(pdm.b);
        if pdm.threshold>0 & (abs(sd)<pdm.threshold)
            ind=find(abs(sd)<pdm.threshold);
            bW=pdm.bW;
            bW(ind)=0;
        end
    end
    bW=bW * pdm.multi;
    sd = bW./sqrt(pdm.b);
else
    if isfield(pdm,'threshold')
        sd = bW./sqrt(pdm.b);
        if pdm.threshold>0 & (abs(sd)<pdm.threshold)
            bW(mode)=0;
        else
            bW=pdm.bW(mode);
        end
    end
    bW=bW * pdm.multi;
    sd = bW./sqrt(pdm.b);
end
if isfield(pdm,'quantisation')
    if pdm.quantisation>1 
        q=pdm.quantisation-1;
        % 2 then 2 bits. 1 bit for sign and 1 per 1.5 sd's
        % 3 then 3 bits. 1 bit for sign and 2 per 1.5 sd's
        sd = pdm.bW./sqrt(pdm.b);
        sdq = round(1.5*sd*2^q)/1.5;
        bW=sdq*sqrt(pdm.b);
    end
end
%model = pdm.Xm + pdm.P * pdm.bW * pdm.multi;	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handlelH, model]=PlotModel(pdm, handlelH, net_offset, showlinesflag, edges)
% Plot model
if nargin<2
    handlelH=[];
end
if nargin<3
    net_offset=[0,0]; %
end
if nargin<4
    showlinesflag=0;
    linesH=[];
end
if nargin<5
    edges=[];
end
%[pdm,bW,sd]=modify_weights(pdm);
model = pdm.Xm + pdm.P * pdm.bW; % * pdm.multi;	
% if original image is present, offset into image
if nargout==1
    model2.pts(:,1)=model(1:2:pdm.Nvals)+net_offset(1); % offset into display
    model2.pts(:,2)=model(2:2:pdm.Nvals)+net_offset(2);
    model2.subject=pdm.subject;
    %if showlinesflag
        if isempty(handlelH)
%             if ~isempty(edges)
%                 for e = 1:size(edges,1)
%                     handlelH(length(handlelH)+1) = plot(...
%                         [model2.pts(edges(e,1),1),model2.pts(edges(e,2),1)], ...
%                         [model2.pts(edges(e,1),2),model2.pts(edges(e,2),2)], ...
%                         '-r', 'LineWidth', 1.5, 'MarkerEdgeColor', [112/255 91/255 223/255], 'HitTest', 'off');
%                 end
%             end
            handlelH(length(handlelH)+1) = plot(model2.pts(:,1), model2.pts(:,2),'.r');
        else
            %             for e = 1:size(edges,1)
            %                 set(handlelH(e),...
            %                     'XData',[model2.pts(edges(e,1),1),model2.pts(edges(e,2),1)], ...
            %                     'YData',[model2.pts(edges(e,1),2),model2.pts(edges(e,2),2)]);
            %             end
            if ishandle(handlelH(end))
                set(handlelH(end),...
                    'XData',model2.pts(:,1), ...
                    'YData',model2.pts(:,2));
            else
                handlelH(length(handlelH)) = plot(model2.pts(:,1), model2.pts(:,2),'.r');
            end
        end
%         set(handlelH,'Visible','on');
%     else
%         set(handlelH,'Visible','off')
%     end
    %handlelH = PlotFaceOutline(model2,1,handlelH);
%     if nargin>2
%         value=showlinesflag;
%         if value<1
%             set(handlelH,'visible','on')
%         else
%             set(handlelH,'visible','off')
%         end
%     end
%     %drawnow
    axis('ij')
    %axis('image')
%     if isfield(pdm,'axis')
%         axis(pdm.axis);
%     end
end

function [handlelHA,wimg,net_offset,handlelHAP,statistics]=ShowModel(...
    aam, model, oversize_by, handlelHA, pictureH, pictureflag,...
    pts, handlelHAP,img2,w_image_pts,w_image_itself, w_image_indexes,speedflag)
if nargin<3
    oversize_by=1.4;
end
if nargin<4
    handlelHA=[];
end
if nargin<6
    pictureflag=0;
    pts=[];
end
if nargin<8
    handlelHAP=0;
end
if nargin<9
    img2=[];
end
if nargin<10
    w_image_pts=[];
end
if nargin<11
    w_image_itself=[];
end
if nargin<12
    w_image_indexes=[];
end
if nargin<13
    speedflag=[];
end
if isfield(aam,'threshold')
    sd = aam.bWA./sqrt(aam.b);
    ind=find(abs(sd)<aam.threshold);
    bWA=aam.bWA;
    bWA(ind)=0;
else    
    bWA=aam.bWA;
end
% if isfield(aam,'quantisation')
%     if pdm.quantisation>1 
%         q=pdm.quantisation-1;
%         % 2 then 2 bits. 1 bit for sign and 1 per 1.5 sd's
%         % 3 then 3 bits. 1 bit for sign and 2 per 1.5 sd's
%         sd = pdm.bW./sqrt(pdm.b);
%         sdq = round(1.5*sd*2^q)/1.5;
%         bW=sdq*sqrt(pdm.b);
%     end
% end%img = aam.Am+aam.P*aam.bWA*aam.multi;
img = double(aam.Am)+aam.P * bWA * aam.multi;
img = reshape(img, [aam.siz(2), aam.siz(1), 3]);
% now we need to warp it to the following shape
rmodel=reshape(model',2,length(model)/2)';
% 
% set up the display image using the original mean pointmodel
% zero the offset
mean_rmodel=reshape(aam.pdm.Xm',2,length(aam.pdm.Xm)/2)';
x_zoffset=min(mean_rmodel(:,1));
y_zoffset=min(mean_rmodel(:,2));
mean_zmodel(:,1)=mean_rmodel(:,1)-x_zoffset;
mean_zmodel(:,2)=mean_rmodel(:,2)-y_zoffset;
% centre into a larger display image
%oversize_by=1.2;
disp_img=zeros(floor([oversize_by*max(mean_zmodel(:,2)),oversize_by*max(mean_zmodel(:,1)),3]));
[rows,cols,planes]=size(disp_img);

x_zoffset=min(rmodel(:,1));
y_zoffset=min(rmodel(:,2));
zmodel(:,1)=rmodel(:,1)-x_zoffset;
zmodel(:,2)=rmodel(:,2)-y_zoffset;
x_middle_zmodel=mean(zmodel(:,1));
y_middle_zmodel=mean(zmodel(:,2));
x_offset=floor((cols/2)-(x_middle_zmodel)); %floor((cols-max(mean_zmodel(:,1)))/2);
y_offset=floor((rows/2)-(y_middle_zmodel)); %floor((rows-max(mean_zmodel(:,2)))/2);
net_offset=[x_offset-x_zoffset, y_offset-y_zoffset];

% Find the pixels that will be warped
timg=triwarp(100*ones(size(img(:,:,1))),aam.ompts,zmodel);
ind=find(timg>1);
% and offset the indexes into the display image
[indy,indx]=ind2sub(size(timg(:,:,1)),ind);
indx_off=indx+x_offset;
indx_off=min(indx_off,cols);
indx_off=max(indx_off,1);
indy_off=indy+y_offset;
indy_off=min(indy_off,rows);
indy_off=max(indy_off,1);
% convert from subscripts back to array index
ind_off=sub2ind(size(disp_img(:,:,1)),indy_off,indx_off);
% now warp the mean image (appearance) to right size
wimg=triwarp(img,aam.ompts,zmodel); % upsample to zero offset
% and insert the pixels that have been warped into the display
[wrows,wcols,wplanes]=size(wimg);
rdisp_img=reshape(disp_img,rows*cols,planes);
rwimg=reshape(wimg,wrows*wcols,wplanes);
rdisp_img(ind_off,:)=rwimg(ind,:);
disp_img=reshape(rdisp_img,[rows,cols,planes]);
% insert into the display image
wimg = disp_img;
wimg = wimg - min(min(min(wimg)));
wimg = wimg / max(max(max(wimg)));
if ~isempty(img2)
    if speedflag==1 % only compute statistics using middle of warped original image
        statistics.n_vertices=length(model(:));
        statistics.dist_pts=sqrt(sum((model(:)-w_image_pts(:)).^2))/statistics.n_vertices;
        [rows,cols,planes]=size(w_image_itself);
        rimg3=reshape(w_image_itself,rows*cols,planes);
        rimg=reshape(img,rows*cols,planes);
        statistics.n_pixels=planes*length(w_image_indexes);
        statistics.dist_pts=sqrt(sum((rimg3(w_image_indexes,:)-rimg(w_image_indexes,:)).^2))/statistics.n_pixels;        
    else % put the newly generated image into the original picutre
        %M2 = calctrm(pts, model, ones(length(pts)/2, 1));
        % the model comes from plotmodel and accounts for slider positions
        M2 = calctrm(pts, model(:), ones(length(pts)/2, 1));
        model2=applytrm(model(:), M2);
        statistics.n_vertices=length(model2(:));
        statistics.dist_pts=sqrt(sum((model2(:)-pts(:)).^2))/statistics.n_vertices;
        picture_rmodel=reshape(model2',2,length(model)/2)';
        % ensure the image fills the full range of intensities
        img2=double(img2); % imported image
        img2=img2-min(min(min(img2)));
		img2=255*img2/max(max(max(img2)));
        img=double(img); % mean or reference image
        img=img-min(min(min(img)));
		img=255*img/max(max(max(img)));
        % Find the pixels that will be warped
        timg=triwarp(100*ones(size(img2(:,:,1))),aam.ompts,picture_rmodel);
        [rows2,cols2,planes2]=size(img2);
        ind=find(timg>1);
        [ii,jj]=ind2sub(size(timg),ind); %correct indexes but ind is wrong size
        % now warp the mean image (appearance) to right size
        picture_img=triwarp(img,aam.ompts,picture_rmodel); % upsample to zero offset
        % and insert the pixels that have been warped into the display
        [prows,pcols,pplanes]=size(picture_img);
        temp=zeros(size(img2)); % placing the model in the same size image
        temp(1:min(rows2,prows),1:min(cols2,pcols),:)=picture_img(1:min(rows2,prows),1:min(cols2,pcols),:);
        ind=find(ii>rows2);
        ii(ind)=rows2;
        ind=find(jj>cols2);
        jj(ind)=cols2;
        % find the indexes for the correct indexes
        indtemp=sub2ind(size(temp),ii,jj);
        % now reshape so as to use the indexes in ind
        rtemp=reshape(temp,rows2*cols2,planes2);
        rimg2=reshape(img2,rows2*cols2,planes2);
        rimg2(indtemp,:)=rtemp(indtemp,:);
        picture_wimg=reshape(rimg2,[rows2,cols2,planes2]);
    end
else
    statistics=[];
    dist_pts=0;
    dist_aam=0;
    picture_wimg=[];
end
%if nargout==1
if isempty(handlelHA)
    handlelHA=image(wimg);
else
    if ishandle(handlelHA)
        set(handlelHA,'CData',wimg);
    else
        handlelHA=image(wimg);
    end
end
axis equal
%drawnow
if nargin>3
    if get(pictureH(2),'value') | get(pictureH(5),'value')
        set(handlelHA,'visible','on')
    else
        set(handlelHA,'visible','off')
    end
end
if pictureflag~=0
    hold on
    if isempty(handlelHAP)
        handlelHAP=image(uint8(picture_wimg));
    else
        if ishandle(handlelHAP)
            set(handlelHAP,'CData',uint8(picture_wimg));
        else
            handlelHAP=image(uint8(picture_wimg));
        end
    end
    hold off
    axis equal
    %drawnow
    if nargin>3
        value=get(pictureH(3),'value');
        if value<1
            set(handlelHAP,'visible','off')
        else
            set(handlelHAP,'visible','on')
        end
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function SetLabel(h,mode,value)
% Set slider label text

set(h,'String',['Mode ',num2str(mode),'  ',num2str(value,'%.2f'),'sd']);
set(h,'visible','off');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = MoveSlider(Data,mode,sd,b,speedflag)
global SETWEIGHTS
% Someone moved a slider
if nargin<5
    speedflag=0;
end
if nargin<2
    % Which push button was pressed?
    mode = find(Data.ui.slH == gcbo);
    % Get values
    sd = get(Data.ui.slH(mode),'Value');
end
if nargin==4
    Data.pdm.bW(mode) = b;
    Data.pdm.bWflag(mode)=0;
    set(Data.ui.pbzero1H(min([mode,size(Data.ui.pbzero1H,2)])),'backgroundcolor','c');
    for i=1:length(Data.ui.slH)
        mode=i; % set slider positions using variance in b
        sd=Data.pdm.multi*Data.pdm.bW(mode)/sqrt(Data.pdm.b(mode));
        if isfield(Data.pdm,'threshold')
            if abs(sd)<Data.pdm.threshold
                sd=0;
            end
        end
        if sd>4
            sd=4;
            Data.pdm.bW(mode)=4*sqrt(Data.pdm.b(mode));
        elseif sd<-4
            sd=-4;
            Data.pdm.bW(mode)=-4*sqrt(Data.pdm.b(mode));
        end
        if SETWEIGHTS==1
            [Data.plot_pdm,bW,sd]=modify_weights(Data.pdm,Data.pdm.bW,sd,i);
        else
            Data.plot_pdm=Data.pdm;
        end
        sd=round(sd*100)/100;
        %SetLabel(Data.ui.teH(mode),mode,sd);
        set(Data.ui.slH(mode),'Value',sd);
        set(Data.ui.sdH(mode),'String',sd,'foregroundcolor','b');
    end
else
    % Update slider
    sd=round(sd*100)/100;
    %SetLabel(Data.ui.teH(mode),mode,sd);
    Data.pdm.bW(mode) = sd * sqrt(Data.pdm.b(mode)); % b is variance of mode
    if SETWEIGHTS==1
        [Data.plot_pdm,bW,sd]=modify_weights(Data.pdm,Data.pdm.bW,sd,mode);
    else
        Data.plot_pdm=Data.pdm;
    end
    Data.pdm.bWflag(mode)=0;
    set(Data.ui.slH(mode),'Value',sd);
    set(Data.ui.sdH(mode),'String',sd,'foregroundcolor','b');
    set(Data.ui.pbzero1H(mode),'backgroundcolor','c');
end
%if ~isempty(Data.aam)
if ~isempty(Data.options.sfam)
    if isfield(Data,'image')
        image_pts=Data.image.pts; % should be the mean
        image_itself=Data.options.image.img;
        w_image_pts=Data.image.meansize_pm;
        w_image_itself=Data.image.meansize_img;
        w_image_indexes=Data.image.pixel_indexes;
        if isfield(Data.ui,'handlelHAP')
            handlelHAP=Data.ui.handlelHAP;
        else
            handlelHAP=[];
        end
    else
        image_pts=[];
        image_itself=[];
        w_image_pts=[];
        w_image_itself=[];
        w_image_indexes=[];
        handlelHAP=[];
    end
    [DummyH,model]=PlotModel(Data.plot_pdm); % get model
    %[DummyH,model]=PlotModel(Data.pdm); % get model
    [Data.ui.lHA,wimg,net_offset,Data.ui.handlelHAP,Data.aam.statistics]=...
        ShowModel(Data.aam,model,Data.oversize_by,Data.ui.lHA,Data.ui.pictureH,...
        1,image_pts,handlelHAP,image_itself,w_image_pts,w_image_itself,w_image_indexes,speedflag);
    hold on
    Data.ui.lH=PlotModel(Data.plot_pdm,Data.ui.lH,net_offset,get(Data.ui.linesH,'value'),Data.edges);% plot model
    hold off
    drawnow
else
    Data.ui.lH=PlotModel(Data.plot_pdm,Data.ui.lH);
    Data.ui.lHA=[];
    drawnow
end
drawnow
if Data.movieflag
    if ~isfield(Data,'Movie')
        Data.Movie=[];
    end
    if Data.movie_imageonly==1
        Data.Movie=[Data.Movie,getframe(gca)];
    else
        Data.Movie=[Data.Movie,getframe(gcf)];
    end
end

function Data = MoveSliderA(Data,mode,sd,b,pictureflag,speedflag)
global SETWEIGHTS
if nargin<6
    speedflag=0;
end
if nargin<5
    pictureflag=0;
    model=[];
end
% Someone moved a slider
% Which push button was pressed?
if nargin<2
    mode = find(Data.ui.slHA == gcbo);
    % Get values
    sd = get(Data.ui.slHA(mode),'Value');
end
if nargin>=4
    Data.aam.bWA(mode) = b;
    Data.aam.bWAflag(mode)=0;
    set(Data.ui.pbzero1HA(min([mode,size(Data.ui.pbzero1HA,2)])),'backgroundcolor','c');
    for i=1:length(Data.ui.slHA)
        mode=i; % set slider positions using variance in b
        sd=Data.aam.multi*Data.aam.bWA(mode)/sqrt(Data.aam.b(mode));
        if isfield(Data.aam,'threshold')
            if abs(sd)< Data.aam.threshold
                sd=0;
            end
        end
        if sd>4
            sd=4;
            Data.aam.bWA(mode)=4*sqrt(Data.aam.b(mode));
        elseif sd<-4
            sd=-4;
            Data.aam.bWA(mode)=-4*sqrt(Data.aam.b(mode));
        end
        sd=round(sd*100)/100;
        %SetLabel(Data.ui.teHA(mode),mode,sd);
        if SETWEIGHTS==1
            [aam,bWA,sd]=modify_weightsA(Data.aam,Data.aam.bWA,sd,i);
        else
            aam=Data.aam;
        end
        set(Data.ui.slHA(mode),'Value',sd);
        set(Data.ui.sdHA(mode),'String',sd,'foregroundcolor','b');
    end
else
    % Update
    sd=round(sd*100)/100;
    %SetLabel(Data.ui.teHA(mode),mode,sd);
    Data.aam.bWA(mode) = sd * sqrt(Data.aam.b(mode));
    Data.aam.bWAflag(mode)=0;
    if SETWEIGHTS==1
        [aam,bWA,sd]=modify_weightsA(Data.aam,Data.aam.bWA,sd,mode);
    else
        aam=Data.aam;
    end
    set(Data.ui.slHA(mode),'Value',sd);
    set(Data.ui.sdHA(mode),'String',sd,'foregroundcolor','b');
    set(Data.ui.pbzero1HA(mode),'backgroundcolor','c');
end
% generate the texture
if ~isempty(Data.aam)
    [dummyH,model]=PlotModel(Data.pdm); % get model
    if isfield(Data,'image')
        image_pts=Data.image.pts;
        image_itself=Data.options.image.img;
        w_image_pts=Data.image.meansize_pm;
        w_image_itself=Data.image.meansize_img;
        w_image_indexes=Data.image.pixel_indexes;
        if isfield(Data.ui,'handlelHAP')
            handlelHAP=Data.ui.handlelHAP;
        else
            handlelHAP=[];
        end
    else
        image_pts=[];
        image_itself=[];
        handlelHAP=[];
        w_image_pts=[];
        w_image_itself=[];
        w_image_indexes=[];
    end
    if ~isfield(Data.ui,'handlelHAP')
        Data.ui.handlelHAP=[];
    end
    [Data.ui.lHA,wimg,net_offset,Data.ui.handlelHAP,Data.aam.statistics]=...
        ShowModel(Data.aam,model,Data.oversize_by,Data.ui.lHA,Data.ui.pictureH,pictureflag,...
        image_pts,Data.ui.handlelHAP,image_itself,w_image_pts,w_image_itself,w_image_indexes,speedflag);  % show image
    hold on
%         if ishandle(Data.ui.lH)
%             delete(Data.ui.lH);
% 			Data.ui.lH=[];
%         end
    %if ~get(Data.ui.linesH,'Value')
        Data.ui.lH=PlotModel(Data.pdm,Data.ui.lH,net_offset,get(Data.ui.linesH,'value'),Data.edges);% plot model
    %else
    %    Data.ui.lH=PlotModel(Data.pdm,Data.ui.lH,net_offset,get(Data.ui.linesH,'value'));% plot model
    %end
    hold off
else
    Data.ui.lH=PlotModel(Data.pdm);
    Data.ui.lHA=[];
end
drawnow
if Data.movieflag
    if ~isfield(Data,'Movie')
        Data.Movie=[];
    end
    if Data.movie_imageonly==1
        Data.Movie=[Data.Movie,getframe(gca)];
    else
        Data.Movie=[Data.Movie,getframe(gcf)];
    end
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = Zerosliders(Data,options)
% Return sliders to 0
% Reset any animation
global gInterruptA
gInterruptA = 1;
if options<0
    k=-options;
    if Data.pdm.bW(k) ~= 0
        Data=MoveSlider(Data,k,0);
    end
    Data.pdm.bW(k) = 0;
    set(Data.ui.pbzero1H(k),'backgroundcolor','w');
else
    k=length(Data.pdm.b):-1:options;
    Data=MoveSlider(Data,k,0);
    set(Data.ui.pbzero1H(k),'backgroundcolor','w');
%     for k=length(Data.pdm.b):-1:options
%         if Data.pdm.bW(k) ~= 0
%             Data=MoveSlider(Data,k,0);
%         end
%         Data.pdm.bW(k) = 0;
%         set(Data.ui.pbzero1H(k),'backgroundcolor','w');
%         drawnow
%     end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = ZeroslidersA(Data,options)
% Return sliders to 0
% Reset any animation
global gInterruptA
gInterruptA = 1;
if options<0
    k=-options;
    if Data.aam.bWA(k) ~= 0
        Data=MoveSliderA(Data,k,0);
    end
    set(Data.ui.pbzero1HA(k),'backgroundcolor','w');
else
    k=length(Data.aam.b):-1:options;
    Data=MoveSliderA(Data,k,0);
    set(Data.ui.pbzero1HA(k),'backgroundcolor','w');
%     for k=length(Data.aam.b):-1:options
%         if Data.aam.bWA(k) ~= 0
%             Data=MoveSliderA(Data,k,0);
%         end
%         Data.aam.bWA(k) = 0;
%         set(Data.ui.pbzero1HA(k),'backgroundcolor','w');
%         drawnow
%     end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = ResetSliders(Data,options)
% Return sliders to 0
if nargin<2
    options=0;
end
% Reset any animation
global gInterrupt
gInterrupt = 1;
set(Data.ui.multiH,'value',3);
Data.pdm.multi=1;
Data.aam.multi=1;

Data=MoveSlider(Data,Data.pdm.Nmodes:-1:1,0,zeros(size(Data.pdm.b)));
drawnow;
% for k=Data.pdm.Nmodes:-1:1
%     if Data.pdm.bW(k) ~= 0
%         Data=MoveSlider(Data,k,0);
%     end
% 	Data.pdm.bW(k) = 0;
%     if options==1
%         drawnow
%     end
% end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = ResetSlidersA(Data,options)
% Return sliders to 0
% Reset any animation
global gInterruptA
gInterruptA = 1;
Data=MoveSliderA(Data,1:length(Data.aam.bW),0,zeros(size(Data.aam.bW)));
drawnow
% for k=length(Data.aam.b):-1:1
%     if Data.aam.bWA(k) ~= 0
%         Data=MoveSliderA(Data,k,0);
%     end
% 	Data.aam.bWA(k) = 0;
%     if options==1
%         drawnow
%     end
% end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=FullWalk(Data,option)
% Walk through all modes in turn
global gInterrupt2;
if option==1
    set(Data.ui.pbWalk,...
        'String','Full walk',...
        'CallBack',[mfilename,'(''fullwalk'',0);']);
    gInterrupt2=1;
else
    set(Data.ui.pbWalk,...
        'String','Stop Full walk',...
        'CallBack',[mfilename,'(''fullwalk'',1);']);
    gInterrupt2=0;
    
    STEPSIZE = Data.sd_stepsize;
    %STEPSIZE = 0.5;
    % Reset all sliders
   % eval([mfilename, '(''reset'',0);'])
    h=get(gca,'children');
    %delete(h); %for some reason we need to force clear old lines
    % Walk through each mode in turn
    
    idx = 0:-STEPSIZE:Data.ui.minVal/2;
    idx = [idx, Data.ui.minVal/2:STEPSIZE:Data.ui.maxVal/2];
    idx = [idx, Data.ui.maxVal/2:-STEPSIZE:0];
    now=clock;
    dt=0;
    if Data.NumModes==1
        number_modes=Data.pdm.Nmodes;
    else
        number_modes=Data.NumModes;
    end
    for m=1:number_modes
        for k=1:length(idx)
            if ~gInterrupt2
                Data=MoveSlider(Data,m,idx(k));
                drawnow
                dt=etime(clock,now);
                while dt<Data.preference.speed
                    dt=etime(clock,now);
                end
                now=clock;
            end
        end
    end
    set(Data.ui.pbWalk,...
        'String','Full walk',...
        'CallBack',[mfilename,'(''fullwalk'',0);']);
    gInterrupt2=1;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=FullWalkA(Data,option)
% Walk through all modes in turn
global gInterrupt2A;
if option==1
    set(Data.ui.pbWalkA,...
        'String','Full walkA',...
        'CallBack',[mfilename,'(''fullwalkA'',0);']);
    gInterrupt2A=1;
else
    set(Data.ui.pbWalkA,...
        'String','Stop Full walkA',...
        'CallBack',[mfilename,'(''fullwalkA'',1);']);
    gInterrupt2A=0;
    STEPSIZE = Data.sd_stepsize;
    %STEPSIZE = 0.5;
    % Reset all sliders
   % eval([mfilename, '(''reset'',0);'])
    h=get(gca,'children');
    %delete(h); %for some reason we need to force clear old lines
    % Walk through each mode in turn
    
    idx = 0:-STEPSIZE:Data.ui.minVal/2;
    idx = [idx, Data.ui.minVal/2:STEPSIZE:Data.ui.maxVal/2];
    idx = [idx, Data.ui.maxVal/2:-STEPSIZE:0];
    now=clock;
    dt=0;
    if Data.NumModes==1
        number_modes=length(Data.aam.b);
    else
        number_modes=Data.NumModes;
    end
    for m=1:number_modes %   for m=1:length(Data.aam.b) %Data.pdm.Nmodes
        for k=1:length(idx)
            if ~gInterrupt2A
                Data=MoveSliderA(Data,m,idx(k));
                drawnow
                dt=etime(clock,now);
                while dt<Data.preference.speed
                    dt=etime(clock,now);
                end
                now=clock;
            end
        end
    end
    set(Data.ui.pbWalkA,...
        'String','Full walk',...
        'CallBack',[mfilename,'(''fullwalkA'',0);']);
    gInterrupt2A=1;
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = Walk(Data, mode)
% Animate given mode

% Global for interrupt
global gInterrupt gAnimate;

% Currently running one so stop it
if gAnimate
	gInterrupt = 1;
	return
end

STEPSIZE = 0.5;

% Which push button was pressed?
if isempty(mode)
	mode = find(Data.ui.pbH == gcbo);
end

% Highlight button and get values
set(Data.ui.pbH(mode),'BackgroundColor',[1.0 0.0 0.0]);
maxVal = get(Data.ui.slH(mode),'Max')/2;
minVal = get(Data.ui.slH(mode),'Min')/2;
sd = get(Data.ui.pbH(mode),'Value');

% Initialise animation
gInterrupt = 0;
gAnimate = mode;
now=clock;
dt=0;

while ~gInterrupt
    while sd < (maxVal -STEPSIZE) & ~gInterrupt
        Data=MoveSlider(Data,mode,sd);
        drawnow
        sd = sd + STEPSIZE;
        dt=etime(clock,now);
        while dt<Data.preference.speed
            dt=etime(clock,now);
        end
        now=clock;
    end
    while sd > (minVal + STEPSIZE) & ~gInterrupt
        Data=MoveSlider(Data,mode,sd);
        drawnow
        sd = sd - STEPSIZE;
        dt=etime(clock,now);
        while dt<Data.preference.speed
            dt=etime(clock,now);
        end
        now=clock;
    end
end

% Reset animation
set(Data.ui.pbH(mode),'BackgroundColor','default');
gAnimate = 0;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data = WalkA(Data, mode)
% Animate given mode

% Global for interrupt
global gInterruptA gAnimateA;

% Currently running one so stop it
if gAnimateA
	gInterruptA = 1;
	return
end

STEPSIZE = 0.5;

% Which push button was pressed?
if isempty(mode)
	mode = find(Data.ui.pbHA == gcbo);
end

% Highlight button and get values
set(Data.ui.pbHA(mode),'BackgroundColor',[1.0 0.0 0.0]);
maxVal = get(Data.ui.slHA(mode),'Max')/2;
minVal = get(Data.ui.slHA(mode),'Min')/2;
sd = get(Data.ui.pbHA(mode),'Value');

% Initialise animation
gInterruptA = 0;
gAnimateA = mode;
now=clock;
dt=0;

while ~gInterruptA
    while sd < (maxVal -STEPSIZE) & ~gInterruptA
        Data=MoveSliderA(Data,mode,sd);
        drawnow
        sd = sd + STEPSIZE;
        dt=etime(clock,now);
        while dt<Data.preference.speed
            dt=etime(clock,now);
        end
        now=clock;
    end
    while sd > (minVal + STEPSIZE) & ~gInterruptA
        Data=MoveSliderA(Data,mode,sd);
        drawnow
        sd = sd - STEPSIZE;
        dt=etime(clock,now);
        while dt<Data.preference.speed
            dt=etime(clock,now);
        end
        now=clock;
    end
end
% Reset animation
set(Data.ui.pbHA(mode),'BackgroundColor','default');
gAnimateA = 0;



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                     File Functions 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Quit(FigH)
% Quit!

% Stop any animations
global gInterrupt gAnimate
if gAnimate
	gInterrupt = 1;
	return
end

close(FigH)
clear global gInterrupt
