function varargout = create_mask_GUI_export(varargin)
% CREATE_MASK_GUI_EXPORT MATLAB code for create_mask_GUI_export.fig
%      CREATE_MASK_GUI_EXPORT, by itself, creates a new CREATE_MASK_GUI_EXPORT or raises the existing
%      singleton*.
%
%      H = CREATE_MASK_GUI_EXPORT returns the handle to a new CREATE_MASK_GUI_EXPORT or the handle to
%      the existing singleton*.
%
%      CREATE_MASK_GUI_EXPORT('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in CREATE_MASK_GUI_EXPORT.M with the given input arguments.
%
%      CREATE_MASK_GUI_EXPORT('Property','Value',...) creates a new CREATE_MASK_GUI_EXPORT or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before create_mask_GUI_export_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to create_mask_GUI_export_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help create_mask_GUI_export

% Last Modified by GUIDE v2.5 29-Oct-2018 10:23:50

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @create_mask_GUI_export_OpeningFcn, ...
                   'gui_OutputFcn',  @create_mask_GUI_export_OutputFcn, ...
                   'gui_LayoutFcn',  @create_mask_GUI_export_LayoutFcn, ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [~, s] = gui_mainfcn(gui_State, varargin{:});

    varargout{1} = s;
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before create_mask_GUI_export is made visible.
function create_mask_GUI_export_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to create_mask_GUI_export (see VARARGIN)

s.done = false;
s.apply = false;

if(nargin > 3)
    for index = 1:2:(nargin-3)
        if nargin-3==index, break, end
        s.(varargin{index}) = varargin{index+1};
    end
end


% disable saving function if not needed / wanted
if s.disable_save
    handles.pushbutton4.Visible = 'off';
end

% Choose default command line output for create_mask_GUI_export
handles.output = hObject;
handles.figure1.UserData = utils.update_param(handles.figure1.UserData, s);

% Update handles structure
guidata(hObject, handles);


% This sets up the initial plot - only do when we are invisible
% so window can get raised using create_mask_GUI_export.
if handles.figure1.UserData.mask3D
    mask_questdlg = questdlg('Detected a 3D dataset. Do you want to create a 3D mask?', '3D mask', 'Yes', 'No', 'Yes');
    switch mask_questdlg
        case 'Yes'
            handles.figure1.UserData.mask3D = true;
        case 'No'
            handles.figure1.UserData.mask3D = false;
    end
end

if handles.figure1.UserData.mask3D
    handles.figure1.UserData.mask_asize = [size(handles.figure1.UserData.mask,1) size(handles.figure1.UserData.mask,2) 1 handles.figure1.UserData.mask_dims];
    handles.figure1.UserData.mask_temp = reshape(repmat(handles.figure1.UserData.mask, [1, 1, handles.figure1.UserData.mask_dims]), handles.figure1.UserData.mask_asize);
else
    handles.figure1.UserData.mask_asize = size(handles.figure1.UserData.mask);
    handles.figure1.UserData.mask_temp = handles.figure1.UserData.mask;
end

handles.figure1.UserData.layerInfo = [];

if strcmp(get(hObject,'Visible'),'off')
    if ~handles.figure1.UserData.mask3D
        imagesc(handles.figure1.UserData.mask); axis equal tight xy
    else
        plotting.imagesc3D(squeeze(prod(handles.figure1.UserData.mask_temp,3))); axis equal tight xy
        set(handles.figure1.UserData.apply_to_stack_toggle, 'Visible', 'on')
        handles.figure1.UserData.stack = true;
        handles.figure1.UserData.listener_orig = handles.axes1.slider_handle.listener('Value','PostSet',@(src, evnt)fig_slice_update(handles));
    end
end
if ~isempty(handles.figure1.UserData.load_mask)
    append_mask(handles, handles.figure1.UserData.load_mask);
end




% listener for imagesc3D - update slice
function fig_slice_update(s)
val = s.axes1.slider_handle.Value;
set(s.figure1.UserData.ax.slider_handle, 'Value', val);
set(s.figure1.UserData.ax.edit_handle, 'String', num2str(val));
s.figure1.UserData.ax.update_fig(s.figure1.UserData.ax);


% --- Outputs from this function are returned to the command line.
function varargout = create_mask_GUI_export_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;
varargout{2} = handles;
update_image(handles)
update_mask_GUI(handles)


function [sel] = getSelType(handles)
toolbarIndex = -1;
for ii=1:numel(handles.figure1.Children)
    if contains(class(handles.figure1.Children(ii)), 'Toolbar')
        toolbarIndex = ii;
    end
end
if toolbarIndex < 0
    error('No toolbar available');
end

icons = handles.figure1.Children(toolbarIndex);
for ii=1:length(icons.Children)
    if strcmpi(icons.Children(ii).State, 'on')
        sel = ii;
    end
end


% --- Executes on button press in pushbutton1.
% add more pixels
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    add_selection(handles, -1, false, true, true, -1, [])

function add_selection(handles, selectionType, updateFigureBefore, updateFigureAfter, forceWait, sliceUpdate, position)

if sliceUpdate < 0
    sliceExists = false;
    sliceUpdate = size(handles.figure1.UserData.mask_temp,3);
else
    sliceExists = true;
    backupSlice = handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,:);
end
handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,:) = ones(handles.figure1.UserData.mask_asize);

if updateFigureBefore
    update_image(handles)
    update_mask_GUI(handles)
end

ax = handles.figure1.UserData.ax;
if isprop(ax, 'user_title')
    current_title = ax.user_title;
else
    current_title = '';
end

    % update title
    title(ax,'Select bad pixels. Double-click to confirm selection.','Interpreter', 'none', 'FontSize', 10);
    
    % get selection
    if selectionType < 0
        toolSel = getSelType(handles);
    else 
        toolSel = selectionType;
    end
        
    layerInfo = [];
    switch toolSel
        case 1
            % polygon
            if ~isempty(position)
                h = impoly(ax, position);
            else
                h = impoly(ax);
            end
            if forceWait
                wait(h);
            end
            layerInfo.type = 'selection';
            layerInfo.shape = 'polygon';

        case 2
            % create rectangle
            if ~isempty(position)
                h = imrect(ax, position);
            else
                h = imrect(ax);
            end
            if forceWait
                wait(h);
            end
            layerInfo.type = 'selection';
            layerInfo.shape = 'rectangle';

        case 3
            % circle
            if ~isempty(position)
                h = imellipse(ax, position);
            else
                h = imellipse(ax);
            end
            if forceWait
                wait(h);
            end
            layerInfo.type = 'selection';
            layerInfo.shape = 'circle';

        otherwise
            error('Unknonwn handle');
            
    end
    try
        layerInfo.position = h.getPosition;
        updateSlice = true;
    catch
        updateSlice = false;
    end

    if updateSlice
        if handles.figure1.UserData.mask3D && ~handles.figure1.UserData.stack
            % I guess one can change the if condition to projection/noprojection
            slice = handles.figure1.UserData.ax.slider_handle.Value;
            handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,slice) = (1-h.createMask()).*handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,slice);
        else
            handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,:) = (1-h.createMask()).*handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,:);
        end
        
        if updateFigureAfter
            update_image(handles)
            update_mask_GUI(handles)
        end
        if ~sliceExists
            % append layerInfo to storage
            handles.figure1.UserData.layerInfo{end+1} = layerInfo;
            tmpHist = handles.figure1.UserData.layer_history.String;
            if isempty(tmpHist)
                if isfield(layerInfo, 'shape')
                    tmpHist = {layerInfo.shape};
                else
                    tmpHist = {layerInfo.type};
                end
            else
                if isfield(layerInfo, 'shape')
                    tmpHist{end+1} = layerInfo.shape;
                else
                    tmpHist{end+1} = layerInfo.type;
                end
            end
            handles.figure1.UserData.layer_history.String = tmpHist;
            handles.figure1.UserData.layer_history.Value = length(tmpHist);
            clear tmpHist;
        else
            handles.figure1.UserData.layerInfo{sliceUpdate} = layerInfo;
        end
    else
        if sliceExists
            handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,:) = backupSlice;
        else
            handles.figure1.UserData.mask_temp(:,:,sliceUpdate+1,:) = [];
        end
    end
    h.delete;

     % revert changes to the title
    if ax.isprop('update_title') && ax.update_title && ~isempty(ax.vars.title_list)
        %%% imagesc3D
        % get slice
        slice = round(get(ax.slider_handle,'Value'));
        slice = max(1, min(length(vars.order), slice));
        % write title
        if isempty(vars.title_list)
            ax.update_title = false;
            if ~isempty(ax.user_title)
                title_text = sprintf(ax.user_title, slice);
                title(ax, title_text, 'Interpreter', 'none');
            end
            ax.update_title = true;
        else
            if ~isempty(vars.title_list)
                title(ax, vars.title_list{slice}, 'Interpreter', 'none')
            end
        end
    else
        %%% normal imagesc
        title(ax, current_title);
    end

