function [] = PreProcessImages(arg, argoption)
global AAMShapemodel_figure_handle
global AAMModelGenerator_handle
global AAMModelBuilder_handle
global AAMSetPicker_handle
global UpdateModel_handle
global PMTemplateBuilder_handle
global PDMWalk_handle
global ShapeSpaceTool_handle
global PreProcess_gui_handle;
if isa(arg, 'AAM')

    PreProcess_gui_handle = openfig(mfilename, 'reuse');
    Data.handles = guihandles(PreProcess_gui_handle);
    Data.handles.figMain = PreProcess_gui_handle;
    set(Data.handles.figMain, 'Color', get(Data.handles.respanel, 'BackgroundColor'));
    Data.handles.aam = arg;
    Data.handles = Initialise(Data.handles);
            if exist('AAMShapemodel_figure_handle')
        if ishandle(AAMShapemodel_figure_handle)
            set(AAMShapemodel_figure_handle,'visible','off');
        end
    end
    guidata(PreProcess_gui_handle, Data);
else
    Data = guidata(PreProcess_gui_handle);
    switch arg
        case 'SelectRegion'
            [Data.handles] = SelectRegion(Data.handles);
        case 'ChangeRes'
            [Data.handles] = ChangeRes(Data.handles);
        case 'GlobalChangeRes'
            [Data.handles] = GlobalChangeRes(Data.handles);        
        case 'Crop'
            [Data.handles] = Crop(Data.handles);
        case 'SelectDir'
            [Data.handles] = SelectDir(Data.handles);
        case 'Next'
            [Data.handles] = Next(Data.handles);
        case 'Skip'
            [Data.handles] = Skip(Data.handles);
        case 'Prev'
            [Data.handles] = Prev(Data.handles);
        case 'Save'
            [Data.handles] = Save(Data.handles);
        case 'Quit'
            if exist('AAMShapemodel_figure_handle')
                if ishandle(AAMShapemodel_figure_handle)
                    set(AAMShapemodel_figure_handle,'visible','on');
                end
            end
            [Data.handles] = Quit(Data.handles);        
        otherwise
            fprintf('Unknown option\n');
    end
    if isfield(Data.handles, 'figMain')
        guidata(PreProcess_gui_handle, Data);
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Quit
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Quit(handles)
delete(handles.figMain);
handles = rmfield(handles, 'figMain');
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Initialise
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Initialise(handles)
%handles.dat.directoryname = get(handles.aam, 'imageDirectory');
handles.dat.directoryname = 'Cropped';
if exist(handles.dat.directoryname, 'dir')
files = dir([handles.dat.directoryname, filesep, '*.JPG']);
handles.dat.files = {files.name};
fprintf('Directory, %s\n', handles.dat.directoryname); 
for f = 1:length(handles.dat.files)
   fprintf('Filename, %s\n', handles.dat.files{f}); 
end
if length(handles.dat.files)>0
    set(handles.filenameList, 'String', handles.dat.files);
    set(handles.filenameList, 'value', 1);
    handles.dat.currentIndex = 1;
    handles = Skip(handles);
    handles = UpdateImage(handles);