% ---------------------------------------------------------------------
function update_mask_GUI(handles)
if handles.figure1.UserData.mask3D
    slice = handles.figure1.UserData.ax.slider_handle.Value;
    handles.axes1.Children.CData = squeeze(prod(handles.figure1.UserData.mask_temp(:,:,:,slice),3));
    handles.axes1.img = squeeze(prod(handles.figure1.UserData.mask_temp,3));
else
    handles.axes1.Children.CData = squeeze(prod(handles.figure1.UserData.mask_temp,3));
end
handles.figure1.UserData.mask = handles.axes1.Children.CData;

function update_mask3D(handles, pos)
if handles.figure1.UserData.mask3D && ~handles.figure1.UserData.stack
    % I guess one can change the if condition to projection/noprojection
    slice = handles.figure1.UserData.ax.slider_handle.Value;
    handles.figure1.UserData.mask_temp(pos(2):pos(2)+pos(4),pos(1):pos(1)+pos(3), end, slice) = 0;
else
    handles.figure1.UserData.mask_temp(pos(2):pos(2)+pos(4),pos(1):pos(1)+pos(3),end,:) = 0;
end
        
function update_image(handles)

ax = handles.figure1.UserData.ax;
if ndims(handles.figure1.UserData.mask_temp)==3
    ax.Children(end).CData = handles.figure1.UserData.CData .* prod(handles.figure1.UserData.mask_temp,3);
elseif ndims(handles.figure1.UserData.mask_temp)==4
    slice = handles.figure1.UserData.ax.slider_handle.Value;
    ax.Children(end).CData = handles.figure1.UserData.CData .* prod(handles.figure1.UserData.mask_temp(:,:,:,slice),3);
else
    ax.Children(end).CData = handles.figure1.UserData.CData .*handles.figure1.UserData.mask_temp;
end

if isfield(handles.figure1.UserData, 'img_orig')
    if ndims(handles.figure1.UserData.mask_temp)>=3
        ax.img = handles.figure1.UserData.img_orig .* squeeze(prod(handles.figure1.UserData.mask_temp,3));
    else
        ax.img = handles.figure1.UserData.img_orig .* handles.figure1.UserData.mask_temp;
    end
end


% --------------------------------------------------------------------
function FileMenu_Callback(hObject, eventdata, handles)
% hObject    handle to FileMenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function OpenMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to OpenMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
file = uigetfile('*.fig');
if ~isequal(file, 0)
    open(file);
end

% --------------------------------------------------------------------
function PrintMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to PrintMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
printdlg(handles.figure1)

% --------------------------------------------------------------------
function CloseMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to CloseMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
selection = questdlg(['Close ' get(handles.figure1,'Name') '?'],...
                     ['Close ' get(handles.figure1,'Name') '...'],...
                     'Yes','No','Yes');
if strcmp(selection,'No')
    return;
end
handles.figure1.UserData.done = true;
pause(0.2)


% --- Executes on selection change in popupmenu1.
function popupmenu1_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu1 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu1
keyboard

% --- Executes during object creation, after setting all properties.
function popupmenu1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
     set(hObject,'BackgroundColor','white');
end

set(hObject, 'String', {'plot(rand(5))', 'plot(sin(1:0.01:25))', 'bar(1:.5:10)', 'plot(membrane)', 'surf(peaks)'});


% --- Executes on button press in pushbutton2.
% undo
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if size(handles.figure1.UserData.mask_temp,3)>1
    sel = handles.figure1.UserData.layer_history.Value;
    handles.figure1.UserData.mask_temp(:,:,sel+1,:) = [];
    handles.figure1.UserData.layerInfo(sel) = [];
    handles.figure1.UserData.layer_history.String(sel) = [];
    handles.figure1.UserData.layer_history.Value = length(handles.figure1.UserData.layer_history.String);
    update_mask_GUI(handles)
    update_image(handles)
end


% --- Executes on button press in pushbutton3.
% load mask
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[fname, fpath, indx] = uigetfile({'*.h5', 'Nexus (*.h5)'; '*.mat', 'Binary mask (*.mat)'});

fname_full = fullfile(fpath, fname);

if ~isempty(fname_full) || length(fnname_full)<2
    
    try
        append_mask(handles, fname_full);
    catch
        fprintf('Failed to load file.\n')
    end

end
update_mask_GUI(handles)
update_image(handles)


% handles.figure1.UserData = s;

function append_mask(handles, fname_full)

[~, ~, ext] = fileparts(fname_full);

switch ext
    case '.h5'
        mask = io.HDF.hdf5_load(fname_full, '-c');
        if isfield(mask, 'history')
            process_history(handles, mask);
        else
            maskOut = math.applyTransform(mask.entry.collection.mask, handles.figure1.UserData.mask_orientation, 'transpose_rot90');
%             maskOut = io.nexus_read(fname_full, 'filter', 'mask');
            if ndims(maskOut)~=ndims(squeeze(handles.figure1.UserData.mask_temp(:,:,1,:))) || any(size(maskOut) ~= size(squeeze(handles.figure1.UserData.mask_temp(:,:,1,:))))
                fprintf('ERROR. Mask dimensions don''t match.\n')
            end
            try
                if handles.figure1.UserData.mask3D && size(maskOut,3)==1 && handles.figure1.UserData.stack
                    % apply mask to 3D stack
                    maskOut = repmat(maskOut, [1 1 size( handles.figure1.UserData.mask_temp,4)]);
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = maskOut;
                elseif handles.figure1.UserData.mask3D && size(maskOut,3)==1 && ~handles.figure1.UserData.stack
                    % get current slider value and apply mask to single
                    % slice
                    slice = handles.figure1.UserData.ax.slider_handle.Value;
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = handles.figure1.UserData.mask_temp(:,:,end,:);
                    handles.figure1.UserData.mask_temp(:,:,end,slice) = maskOut;
                else
                    % 2D case
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = maskOut;
                end
                layerInfo = [];
                layerInfo.type = 'mask';
                layerInfo.fname = fname_full;
                append_layer_info(handles, layerInfo);
            catch
                fprintf('Failed to append mask.\n')
            end
        end
        
    case '.mat'
        
        f = load(fname_full);
        if isfield(f, 'mask')
            % load binary mask
            if ndims(f.mask)~=ndims(squeeze(handles.figure1.UserData.mask_temp(:,:,1,:))) || any(size(f.mask) ~= size(squeeze(handles.figure1.UserData.mask_temp(:,:,1,:))))
                fprintf('ERROR. Mask dimensions don''t match.\n')
            end
            try
                if handles.figure1.UserData.mask3D && size(f.mask,3)==1 && handles.figure1.UserData.stack
                    % apply mask to 3D stack
                    f.mask = repmat(f.mask, [1 1 size( handles.figure1.UserData.mask_temp,4)]);
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = f.mask;
                elseif handles.figure1.UserData.mask3D && size(f.mask,3)==1 && ~handles.figure1.UserData.stack
                    % get current slider value and apply mask to single
                    % slice
                    slice = handles.figure1.UserData.ax.slider_handle.Value;
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = handles.figure1.UserData.mask_temp(:,:,end,:);
                    handles.figure1.UserData.mask_temp(:,:,end,slice) = f.mask;
                else
                    % 2D case
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = f.mask;
                end
                layerInfo = [];
                layerInfo.type = 'mask';
                layerInfo.fname = fname_full;
                append_layer_info(handles, layerInfo);
            catch
                fprintf('Failed to append mask.\n')
            end
        elseif isfield(f, 'valid_mask')
            % load indices for mask
            if numel(f.valid_mask.framesize)~=ndims(squeeze(handles.figure1.UserData.mask_temp(:,:,1,:))) || any(f.valid_mask.framesize ~= size(squeeze(handles.figure1.UserData.mask_temp(:,:,1,:))))
                fprintf('ERROR. Mask dimensions don''t match.\n')
            end
            try
                if handles.figure1.UserData.mask3D && numel(f.valid_mask.framesize)==2 && handles.figure1.UserData.stack
                    % apply mask to 3D stack
                    mask = repmat(beamline.ind2mask(f.valid_mask), [1 1 size( handles.figure1.UserData.mask_temp,4)]);
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = mask;
                elseif handles.figure1.UserData.mask3D && numel(f.valid_mask.framesize)==2 && ~handles.figure1.UserData.stack
                    % get current slider value and apply mask to single
                    % slice
                    slice = handles.figure1.UserData.ax.slider_handle.Value;
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = handles.figure1.UserData.mask_temp(:,:,end,:);
                    handles.figure1.UserData.mask_temp(:,:,end,slice) = beamline.ind2mask(f.valid_mask);
                else
                    % 2D case
                    handles.figure1.UserData.mask_temp(:,:,end+1,:) = beamline.ind2mask(f.valid_mask);
                end
                layerInfo = [];
                layerInfo.type = 'mask';
                layerInfo.fname = fname_full;
                append_layer_info(handles, layerInfo);
            catch
                fprintf('Failed to append mask.\n')
            end
        elseif isfield(f, 'history')
            process_history(handles, f);
        end
end

    

function process_history(handles, f)
ax = handles.figure1.UserData.ax;
for ii=1:numel(f.history)
    layerInfo = [];
    switch f.history{ii}.type
        case 'selection'
            handles.figure1.UserData.mask_temp(:,:,end+1,:) = ones(handles.figure1.UserData.mask_asize);
            switch f.history{ii}.shape
                case 'rectangle'
                    h = imrect(ax, f.history{ii}.position);
                    layerInfo.type = 'selection';
                    layerInfo.shape = 'rectangle';
                    layerInfo.position = h.getPosition;
                case 'polygon'
                    h = impoly(ax, f.history{ii}.position);
                    layerInfo.type = 'selection';
                    layerInfo.shape = 'polygon';
                    layerInfo.position = h.getPosition;
                case 'circle'
                    h = imellipse(ax, f.history{ii}.position);
                    layerInfo.type = 'selection';
                    layerInfo.shape = 'circle';
                    layerInfo.position = h.getPosition;
                    
                otherwise
                    error('Unknown selection shape')
            end
            if handles.figure1.UserData.mask3D && ~handles.figure1.UserData.stack
                % I guess one can change the if condition to projection/noprojection
                slice = handles.figure1.UserData.ax.slider_handle.Value;
                handles.figure1.UserData.mask_temp(:,:,end,slice) = (1-h.createMask()).*handles.figure1.UserData.mask_temp(:,:,end,slice);
            else
                handles.figure1.UserData.mask_temp(:,:,end,:) = (1-h.createMask()).*handles.figure1.UserData.mask_temp(:,:,end,:);
            end
            h.delete;
            
            % append layerInfo to storage
            append_layer_info(handles, layerInfo)
            
        case 'mask'
            append_mask(handles, f.history{ii}.fname);
            
        otherwise
            error('Unknown layer type.')
    end
    
    
    update_image(handles)
    update_mask_GUI(handles)
    
    
end

function append_layer_info(handles, layerInfo)
handles.figure1.UserData.layerInfo{end+1} = layerInfo;
tmpHist = handles.figure1.UserData.layer_history.String;
if isempty(tmpHist)
    if isfield(layerInfo, 'shape')
        tmpHist = {layerInfo.shape};
    else
        tmpHist = {layerInfo.type};
    end
else
    if isfield(layerInfo, 'shape')
        tmpHist{end+1} = layerInfo.shape;
    else
        tmpHist{end+1} = layerInfo.type;
    end
end
handles.figure1.UserData.layer_history.String = tmpHist;
handles.figure1.UserData.layer_history.Value = length(tmpHist);

% --- Executes on button press in pushbutton4.
% save mask
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if isempty(handles.figure1.UserData.default_filename)
    filename = 'new_mask';
end
[fname, fpath, ftype] = uiputfile({'*.h5', 'Nexus (*.h5)'; '*.mat',...
 'Binary mask (*.mat)';
 '*.mat', 'Indices (*.mat)'}, 'Save mask', filename);
fname_full = fullfile(fpath, fname);
if ~isempty(fname_full)
    try
        switch ftype
            case 1
                % nexus mask
                mask = squeeze(prod(handles.figure1.UserData.mask_temp,3));
                io.save_mask_nexus(fname_full, mask);
            case 2
                % binary mask
                mask = squeeze(prod(handles.figure1.UserData.mask_temp,3));
                save(fname_full, 'mask');
            case 3
                % indices
                mask = squeeze(prod(handles.figure1.UserData.mask_temp,3));
                valid_mask = beamline.mask2ind(mask);
                save(fname_full, 'valid_mask');
        end
        fprintf('Saved mask to %s.\n', fname_full)
    catch ME
        fprintf('Failed to save file.\n')
    end
end


% --- Executes on button press in pushbutton4.
% reset
function revert_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
handles.figure1.UserData.mask_temp = ones(handles.figure1.UserData.mask_asize);
handles.figure1.UserData.layerInfo = [];
handles.figure1.UserData.layer_history.String = '';
update_mask_GUI(handles);
update_image(handles);