else
    set(handles.filenameList, 'String', 'No images');
    set(handles.filenameList, 'value', 1);
    handles.dat.currentIndex = 1;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Save
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Save(handles)
imwrite(handles.dat.CurrentImage, [handles.dat.CurrentImageDir, filesep, handles.dat.CurrentImageName]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SelectRegion
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = SelectRegion(handles)
BW = roipoly;
handles.dat.CurrentImage(:,:,1) = handles.dat.CurrentImage(:,:,1).*BW;
handles.dat.CurrentImage(:,:,2) = handles.dat.CurrentImage(:,:,2).*BW;
handles.dat.CurrentImage(:,:,3) = handles.dat.CurrentImage(:,:,3).*BW;
L = bwlabel(BW);
S = regionprops(L, 'BoundingBox');
R = S(1).BoundingBox;
%handles.dat.CurrentImage = imcrop(handles.dat.CurrentImage,R);
handles = UpdateImage(handles);
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GlobalChangeRes
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = GlobalChangeRes(handles)
files = handles.dat.files;
dir = handles.dat.directoryname;
res = str2num(get(handles.resTxt, 'String'));
w = waitbar(0, 'Applying global resolution change, please wait...');
for f = 1:length(files)
    waitbar(f/length(files), w);
    I = imread([dir, filesep, files{f}]);
    I = double(I);
    I = I./max(I(:));
    I = imresize(I, res);
    imwrite(I, [dir, filesep, files{f}]);
    clear I;
end
close(w);
handles = Skip(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ChangeRes
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = ChangeRes(handles)
res = str2num(get(handles.resTxt, 'String'));
handles.dat.CurrentImage = imresize(handles.dat.CurrentImage, res);
handles = UpdateImage(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Next
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Next(handles)
N = length(handles.dat.files);
v = get(handles.filenameList, 'value');
if (v < N)
    v = v +1;
    handles.dat.currentIndex =   handles.dat.currentIndex + 1;
else
    v = N;
end
set(handles.filenameList, 'value', v);
handles = Skip(handles);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Prev
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Prev(handles)
N = length(handles.dat.files);
v = get(handles.filenameList, 'value');
if (v > 1)
    v = v -1;
    handles.dat.currentIndex =   handles.dat.currentIndex + 1;
else
    v = 1;
end
set(handles.filenameList, 'value', v);
handles = Skip(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Select image directory
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = SelectDir(handles)
handles.dat.directoryname = uigetdir(pwd);
if handles.dat.directoryname~=0
files = dir([handles.dat.directoryname, filesep, '*.JPG']);
handles.dat.files = {files.name};
fprintf('Directory, %s\n', handles.dat.directoryname); 
for f = 1:length(handles.dat.files)
   fprintf('Filename, %s\n', handles.dat.files{f}); 
end
if length(handles.dat.files)>0
    set(handles.filenameList, 'String', handles.dat.files);
    set(handles.filenameList, 'value', 1);
    handles.dat.currentIndex = 1;
    handles = Skip(handles);
    handles = UpdateImage(handles);
else
    set(handles.filenameList, 'String', 'No images');
    set(handles.filenameList, 'value', 1);
    handles.dat.currentIndex = 1;
end
end
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Skip
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Skip(handles)
handles.dat.currentIndex = get(handles.filenameList, 'value');
I = imread([handles.dat.directoryname, filesep,handles.dat.files{handles.dat.currentIndex}]);
I = double(I);
handles.dat.CurrentImage = I./max(I(:));
handles.dat.CurrentImageName = handles.dat.files{handles.dat.currentIndex};
handles.dat.CurrentImageDir = handles.dat.directoryname;
handles = UpdateImage(handles);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Update Image
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = UpdateImage(handles)

imagesc(handles.dat.CurrentImage, 'Parent', handles.mainAxes, 'HitTest', 'off');
axis(handles.mainAxes, 'image');
set(handles.imwidthTxt, 'String', num2str(size(handles.dat.CurrentImage,2)));
set(handles.imheightTxt, 'String', num2str(size(handles.dat.CurrentImage,1)));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Process Image
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [handles] = Crop(handles)
[x, y] = ginput(1);
width = str2num(get(handles.widthTxt, 'String'));
height = str2num(get(handles.heightTxt, 'String'));
fprintf('Width, %d, Height, %d\n', width, height);

ys = round(x-width/2)
yf = round(x+width/2)-1
xs = round(y-height/2)
xf = round(y+height/2)-1

if xs<1
    xs = 1;
end
if xf>size(handles.dat.CurrentImage,1)
    xf = size(handles.dat.CurrentImage,1);
end
if ys < 1
    ys = 1;
end
if yf > size(handles.dat.CurrentImage,2)
    yf = size(handles.dat.CurrentImage,2);
end
handles.dat.CurrentImage = handles.dat.CurrentImage(xs:xf, ys:yf,:);
if size(handles.dat.CurrentImage,1)<height 
    r= [handles.dat.CurrentImage(:,:,1); zeros(height - size(handles.dat.CurrentImage,1), size(handles.dat.CurrentImage, 2))];
    g = [handles.dat.CurrentImage(:,:,2); zeros(height - size(handles.dat.CurrentImage,1), size(handles.dat.CurrentImage, 2))];
    b = [handles.dat.CurrentImage(:,:,3); zeros(height - size(handles.dat.CurrentImage,1), size(handles.dat.CurrentImage, 2))];

handles.dat.CurrentImage = [];
handles.dat.CurrentImage(:,:,1) = r;
handles.dat.CurrentImage(:,:,2) = g;
handles.dat.CurrentImage(:,:,3) = b;
end
if size(handles.dat.CurrentImage,2)<width
    r = [handles.dat.CurrentImage(:,:,1), zeros(size(handles.dat.CurrentImage, 1), width - size(handles.dat.CurrentImage,2))];
    g = [handles.dat.CurrentImage(:,:,2), zeros(size(handles.dat.CurrentImage, 1), width - size(handles.dat.CurrentImage,2))];
    b = [handles.dat.CurrentImage(:,:,3), zeros(size(handles.dat.CurrentImage, 1), width - size(handles.dat.CurrentImage,2))];
    handles.dat.CurrentImage = [];
    handles.dat.CurrentImage(:,:,1) = r;
    handles.dat.CurrentImage(:,:,2) = g;
    handles.dat.CurrentImage(:,:,3) = b;
end
handles = UpdateImage(handles);
return;