% --- Executes on button press in quit.
% quit
function quit_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
CloseMenuItem_Callback(hObject, eventdata, handles)


function listbox_callback(hObject, eventdata, handles)
    if strcmp(get(gcf, 'selectiontype'), 'open')
        backup = handles.figure1.UserData.mask_temp;
        try
            cVal = handles.figure1.UserData.layer_history.Value;
            layerInfo = handles.figure1.UserData.layerInfo{cVal};
            ax = handles.figure1.UserData.ax;
            switch layerInfo.type
                case 'selection'
                    switch layerInfo.shape
                        case 'rectangle'
                            add_selection(handles, 2, true, true, true, cVal, layerInfo.position)
                        case 'polygon'
                            add_selection(handles, 1, true, true, true, cVal, layerInfo.position)
                        case 'circle'
                            add_selection(handles, 3, true, true, true, cVal, layerInfo.position)
                        otherwise
                            error('Unknown selection shape')
                    end
%                     handles.figure1.UserData.mask_temp(:,:,cVal+1,:) = ones(handles.figure1.UserData.mask_asize);
%                     update_mask_GUI(handles)
%                     update_image(handles)
%                     switch layerInfo.shape
%                         case 'rectangle'
%                             h = imrect(ax, layerInfo.position);
%                             h.wait();
%                         case 'polygon'
%                             h = impoly(ax, layerInfo.position);
%                             h.wait();
%                         case 'circle'
%                             h = imellipse(ax, layerInfo.position);
%                             h.wait();
%                         otherwise
%                             error('Unknown selection shape')
%                     end
%                     if handles.figure1.UserData.mask3D && ~handles.figure1.UserData.stack
%                         % I guess one can change the if condition to projection/noprojection
%                         slice = handles.figure1.UserData.ax.slider_handle.Value;
%                         handles.figure1.UserData.mask_temp(:,:,cVal+1,slice) = (1-h.createMask()).*handles.figure1.UserData.mask_temp(:,:,cVal+1,slice);
%                     else
%                         handles.figure1.UserData.mask_temp(:,:,cVal+1,:) = (1-h.createMask()).*handles.figure1.UserData.mask_temp(:,:,cVal+1,:);
%                     end
%                     
%                     % update history
%                     handles.figure1.UserData.layerInfo{cVal}.position = h.getPosition;
%                     h.delete;
                    
                case 'mask'
                    fprintf('Binary masks cannot be modified.\n');
                otherwise
                    error('Unknown layer type.')
            end
        catch
            handles.figure1.UserData.mask_temp = backup;
        end
        
        update_mask_GUI(handles)
        update_image(handles)
        
    end




% --- Executes on button press in quit.
% toggle button stack
function toggle_button_stack_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
val = get(hObject, 'Value');
if val
    set(hObject, 'BackgroundColor', [0.956 0.3137 0.2588])
    handles.figure1.UserData.stack = true;
else
    set(hObject, 'BackgroundColor', [1 1 1])
    handles.figure1.UserData.stack = false;
end

function toolCallback(src,event)
if strcmpi(src.State, 'off')
    src.State = 'on';
else
    % disable other tools
    c = src.Parent();
    for ii=1:length(c.Children)
        if ~strcmpi(c.Children(ii).TooltipString, src.TooltipString)
            c.Children(ii).State = 'off';
        end
    end
end

% --- Creates and returns a handle to the GUI figure. 
function h1 = create_mask_GUI_export_LayoutFcn(policy)
% policy - create a new figure or use a singleton. 'new' or 'reuse'.

persistent hsingleton;
if strcmpi(policy, 'reuse') & ishandle(hsingleton)
    h1 = hsingleton;
    return;
end
% load create_mask_GUI_export.mat


appdata = [];
% appdata.GUIDEOptions = mat{1};
appdata.GUIDEOptions.syscolorfig = true;

appdata.lastValidTag = 'figure1';
appdata.GUIDELayoutEditor = [];
appdata.initTags = struct(...
    'handle', [], ...
    'tag', 'figure1');

h1 = figure(...
'PaperUnits',get(0,'defaultfigurePaperUnits'),...
'Units','pixels',...
'Position',[986 614 971 503],...
'Visible',get(0,'defaultfigureVisible'),...
'Color',get(0,'defaultfigureColor'),...
'CloseRequestFcn',get(0,'defaultfigureCloseRequestFcn'),...
'CurrentAxesMode','manual',...
'CurrentObjectMode','manual',...
'CurrentPointMode','manual',...
'SelectionTypeMode','manual',...
'ResizeFcn',blanks(0),...
'IntegerHandle','off',...
'NextPlot',get(0,'defaultfigureNextPlot'),...
'Alphamap',get(0,'defaultfigureAlphamap'),...
'WindowButtonDownFcn',blanks(0),...
'WindowButtonUpFcn',blanks(0),...
'WindowButtonMotionFcn',blanks(0),...
'WindowScrollWheelFcn',blanks(0),...
'WindowKeyPressFcn',blanks(0),...
'WindowKeyReleaseFcn',blanks(0),...
'MenuBar','none',...
'ToolBar','figure',...
'Pointer',get(0,'defaultfigurePointer'),...
'PointerShapeHotSpot',get(0,'defaultfigurePointerShapeHotSpot'),...
'Name','Mask selection',...
'NumberTitle','off',...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','figure1',...
'UserData',[],...
'WindowStyle',get(0,'defaultfigureWindowStyle'),...
'DockControls',get(0,'defaultfigureDockControls'),...
'Resize','off',...
'PaperPosition',get(0,'defaultfigurePaperPosition'),...
'PaperSize',get(0,'defaultfigurePaperSize'),...
'PaperType',get(0,'defaultfigurePaperType'),...
'InvertHardcopy',get(0,'defaultfigureInvertHardcopy'),...
'PaperOrientation',get(0,'defaultfigurePaperOrientation'),...
'ScreenPixelsPerInchMode','manual',...
'KeyPressFcn',blanks(0),...
'KeyReleaseFcn',blanks(0),...
'HandleVisibility','callback');

t = uitoolbar(h1);
cpath = fileparts(mfilename('fullpath'));
[img,map] = imread(fullfile(cpath, 'GUI_draw_circle.gif'));
icon = ind2rgb(uint8(img),map);
p_circ = uitoggletool(t,'TooltipString','Draw circle','ClickedCallback',@toolCallback);
p_circ.CData = icon;
p_circ.State = 'off';

[img,map] = imread(fullfile(cpath, 'GUI_draw_rect.gif'));
icon = ind2rgb(uint8(img),map);
p_rect = uitoggletool(t,'TooltipString','Draw rectangle','ClickedCallback',@toolCallback);
p_rect.CData = icon;
p_rect.State = 'on';

[img,map] = imread(fullfile(cpath, 'GUI_draw_poly.gif'));
icon = ind2rgb(uint8(img),map);
p_poly = uitoggletool(t,'TooltipString','Draw polygon','ClickedCallback',@toolCallback);
p_poly.CData = icon;
p_poly.State = 'off';

appdata = [];
appdata.lastValidTag = 'axes1';

h2 = axes(...
'Parent',h1,...
'FontUnits','normalized',...
'Units',get(0,'defaultaxesUnits'),...
'CameraPosition',[0.5 0.5 9.16025403784439],...
'CameraPositionMode','manual',...
'CameraTarget',[0.5 0.5 0.5],...
'CameraUpVector',get(0,'defaultaxesCameraUpVector'),...
'CameraViewAngle',get(0,'defaultaxesCameraViewAngle'),...
'Projection',get(0,'defaultaxesProjection'),...
'LabelFontSizeMultiplier',get(0,'defaultaxesLabelFontSizeMultiplier'),...
'AmbientLightColor',get(0,'defaultaxesAmbientLightColor'),...
'WarpToFill','off',...
'WarpToFillMode',get(0,'defaultaxesWarpToFillMode'),...
'DataAspectRatio',get(0,'defaultaxesDataAspectRatio'),...
'PlotBoxAspectRatio',get(0,'defaultaxesPlotBoxAspectRatio'),...
'FontName',get(0,'defaultaxesFontName'),...
'FontAngle',get(0,'defaultaxesFontAngle'),...
'FontWeight',get(0,'defaultaxesFontWeight'),...
'FontSmoothing',get(0,'defaultaxesFontSmoothing'),...
'TickLabelInterpreter',get(0,'defaultaxesTickLabelInterpreter'),...
'XLim',get(0,'defaultaxesXLim'),...
'YLim',get(0,'defaultaxesYLim'),...
'ZLim',get(0,'defaultaxesZLim'),...
'CLim',get(0,'defaultaxesCLim'),...
'ALim',get(0,'defaultaxesALim'),...
'Layer',get(0,'defaultaxesLayer'),...
'TickLength',get(0,'defaultaxesTickLength'),...
'GridLineStyle',get(0,'defaultaxesGridLineStyle'),...
'MinorGridLineStyle',get(0,'defaultaxesMinorGridLineStyle'),...
'XAxisLocation',get(0,'defaultaxesXAxisLocation'),...
'XTick',[0 0.2 0.4 0.6 0.8 1],...
'XTickLabelRotation',get(0,'defaultaxesXTickLabelRotation'),...
'XScale',get(0,'defaultaxesXScale'),...
'XTickLabel',{  '0  '; '0.2'; '0.4'; '0.6'; '0.8'; '1  ' },...
'XMinorTick',get(0,'defaultaxesXMinorTick'),...
'YAxisLocation',get(0,'defaultaxesYAxisLocation'),...
'YTick',[0 0.2 0.4 0.6 0.8 1],...
'YTickLabelRotation',get(0,'defaultaxesYTickLabelRotation'),...
'YScale',get(0,'defaultaxesYScale'),...
'YTickLabel',{  '0  '; '0.2'; '0.4'; '0.6'; '0.8'; '1  ' },...
'YMinorTick',get(0,'defaultaxesYMinorTick'),...
'ZTick',[0 0.5 1],...
'ZTickLabelRotation',get(0,'defaultaxesZTickLabelRotation'),...
'ZScale',get(0,'defaultaxesZScale'),...
'ZTickLabel',blanks(0),...
'ZMinorTick',get(0,'defaultaxesZMinorTick'),...
'BoxStyle',get(0,'defaultaxesBoxStyle'),...
'LineWidth',get(0,'defaultaxesLineWidth'),...
'Color',get(0,'defaultaxesColor'),...
'ClippingStyle',get(0,'defaultaxesClippingStyle'),...
'CameraMode',get(0,'defaultaxesCameraMode'),...
'DataSpaceMode',get(0,'defaultaxesDataSpaceMode'),...
'ColorSpaceMode',get(0,'defaultaxesColorSpaceMode'),...
'DecorationContainerMode',get(0,'defaultaxesDecorationContainerMode'),...
'ChildContainerMode',get(0,'defaultaxesChildContainerMode'),...
'XRulerMode',get(0,'defaultaxesXRulerMode'),...
'XBaselineMode',get(0,'defaultaxesXBaselineMode'),...
'YRulerMode',get(0,'defaultaxesYRulerMode'),...
'YBaselineMode',get(0,'defaultaxesYBaselineMode'),...
'ZRulerMode',get(0,'defaultaxesZRulerMode'),...
'ZBaselineMode',get(0,'defaultaxesZBaselineMode'),...
'AmbientLightSourceMode',get(0,'defaultaxesAmbientLightSourceMode'),...
'XGrid',get(0,'defaultaxesXGrid'),...
'XMinorGrid',get(0,'defaultaxesXMinorGrid'),...
'YGrid',get(0,'defaultaxesYGrid'),...
'YMinorGrid',get(0,'defaultaxesYMinorGrid'),...
'ZGrid',get(0,'defaultaxesZGrid'),...
'ZMinorGrid',get(0,'defaultaxesZMinorGrid'),...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','axes1',...
'UserData',[],...
'HitTest',get(0,'defaultaxesHitTest'),...
'PickableParts',get(0,'defaultaxesPickableParts'),...
'Position',[0.11083 0.125248 0.487795 0.7952286],...
'ActivePositionProperty','position',...
'LooseInset',[0.13 0.11 0.095 0.075],...
'ColorOrderIndex',get(0,'defaultaxesColorOrderIndex'),...
'LineStyleOrder',get(0,'defaultaxesLineStyleOrder'),...
'LineStyleOrderIndex',get(0,'defaultaxesLineStyleOrderIndex'),...
'FontSize',0.090702947845805,...
'TitleFontWeight',get(0,'defaultaxesTitleFontWeight'),...
'TitleFontSizeMultiplier',get(0,'defaultaxesTitleFontSizeMultiplier'),...
'SortMethod','childorder',...
'TickDir',get(0,'defaultaxesTickDir'),...
'MinorGridColor',get(0,'defaultaxesMinorGridColor'),...
'Clipping',get(0,'defaultaxesClipping'),...
'NextPlot',get(0,'defaultaxesNextPlot'),...
'Box',get(0,'defaultaxesBox'),...
'ChildrenMode','manual',...
'Visible',get(0,'defaultaxesVisible'),...
'HandleVisibility',get(0,'defaultaxesHandleVisibility'));

h3 = get(h2,'title');

set(h3,...
'Parent',h2,...
'Units','data',...
'FontUnits','normalized',...
'DecorationContainer',[],...
'DecorationContainerMode','auto',...
'Color',[0 0 0],...
'ColorMode','auto',...
'Position',[0.500000730279374 1.00006515710682 0.5],...
'PositionMode','auto',...
'String',blanks(0),...
'Interpreter','tex',...
'Rotation',0,...
'RotationMode','auto',...
'FontName','Helvetica',...
'FontSize',0.0951293759512938,...
'FontAngle','normal',...
'FontWeight','normal',...
'HorizontalAlignment','center',...
'HorizontalAlignmentMode','auto',...
'VerticalAlignment','bottom',...
'VerticalAlignmentMode','auto',...
'EdgeColor','none',...
'LineStyle','-',...
'LineWidth',0.5,...
'BackgroundColor','none',...
'Margin',2,...
'Clipping','off',...
'Layer','middle',...
'LayerMode','auto',...
'FontSmoothing','on',...
'FontSmoothingMode','auto',...
'IncludeRenderer','on',...
'IsContainer','off',...
'IsContainerMode','auto',...
'HelpTopicKey',blanks(0),...
'ButtonDownFcn',blanks(0),...
'BusyAction','queue',...
'Interruptible','on',...
'CreateFcn', {@local_CreateFcn, blanks(0), ''} ,...
'DeleteFcn',blanks(0),...
'Tag',blanks(0),...
'UserData',[],...
'HitTest','on',...
'PickableParts','visible',...
'PickablePartsMode','auto',...
'DimensionNames',{  'X' 'Y' 'Z' },...
'DimensionNamesMode','auto',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...
'Description','Axes Title',...
'DescriptionMode','auto',...
'Visible','on',...
'Serializable','on',...
'HandleVisibility','off',...
'TransformForPrintFcnImplicitInvoke','on',...
'TransformForPrintFcnImplicitInvokeMode','auto');

h4 = get(h2,'xlabel');

set(h4,...
'Parent',h2,...
'Units','data',...
'FontUnits','normalized',...
'DecorationContainer',[],...
'DecorationContainerMode','auto',...
'Color',[0.15 0.15 0.15],...
'ColorMode','auto',...
'Position',[0.500000476837158 -0.136405433827787 0],...
'PositionMode','auto',...
'String',blanks(0),...
'Interpreter','tex',...
'Rotation',0,...
'RotationMode','auto',...
'FontName','Helvetica',...
'FontSize',0.0951293759512938,...
'FontAngle','normal',...
'FontWeight','normal',...
'HorizontalAlignment','center',...
'HorizontalAlignmentMode','auto',...
'VerticalAlignment','top',...
'VerticalAlignmentMode','auto',...
'EdgeColor','none',...
'LineStyle','-',...
'LineWidth',0.5,...
'BackgroundColor','none',...
'Margin',2,...
'Clipping','off',...
'Layer','back',...
'LayerMode','auto',...
'FontSmoothing','on',...
'FontSmoothingMode','auto',...
'IncludeRenderer','on',...
'IsContainer','off',...
'IsContainerMode','auto',...
'HelpTopicKey',blanks(0),...
'ButtonDownFcn',blanks(0),...
'BusyAction','queue',...
'Interruptible','on',...
'CreateFcn', {@local_CreateFcn, blanks(0), ''} ,...
'DeleteFcn',blanks(0),...
'Tag',blanks(0),...
'UserData',[],...
'HitTest','on',...
'PickableParts','visible',...
'PickablePartsMode','auto',...
'DimensionNames',{  'X' 'Y' 'Z' },...
'DimensionNamesMode','auto',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...
'Description','NumericRuler Label',...
'DescriptionMode','auto',...
'Visible','on',...
'Serializable','on',...
'HandleVisibility','off',...
'TransformForPrintFcnImplicitInvoke','on',...
'TransformForPrintFcnImplicitInvokeMode','auto');

h5 = get(h2,'ylabel');

set(h5,...
'Parent',h2,...
'Units','data',...
'FontUnits','normalized',...
'DecorationContainer',[],...
'DecorationContainerMode','auto',...
'Color',[0.15 0.15 0.15],...
'ColorMode','auto',...
'Position',[-0.182371949750624 0.500000476837158 0],...
'PositionMode','auto',...
'String',blanks(0),...
'Interpreter','tex',...
'Rotation',90,...
'RotationMode','auto',...
'FontName','Helvetica',...
'FontSize',0.0951293759512938,...
'FontAngle','normal',...
'FontWeight','normal',...
'HorizontalAlignment','center',...
'HorizontalAlignmentMode','auto',...
'VerticalAlignment','bottom',...
'VerticalAlignmentMode','auto',...
'EdgeColor','none',...
'LineStyle','-',...
'LineWidth',0.5,...
'BackgroundColor','none',...
'Margin',2,...
'Clipping','off',...
'Layer','back',...
'LayerMode','auto',...
'FontSmoothing','on',...
'FontSmoothingMode','auto',...
'IncludeRenderer','on',...
'IsContainer','off',...
'IsContainerMode','auto',...
'HelpTopicKey',blanks(0),...
'ButtonDownFcn',blanks(0),...
'BusyAction','queue',...
'Interruptible','on',...
'CreateFcn', {@local_CreateFcn, blanks(0), ''} ,...
'DeleteFcn',blanks(0),...
'Tag',blanks(0),...
'UserData',[],...
'HitTest','on',...
'PickableParts','visible',...
'PickablePartsMode','auto',...
'DimensionNames',{  'X' 'Y' 'Z' },...
'DimensionNamesMode','auto',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...
'Description','NumericRuler Label',...
'DescriptionMode','auto',...
'Visible','on',...
'Serializable','on',...
'HandleVisibility','off',...
'TransformForPrintFcnImplicitInvoke','on',...
'TransformForPrintFcnImplicitInvokeMode','auto');

h6 = get(h2,'zlabel');

set(h6,...
'Parent',h2,...
'Units','data',...
'FontUnits','normalized',...
'DecorationContainer',[],...
'DecorationContainerMode','auto',...
'Color',[0.15 0.15 0.15],...
'ColorMode','auto',...
'Position',[0 0 0],...
'PositionMode','auto',...
'Interpreter','tex',...
'InterpreterMode','auto',...
'Rotation',0,...
'RotationMode','auto',...
'FontName','Helvetica',...
'FontNameMode','auto',...
'FontSize',0.103930461073318,...
'FontSizeMode','auto',...
'FontAngle','normal',...
'FontAngleMode','auto',...
'FontWeight','normal',...
'FontWeightMode','auto',...
'HorizontalAlignment','left',...
'HorizontalAlignmentMode','auto',...
'VerticalAlignment','middle',...
'VerticalAlignmentMode','auto',...
'EdgeColor','none',...
'EdgeColorMode','auto',...
'LineStyle','-',...
'LineStyleMode','auto',...
'LineWidth',0.5,...
'LineWidthMode','auto',...
'BackgroundColor','none',...
'BackgroundColorMode','auto',...
'Margin',3,...
'MarginMode','auto',...
'Clipping','off',...
'ClippingMode','auto',...
'Layer','middle',...
'LayerMode','auto',...
'FontSmoothing','on',...
'FontSmoothingMode','auto',...
'IncludeRenderer','on',...
'IsContainer','off',...
'IsContainerMode','auto',...
'HG1EraseMode','auto',...
'BusyAction','queue',...
'Interruptible','on',...
'HitTest','on',...
'HitTestMode','auto',...
'PickableParts','visible',...
'PickablePartsMode','auto',...
'DimensionNames',{  'X' 'Y' 'Z' },...
'DimensionNamesMode','auto',...
'XLimInclude','on',...
'XLimIncludeMode','auto',...
'YLimInclude','on',...
'YLimIncludeMode','auto',...
'ZLimInclude','on',...
'ZLimIncludeMode','auto',...
'CLimInclude','on',...
'CLimIncludeMode','auto',...
'ALimInclude','on',...
'ALimIncludeMode','auto',...
'Description','NumericRuler Label',...
'DescriptionMode','auto',...
'Visible','off',...
'VisibleMode','auto',...
'Serializable','on',...
'SerializableMode','auto',...
'HandleVisibility','off',...
'HandleVisibilityMode','auto',...
'TransformForPrintFcnImplicitInvoke','on',...
'TransformForPrintFcnImplicitInvokeMode','auto');

appdata = [];
appdata.lastValidTag = 'pushbutton1';

h7 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'ListboxTop',0,...
'String','Add more pixels',...
'Position',[613 413 146 48],...
'BackgroundColor',[0.831 0.816 0.784],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('pushbutton1_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','pushbutton1',...
'UserData',[],...
'KeyPressFcn',blanks(0),...
'FontSize',8,...
'FontSizeMode',get(0,'defaultuicontrolFontSizeMode'));

appdata = [];
appdata.lastValidTag = 'pushbutton2';

h8 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'ListboxTop',0,...
'String','Undo',...
'Position',[613 344 146 48],...
'BackgroundColor',[0.831 0.816 0.784],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('pushbutton2_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','pushbutton2',...
'UserData',[],...
'KeyPressFcn',blanks(0),...
'FontSize',8,...
'FontSizeMode',get(0,'defaultuicontrolFontSizeMode'));

appdata = [];
appdata.lastValidTag = 'pushbutton5';

h8 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'ListboxTop',0,...
'String','Reset',...
'Position',[613 275 146 48],...
'BackgroundColor',[0.831 0.816 0.784],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('revert_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','pushbutton2',...
'UserData',[],...
'KeyPressFcn',blanks(0),...
'FontSize',8,...
'FontSizeMode',get(0,'defaultuicontrolFontSizeMode'));

appdata = [];
appdata.lastValidTag = 'pushbutton3';

h9 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'ListboxTop',0,...
'String','Load mask',...
'Position',[613 206 146 48],...
'BackgroundColor',[0.831 0.816 0.784],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('pushbutton3_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','pushbutton3',...
'UserData',[],...
'KeyPressFcn',blanks(0),...
'FontSize',8,...
'FontSizeMode',get(0,'defaultuicontrolFontSizeMode'));

appdata = [];
appdata.lastValidTag = 'pushbutton4';

h10 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'ListboxTop',0,...
'String','Save mask',...
'Position',[613 137 146 48],...
'BackgroundColor',[0.831 0.816 0.784],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('pushbutton4_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','pushbutton4',...
'UserData',[],...
'KeyPressFcn',blanks(0),...
'FontSize',8,...
'FontSizeMode',get(0,'defaultuicontrolFontSizeMode'));

appdata = [];
appdata.lastValidTag = 'quit';

h11 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'ListboxTop',0,...
'String','Quit',...
'Position',[613 68 146 48],...
'BackgroundColor',[0.831 0.816 0.784],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('quit_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'ButtonDownFcn',blanks(0),...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ,...
'DeleteFcn',blanks(0),...
'Tag','quit',...
'UserData',[],...
'KeyPressFcn',blanks(0),...
'FontSize',8,...
'FontSizeMode',get(0,'defaultuicontrolFontSizeMode'));

appdata = [];
appdata.lastValidTag = 'quit';

h12 = uicontrol(...
'Parent',h1,...
'FontUnits',get(0,'defaultuicontrolFontUnits'),...
'Units','pixels',...
'String',{  'Apply to stack' },...
'Style','togglebutton',...
'Position',[613 472 146 22],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('toggle_button_stack_Callback',hObject,eventdata,guidata(hObject)),...
'Children',[],...
'Tag','togglebutton1',...
'Visible', 'off',...
'Value', 1,...
'BackgroundColor', [0.956 0.3137 0.2588],...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

h13 = uicontrol(...
'Parent',h1,...
'Style', 'listbox', ...
'Position', [778 68 146 394],...
'Callback',@(hObject,eventdata)create_mask_GUI_export('listbox_callback',hObject,eventdata,guidata(hObject)));

h1.UserData.apply_to_stack_toggle = h12;
h1.UserData.layer_history = h13;


appdata = [];
appdata.lastValidTag = 'quit';


hsingleton = h1;


% --- Set application data first then calling the CreateFcn. 
function local_CreateFcn(hObject, eventdata, createfcn, appdata)

if ~isempty(appdata)
   names = fieldnames(appdata);
   for i=1:length(names)
       name = char(names(i));
       setappdata(hObject, name, getfield(appdata,name));
   end
end

if ~isempty(createfcn)
   if isa(createfcn,'function_handle')
       createfcn(hObject, eventdata);
   else
       eval(createfcn);
   end
end


% --- Handles default GUIDE GUI creation and callback dispatch
function varargout = gui_mainfcn(gui_State, varargin)

gui_StateFields =  {'gui_Name'
    'gui_Singleton'
    'gui_OpeningFcn'
    'gui_OutputFcn'
    'gui_LayoutFcn'
    'gui_Callback'};
gui_Mfile = '';
for i=1:length(gui_StateFields)
    if ~isfield(gui_State, gui_StateFields{i})
        error(message('MATLAB:guide:StateFieldNotFound', gui_StateFields{ i }, gui_Mfile));
    elseif isequal(gui_StateFields{i}, 'gui_Name')
        gui_Mfile = [gui_State.(gui_StateFields{i}), '.m'];
    end
end

numargin = length(varargin);

if numargin == 0
    % CREATE_MASK_GUI_EXPORT
    % create the GUI only if we are not in the process of loading it
    % already
    gui_Create = true;
elseif local_isInvokeActiveXCallback(gui_State, varargin{:})
    % CREATE_MASK_GUI_EXPORT(ACTIVEX,...)
    vin{1} = gui_State.gui_Name;
    vin{2} = [get(varargin{1}.Peer, 'Tag'), '_', varargin{end}];
    vin{3} = varargin{1};
    vin{4} = varargin{end-1};
    vin{5} = guidata(varargin{1}.Peer);
    feval(vin{:});
    return;
elseif local_isInvokeHGCallback(gui_State, [])
    % CREATE_MASK_GUI_EXPORT('CALLBACK',hObject,eventData,handles,...)
    gui_Create = false;
else
    % CREATE_MASK_GUI_EXPORT(...)
    % create the GUI and hand varargin to the openingfcn
    gui_Create = true;
end

if ~gui_Create
    % In design time, we need to mark all components possibly created in
    % the coming callback evaluation as non-serializable. This way, they
    % will not be brought into GUIDE and not be saved in the figure file
    % when running/saving the GUI from GUIDE.
    designEval = false;
    if (numargin>1 && ishghandle(varargin{2}))
        fig = varargin{2};
        while ~isempty(fig) && ~ishghandle(fig,'figure')
            fig = get(fig,'parent');
        end
        
        designEval = isappdata(0,'CreatingGUIDEFigure') || (isscalar(fig)&&isprop(fig,'GUIDEFigure'));
    end
        
    if designEval
        beforeChildren = findall(fig);
    end
    
    % evaluate the callback now
    varargin{1} = gui_State.gui_Callback;
    if nargout
        [varargout{1:nargout}] = feval(varargin{:});
    else       
        feval(varargin{:});
    end
    
    % Set serializable of objects created in the above callback to off in
    % design time. Need to check whether figure handle is still valid in
    % case the figure is deleted during the callback dispatching.
    if designEval && ishghandle(fig)
        set(setdiff(findall(fig),beforeChildren), 'Serializable','off');
    end
else
    if gui_State.gui_Singleton
        gui_SingletonOpt = 'reuse';
    else
        gui_SingletonOpt = 'new';
    end

    % Check user passing 'visible' P/V pair first so that its value can be
    % used by oepnfig to prevent flickering
    gui_Visible = 'auto';
    gui_VisibleInput = '';
    for index=1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break;
        end

        % Recognize 'visible' P/V pair
        len1 = min(length('visible'),length(varargin{index}));
        len2 = min(length('off'),length(varargin{index+1}));
        if ischar(varargin{index+1}) && strncmpi(varargin{index},'visible',len1) && len2 > 1
            if strncmpi(varargin{index+1},'off',len2)
                gui_Visible = 'invisible';
                gui_VisibleInput = 'off';
            elseif strncmpi(varargin{index+1},'on',len2)
                gui_Visible = 'visible';
                gui_VisibleInput = 'on';
            end
        end
    end
    
    % Open fig file with stored settings.  Note: This executes all component
    % specific CreateFunctions with an empty HANDLES structure.

    
    % Do feval on layout code in m-file if it exists
    gui_Exported = ~isempty(gui_State.gui_LayoutFcn);
    % this application data is used to indicate the running mode of a GUIDE
    % GUI to distinguish it from the design mode of the GUI in GUIDE. it is
    % only used by actxproxy at this time.   
    setappdata(0,genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]),1);
    if gui_Exported
        gui_hFigure = feval(gui_State.gui_LayoutFcn, gui_SingletonOpt);

        % make figure invisible here so that the visibility of figure is
        % consistent in OpeningFcn in the exported GUI case
        if isempty(gui_VisibleInput)
            gui_VisibleInput = get(gui_hFigure,'Visible');
        end
        set(gui_hFigure,'Visible','off')

        % openfig (called by local_openfig below) does this for guis without
        % the LayoutFcn. Be sure to do it here so guis show up on screen.
        movegui(gui_hFigure,'onscreen');
    else
        gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt, gui_Visible);
        % If the figure has InGUIInitialization it was not completely created
        % on the last pass.  Delete this handle and try again.
        if isappdata(gui_hFigure, 'InGUIInitialization')
            delete(gui_hFigure);
            gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt, gui_Visible);
        end
    end
    if isappdata(0, genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]))
        rmappdata(0,genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]));
    end

    % Set flag to indicate starting GUI initialization
    setappdata(gui_hFigure,'InGUIInitialization',1);

    % Fetch GUIDE Application options
    gui_Options = getappdata(gui_hFigure,'GUIDEOptions');
    % Singleton setting in the GUI MATLAB code file takes priority if different
    gui_Options.singleton = gui_State.gui_Singleton;

    if ~isappdata(gui_hFigure,'GUIOnScreen')
        % Adjust background color
        if gui_Options.syscolorfig
            set(gui_hFigure,'Color', get(0,'DefaultUicontrolBackgroundColor'));
        end

        % Generate HANDLES structure and store with GUIDATA. If there is
        % user set GUI data already, keep that also.
        data = guidata(gui_hFigure);
        handles = guihandles(gui_hFigure);
        if ~isempty(handles)
            if isempty(data)
                data = handles;
            else
                names = fieldnames(handles);
                for k=1:length(names)
                    data.(char(names(k)))=handles.(char(names(k)));
                end
            end
        end
        guidata(gui_hFigure, data);
    end

    % Apply input P/V pairs other than 'visible'
    for index=1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break;
        end

        len1 = min(length('visible'),length(varargin{index}));
        if ~strncmpi(varargin{index},'visible',len1)
            try set(gui_hFigure, varargin{index}, varargin{index+1}), catch break, end
        end
    end

    % If handle visibility is set to 'callback', turn it on until finished
    % with OpeningFcn
    gui_HandleVisibility = get(gui_hFigure,'HandleVisibility');
    if strcmp(gui_HandleVisibility, 'callback')
        set(gui_hFigure,'HandleVisibility', 'on');
    end

    feval(gui_State.gui_OpeningFcn, gui_hFigure, [], guidata(gui_hFigure), varargin{:});

    if isscalar(gui_hFigure) && ishghandle(gui_hFigure)
        % Handle the default callbacks of predefined toolbar tools in this
        % GUI, if any
        guidemfile('restoreToolbarToolPredefinedCallback',gui_hFigure); 
        
        % Update handle visibility
        set(gui_hFigure,'HandleVisibility', gui_HandleVisibility);

        % Call openfig again to pick up the saved visibility or apply the
        % one passed in from the P/V pairs
        if ~gui_Exported
            gui_hFigure = local_openfig(gui_State.gui_Name, 'reuse',gui_Visible);
        elseif ~isempty(gui_VisibleInput)
            set(gui_hFigure,'Visible',gui_VisibleInput);
        end
        if strcmpi(get(gui_hFigure, 'Visible'), 'on')
            figure(gui_hFigure);
            
            if gui_Options.singleton
                setappdata(gui_hFigure,'GUIOnScreen', 1);
            end
        end

        % Done with GUI initialization
        if isappdata(gui_hFigure,'InGUIInitialization')
            rmappdata(gui_hFigure,'InGUIInitialization');
        end

        % If handle visibility is set to 'callback', turn it on until
        % finished with OutputFcn
        gui_HandleVisibility = get(gui_hFigure,'HandleVisibility');
        if strcmp(gui_HandleVisibility, 'callback')
            set(gui_hFigure,'HandleVisibility', 'on');
        end
        gui_Handles = guidata(gui_hFigure);
    else
        gui_Handles = [];
    end

    if nargout
        [varargout{1:nargout}] = feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    else
        feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    end

    if isscalar(gui_hFigure) && ishghandle(gui_hFigure)
        set(gui_hFigure,'HandleVisibility', gui_HandleVisibility);
    end
end

function gui_hFigure = local_openfig(name, singleton, visible)

% openfig with three arguments was new from R13. Try to call that first, if
% failed, try the old openfig.
if nargin('openfig') == 2
    % OPENFIG did not accept 3rd input argument until R13,
    % toggle default figure visible to prevent the figure
    % from showing up too soon.
    gui_OldDefaultVisible = get(0,'defaultFigureVisible');
    set(0,'defaultFigureVisible','off');
    gui_hFigure = matlab.hg.internal.openfigLegacy(name, singleton);
    set(0,'defaultFigureVisible',gui_OldDefaultVisible);
else
    % Call version of openfig that accepts 'auto' option"
    gui_hFigure = matlab.hg.internal.openfigLegacy(name, singleton, visible);  
%     %workaround for CreateFcn not called to create ActiveX
%         peers=findobj(findall(allchild(gui_hFigure)),'type','uicontrol','style','text');    
%         for i=1:length(peers)
%             if isappdata(peers(i),'Control')
%                 actxproxy(peers(i));
%             end            
%         end
end

function result = local_isInvokeActiveXCallback(gui_State, varargin)

try
    result = ispc && iscom(varargin{1}) ...
             && isequal(varargin{1},gcbo);
catch
    result = false;
end

function result = local_isInvokeHGCallback(gui_State, varargin)

try
    fhandle = functions(gui_State.gui_Callback);
    result = ~isempty(findstr(gui_State.gui_Name,fhandle.file)) || ...
             (ischar(varargin{1}) ...
             && isequal(ishghandle(varargin{2}), 1) ...
             && (~isempty(strfind(varargin{1},[get(varargin{2}, 'Tag'), '_'])) || ...
                ~isempty(strfind(varargin{1}, '_CreateFcn'))) );
catch
    result = false;
end


