function h=LoadDataFig(MainFig,varargin)
% Optional arguments can be a string with a filename of a preset file, 
% which initiates direct loading of this preset.

h = figure('Units','pixels',...
			'Position',[150 100 700 450],...
			'Resize','off',...
			'NumberTitle','off',...
			'Menubar','none',...
			'Toolbar','none',...
			'Name','Data loader',...
            'CloseRequestFcn',@Close);

handles.MainFig = MainFig;

% File menu
handles.mnFile = uimenu('Parent',gcf,...
                        'Label','File');
handles.mnLoadData = uimenu('Parent',handles.mnFile,...
                            'Label','Load settings',...
                            'Callback',@mnLoadSetFile_Callback);
handles.mnSaveData = uimenu('Parent',handles.mnFile,...
                            'Label','Save settings',...
                            'Callback',@mnSaveSetFile_Callback);
handles.mnClose = uimenu('Parent',handles.mnFile,...
                            'Label','Close',...
                            'Callback',@Close);


% Define listbox at left for control
handles.lstCategories = uicontrol('Style','list',...
									'Units','pixels',...
									'Position',[25 95 150 315],...
									'BackgroundColor',[1 1 1],...
									'Callback',@lstCategories_Callback);

handles.btnOk = uicontrol('Style','pushbutton',...
							'Units','pixels',...
							'Position',[45 60 110 20],...
							'String','Ok',...
							'HorizontalAlignment','center',...
							'Callback', @SaveClose);

handles.btnCancel = uicontrol('Style','pushbutton',...
								'Units','pixels',...
								'Position',[45 25 110 20],...
								'String','Cancel',...
								'HorizontalAlignment','center',...
								'Callback', @Close);

% ==== Celltypes tab
handles.pnlCellTypes = uibuttongroup('Units','pixels',...
										'Position',[200 25 475 400],...
										'BackgroundColor',get(gcf,'Color'),...
										'Title','Neuron properties',...
										'SelectionChangeFcn',@pnlTab_Callback);

% --- Radio group No differentation
handles.rdoNeuronsNoDiff = uicontrol('Parent',handles.pnlCellTypes,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 340 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','No distinction',...
										'HorizontalAlignment','left');

handles = AddGroup2Tab(handles, handles.rdoNeuronsNoDiff, []);

% --- Radio group Differentiation
handles.rdoNeuronsDiff = uicontrol('Parent',handles.pnlCellTypes,...
									'Style','radiobutton',...
									'Units','pixels',...
									'Position',[20 310 200 20],...
									'BackgroundColor',get(gcf,'Color'),...
									'String','Multiple types',...
									'HorizontalAlignment','left');

% uitable is unsupported for matlabd r2007 and older
if(verlessthan('matlab','7.6'))
    handles.lblError = uicontrol('Parent',handles.pnlCellTypes,...
                                    'Style','text',...
                                    'Units','pixels',...
                                    'Position',[30 180 380 100],...
                                    'BackgroundColor',get(gcf,'Color'),...
                                    'String',{'This version of Matlab does not support a usertable.',...
                                        'Please upgrade to version R2008 or newer.',...
                                        '',...
                                        'Changes can still be made by modifying DefaultCellTypes.mat',...
                                        'and restarting Skuld'});

	handles.grpNeuronsDiff = handles.lblError;
                               
else                                    
    handles.tblCellTypes = uitable('Parent',handles.pnlCellTypes,...
                                    'Units','pixels',...
                                    'Position',[30 155 380 135],...
									'ColumnFormat',{'logical','char','numeric',{'-','E','I'},'char','char'},...
									'ColumnName',{'Show','Name','#','E/I','Symbol','Color'},...
									'ColumnWidth',{40,60,40,40,50,80},...
									'ColumnEditable',logical([1 1 1 1 1 1]),...
									'Data',cell(0,6));

	handles.btnAddCellType = uicontrol('Parent',handles.pnlCellTypes,...
										'Style','pushbutton',...
										'Units','pixels',...
										'Position',[135 125 80 20],...
										'String','Add',...
										'HorizontalAlignment','center',...
										'Callback', @btnAddCellType_Callback);

	handles.btnRemCellType = uicontrol('Parent',handles.pnlCellTypes,...
										'Style','pushbutton',...
										'Units','pixels',...
										'Position',[225 125 80 20],...
										'String','Remove',...
										'HorizontalAlignment','center',...
										'Callback', @btnRemCellType_Callback);

	handles.grpNeuronsDiff = [handles.tblCellTypes, handles.btnAddCellType, handles.btnRemCellType];
end                            

handles = AddGroup2Tab(handles, handles.rdoNeuronsDiff, handles.grpNeuronsDiff);

% === Positions tab
handles.pnlPositions = uibuttongroup('Units','pixels',...
										'Position',[200 25 475 400],...
										'BackgroundColor',get(gcf,'Color'),...
										'Title','Neuron positions',...
										'SelectionChangeFcn',@pnlTab_Callback);

% --- Radio group File
handles.rdoPositionsFile = uicontrol('Parent',handles.pnlPositions,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 340 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','Positions from file',...
										'HorizontalAlignment','left');

[handles, Objects1, handles.FilePathCllPosId] = MakeFileSelector(handles,handles.pnlPositions,'CellPositions.nwk',[30 290]);

handles.grpPositionsFile = Objects1;

handles = AddGroup2Tab(handles, handles.rdoPositionsFile, handles.grpPositionsFile);

% --- Radio group Structured
handles.rdoPositionsStrc = uicontrol('Parent',handles.pnlPositions,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 250 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','Structured positions',...
										'HorizontalAlignment','left');

handles = AddGroup2Tab(handles, handles.rdoPositionsStrc, []);

% --- Radio group Structured
handles.rdoPositionsRand = uicontrol('Parent',handles.pnlPositions,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 220 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','Random positions',...
										'HorizontalAlignment','left');

handles = AddGroup2Tab(handles, handles.rdoPositionsRand, []);



% ==== Network tab
handles.pnlNetwork = uibuttongroup('Units','pixels',...
									'Position',[200 25 475 400],...
									'BackgroundColor',get(gcf,'Color'),...
									'Title','Network properties',...
									'SelectionChangeFcn',@pnlTab_Callback);

% --- Radio group No Network
handles.rdoNetworkNone = uicontrol('Parent',handles.pnlNetwork,...
									'Style','radiobutton',...
									'Units','pixels',...
									'Position',[20 340 200 20],...
									'BackgroundColor',get(gcf,'Color'),...
									'String','No connectivity',...
									'HorizontalAlignment','left');

handles = AddGroup2Tab(handles, handles.rdoNetworkNone, []);

% --- Radio group Network NeuroSim
handles.rdoNetworkNeuroSim = uicontrol('Parent',handles.pnlNetwork,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 310 100 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','Verdandi',...
										'HorizontalAlignment','left');

[handles, Objects1, handles.FilePathConCntId] = MakeFileSelector(handles,handles.pnlNetwork,'ConnectionCount',[30 260]);
[handles, Objects2, handles.FilePathConLstId] = MakeFileSelector(handles,handles.pnlNetwork, 'ConnectionList',[30 210]);

handles.popConLstFormat = uicontrol('Parent',handles.pnlNetwork,...
                                    'Style','popupmenu',...
                                    'Units','pixels',...
                                    'Position',[30 175 180 20],...
                                    'String',{'Native format','Big-endian','Little-endian (x86)', 'ASCII'},...
                                    'HorizontalAlignment','left',...
                                    'Value',1);

handles.grpNetworkNeuroSim = [Objects1, Objects2, handles.popConLstFormat];

handles = AddGroup2Tab(handles, handles.rdoNetworkNeuroSim, handles.grpNetworkNeuroSim);

% --- Radio group Connection Matrix
handles.rdoNetworkMatrix = uicontrol('Parent',handles.pnlNetwork,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 135 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','Connectivity matrix',...
										'HorizontalAlignment','left');

[handles, handles.grpNetworkMatrix, handles.FilePathConMatId] = MakeFileSelector(handles,handles.pnlNetwork, 'Matrix file',[30 85]);

handles = AddGroup2Tab(handles, handles.rdoNetworkMatrix, handles.grpNetworkMatrix);

% === Spike data tab
handles.pnlSpikeData = uibuttongroup('Units','pixels',...
										'Position',[200 25 475 400],...
										'BackgroundColor',get(gcf,'Color'),...
										'Title','Spike data',...
										'SelectionChangeFcn',@pnlTab_Callback);

handles.rdoSpikeDataNone = uicontrol('Parent',handles.pnlSpikeData,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 340 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','No spike data',...
										'HorizontalAlignment','left');

handles = AddGroup2Tab(handles, handles.rdoSpikeDataNone, []);

% --- Radio group Membrane potentials
handles.rdoSpikeDataVm = uicontrol('Parent',handles.pnlSpikeData,...
									'Style','radiobutton',...
									'Units','pixels',...
									'Position',[20 310 200 20],...
									'BackgroundColor',get(gcf,'Color'),...
									'String','Membrane potentials',...
									'HorizontalAlignment','left');

[handles, Objects1, handles.FilePathVmId] = MakeFileSelector(handles,handles.pnlSpikeData, 'Vm.dat',[30 260]);
[handles, Objects2, handles.NumberSampRateVm] = MakeNumberBox(handles,handles.pnlSpikeData,'Sampling rate (Hz)',[30 225]);
[handles, Objects3, handles.NumberDurationVm] = MakeNumberBox(handles,handles.pnlSpikeData,'Duration (s)',[30 200]);
[handles, Objects4, handles.NumberThresVm] = MakeNumberBox(handles,handles.pnlSpikeData,'Spike threshold',[30 175]);

handles.grpSpikeDataVm = [Objects1, Objects2, Objects3, Objects4];

handles = AddGroup2Tab(handles, handles.rdoSpikeDataVm, handles.grpSpikeDataVm);

% --- Radio group Spike times
handles.rdoSpikeDataSpkTms = uicontrol('Parent',handles.pnlSpikeData,...
										'Style','radiobutton',...
										'Units','pixels',...
										'Position',[20 135 200 20],...
										'BackgroundColor',get(gcf,'Color'),...
										'String','Spike times',...
										'HorizontalAlignment','left');

[handles, Objects1, handles.FilePathSpkTmsId] = MakeFileSelector(handles,handles.pnlSpikeData, 'File',[30 85]);
[handles, Objects2, handles.SpkTmsNumberColumnTime] = MakeNumberBox(handles,handles.pnlSpikeData, 'Time column',[30 50]);
[handles, Objects3, handles.SpkTmsNumberColumnNeur] = MakeNumberBox(handles,handles.pnlSpikeData, 'Cell column',[30 25]);
handles.chkSpkTmsOffset = uicontrol('Parent',handles.pnlSpikeData,...
                                    'Style','checkbox',...
                                    'Units','pixels',...
                                    'Position',[250, 27, 200 20],...
                                    'BackgroundColor',get(gcf,'Color'),...
                                    'String','Contains ID 0',...
                                    'HorizontalAlignment','left');

handles.grpSpikeDataSpkTms = [Objects1, Objects2, Objects3, handles.chkSpkTmsOffset];

handles = AddGroup2Tab(handles, handles.rdoSpikeDataSpkTms, handles.grpSpikeDataSpkTms);

% === EEG data tab
handles.pnlEEGData = uibuttongroup('Units','pixels',...
									'Position',[200 25 475 400],...
									'BackgroundColor',get(gcf,'Color'),...
									'Title','EEG/LFP data',...
									'SelectionChangeFcn',@pnlTab_Callback);

handles.rdoEEGDataNone = uicontrol('Parent',handles.pnlEEGData,...
									'Style','radiobutton',...
									'Units','pixels',...
									'Position',[20 340 200 20],...
									'BackgroundColor',get(gcf,'Color'),...
									'String','No EEG data',...
									'HorizontalAlignment','left');

handles = AddGroup2Tab(handles, handles.rdoEEGDataNone, []);

% --- Radio group Membrane potentials
handles.rdoEEGDataIm = uicontrol('Parent',handles.pnlEEGData,...
									'Style','radiobutton',...
									'Units','pixels',...
									'Position',[20 310 200 20],...
									'BackgroundColor',get(gcf,'Color'),...
									'String','Transmembrane currents',...
									'HorizontalAlignment','left');

[handles, Objects1, handles.FilePathImId] = MakeFileSelector(handles,handles.pnlEEGData, 'Im.dat',[30 260]);
[handles, Objects2, handles.NumberSampRateIm] = MakeNumberBox(handles,handles.pnlEEGData,'Sampling rate (Hz)',[30 225]);
[handles, Objects3, handles.NumberDurationIm] = MakeNumberBox(handles,handles.pnlEEGData,'Duration (s)',[30 200]);
[handles, Objects4, handles.NumberNumNeurIm] = MakeNumberBox(handles,handles.pnlEEGData,'Number of neurons',[30 175]);

handles.grpEEGDataIm = [Objects1, Objects2, Objects3, Objects4];

handles = AddGroup2Tab(handles, handles.rdoEEGDataIm, handles.grpEEGDataIm);

% --- Radio group Time series
handles.rdoEEGDataEEG = uicontrol('Parent',handles.pnlEEGData,...
									'Style','radiobutton',...
									'Units','pixels',...
									'Position',[20 135 200 20],...
									'BackgroundColor',get(gcf,'Color'),...
									'String','Time series',...
									'HorizontalAlignment','left');

[handles, Objects1, handles.FilePathEEGId] = MakeFileSelector(handles,handles.pnlEEGData, 'EEG.dat',[30 85]);
[handles, Objects2, handles.NumberSampRateEEG] = MakeNumberBox(handles,handles.pnlEEGData,'Sampling rate (Hz)',[30 50]);
[handles, Objects3, handles.NumberDurationEEG] = MakeNumberBox(handles,handles.pnlEEGData,'Duration (s)',[30 25]);

handles.grpEEGDataEEG = [Objects1, Objects2, Objects3];

handles = AddGroup2Tab(handles, handles.rdoEEGDataEEG, handles.grpEEGDataEEG);


handles.Categories.Names = {'Neurons','Positions','Network','Spike data','EEG/LFP data'};
handles.Categories.Panels = [handles.pnlCellTypes, handles.pnlPositions, handles.pnlNetwork, handles.pnlSpikeData, handles.pnlEEGData];
for iPanel = 1:length(handles.Categories.Panels)
	handles = SelectRadio(handles,iPanel,1);
end

MainHandles = guidata(handles.MainFig);
if(isfield(MainHandles,'Settings'))
    handles = LoadPreset(handles,MainHandles.Settings,0);
end



guidata(h,handles);
set(handles.lstCategories,'String',handles.Categories.Names,'Value',1);
CategorySelected(handles,1);

if(~isempty(varargin))
    LoadPresetFromFile(h,varargin{1});
end


% Navigation and option selection
function lstCategories_Callback(hObject, eventdata, handles)
handles = guidata(gcbf);
CategorySelected(handles, get(handles.lstCategories,'Value'));

function CategorySelected(handles, Id)
% Turn all tabs invisible and make selected tab visible again
set(handles.Categories.Panels,'Visible','off');
set(handles.Categories.Panels(Id),'Visible','on');

function handles = AddGroup2Tab(handles, Radio, Group)
% This function adds a radiobutton and corresponding group to a struct
if(isfield(handles,'Tab'))
	Id = find([handles.Tab(:).Panel]==get(Radio,'Parent'));
	if(~isempty(Id))
		% Add Group to existing tab
		nRadio = length(handles.Tab(Id).Radio);
		handles.Tab(Id).Radio(nRadio+1) = Radio;
		handles.Tab(Id).Group{nRadio+1} = Group;
	else
		% Add new tab
		nTab = length(handles.Tab);
		handles.Tab(nTab+1).Panel = get(Radio,'Parent');
		handles.Tab(nTab+1).Radio(1) = Radio;
		handles.Tab(nTab+1).Group{1} = Group;
	end
else
	% Make Tab struct
	handles.Tab(1).Panel = get(Radio,'Parent');
	handles.Tab(1).Radio(1) = Radio;
	handles.Tab(1).Group{1} = Group;
end

function pnlTab_Callback(source, eventdata)
% Funcion called when a radiobutton is changed. 
handles = guidata(gcbf);
TabId = find([handles.Tab(:).Panel]==source);
RadioId = find([handles.Tab(TabId).Radio(:)]==eventdata.NewValue);
handles = SelectRadio(handles, TabId, RadioId);
guidata(gcbf,handles);

function handles = SelectRadio(handles, TabId, RadioId)
% Set the correct radio button to active
set(handles.Tab(TabId).Panel,'SelectedObject',handles.Tab(TabId).Radio(RadioId));

% Set enable field of all groups on the tab
Groups = [handles.Tab(TabId).Group{:}];
set(Groups,'Enable','off');
set(handles.Tab(TabId).Group{RadioId},'Enable','on');

handles.RadioSelected(TabId) = RadioId;

% File Selectors
function [handles, ObjectHandles, Id] = MakeFileSelector(handles, Parent, Label, Pos)
% This function adds a typical file selector to the figure FigHandle with a given Parent (either figure or panel).
% The fileselector contains a label for the description, a textbox for the filepath and a button to browse files.
% The automated functions ensure proper operation of the browse buttons etc.

% Make the three required elements: label, textbox and button.
% Link objects to generic callback function that identify the object again
temp.lbl = uicontrol('Parent',Parent,...
						'Style','text',...
						'Units','pixels',...
						'Position',[(Pos+[20, 20]), 150, 20],...
						'BackgroundColor',get(gcf,'Color'),...
						'String',Label,...
						'HorizontalAlignment','left');
temp.txt = uicontrol('Parent',Parent,...
						'Style','edit',...
						'Units','pixels',...
						'Position',[(Pos+[0, 0]), 300, 24],...
						'BackgroundColor',[1 1 1],...
						'HorizontalAlignment','left',...
						'Callback',@txtFileSelector_Callback);
temp.btn = uicontrol('Parent',Parent,...
						'Style','pushbutton',...
						'Units','pixels',...
						'Position',[(Pos+[308, 2]), 70, 20],...
						'String','Browse',...
						'HorizontalAlignment','center',...
						'Callback',@btnFileSelector_Callback);
ObjectHandles = [temp.lbl, temp.txt, temp.btn];

temp.Path = '';	% Initial directory is set to current directory
temp.PathValid = 0;
temp.PathChanged = 0;

% Add this FileSelector to the list of others. Check first if the list is already defined
if(isfield(handles,'FileSelector'))
	Id = length(handles.FileSelector)+1;
	handles.FileSelector(Id) = temp;
else
	Id = 1;
	handles.FileSelector = temp;
end

function handles = SetFileSelector(handles,SelectorId,Path)
% Function sets a path to a certain FileSelector
hObject = handles.FileSelector(SelectorId).txt;
set(hObject,'String',Path);
% Check path and set flags accordingly
if (exist(Path)==2)
    handles.FileSelector(SelectorId).Path = Path;
    handles.FileSelector(SelectorId).PathValid = 1;
    set(hObject,'ForeGroundColor',[0 0 0]);
else
    set(hObject,'ForeGroundColor',[1 0 0]);
    handles.FileSelector(SelectorId).PathValid = 0;
end

function txtFileSelector_Callback(hObject, eventdata, handles)
% This function gets called when a textfield of a FileSelector is edited.
% It checks whether the entered file exists or not and flags are set accordingly
handles=guidata(gcbf);

% Find Id of this selector in the handles.FileSelector
temp = [handles.FileSelector(:).txt];
Id = find(temp==hObject);

% Check path and set flags
Path = get(hObject,'String');
handles = SetFileSelector(handles,Id,Path);
handles.FileSelector(Id).PathChanged = 1;
guidata(gcbf,handles);

function btnFileSelector_Callback(hObject, eventdata, handles)
% This function gets called when the browse button of a FileSelector is clicked
% It pops up a file selector window and it processes the data accordingly
handles=guidata(gcbf);

% Find Id of this selector in the handles.FileSelector
temp = [handles.FileSelector(:).btn];
Id = find(temp==hObject);

F = handles.FileSelector(Id).Path;
% Determine the directory in which the browser should start
if(exist(F) == 2)
    % Existing file: point to directory of file
    Dir = fileparts(F);
elseif(exist(F) == 7)
    % F is a folder, use this:
    Dir = F;
else
    % In all other cases, use current directory:
    Dir = pwd;
end
% Open dialog for file selection
[FileName,PathName,FilterIndex] = uigetfile({'*.txt;*.nwk;*.dat;*.mat','Data files (*.txt, *.nwk, *.dat, *.mat)';...
												'*.*','All Files (*.*)'},...
												'Locate file',[Dir filesep]);

% If a file is selected
if(PathName~=0)
    handles.FileSelector(Id).Path = [PathName FileName];
    % The delsected file is valid:
    handles.FileSelector(Id).PathValid = 1;
    handles.FileSelector(Id).PathChanged = 1;
    set(handles.FileSelector(Id).txt,'String',handles.FileSelector(Id).Path,'ForeGroundColor',[0 0 0]);
    guidata(gcbf,handles);
end

% Number boxes
function [handles, ObjectHandles, Id] = MakeNumberBox(handles, Parent, Label, Pos)
% This function adds a typical textbox for numbers to the figure FigHandle with a given Parent (either figure or panel).
% The NumberBox contains a label for the description and a textbox for the input
% The automated functions ensure proper operation of the callback options

% Make the two required elements: label and textbox
% Link objects to generic callback function that identify the object again
temp.lbl = uicontrol('Parent',Parent,...
						'Style','text',...
						'Units','pixels',...
						'Position',[Pos, 150, 20],...
						'BackgroundColor',get(gcf,'Color'),...
						'String',Label,...
						'HorizontalAlignment','left');
temp.txt = uicontrol('Parent',Parent,...
						'Style','edit',...
						'Units','pixels',...
						'Position',[(Pos+[120, 0]), 80, 24],...
						'BackgroundColor',[1 1 1],...
						'HorizontalAlignment','left',...
						'Callback',@txtNumberBox_Callback);

ObjectHandles = [temp.lbl, temp.txt];

temp.Value = [];
temp.ValueChanged = 0;

% Add this NumberBox to the list of others. Check first if the list is already defined
if(isfield(handles,'NumberBox'))
	Id = length(handles.NumberBox)+1;
	handles.NumberBox(Id) = temp;
else
	Id = 1;
	handles.NumberBox = temp;
end

function handles = SetNumberBox(handles, BoxId, Value)
% Sets the value of a NumberBox
set(handles.NumberBox(BoxId).txt,'String',num2str(Value));
handles.NumberBox(BoxId).Value = Value;

function txtNumberBox_Callback(hObject, eventdata, handles)
% This function gets called when a NumberBox is edited.
% It checks whether the entered input is valid or not and flags are set accordingly
handles=guidata(gcf);

% Find Id of this element in the handles.NumberBox
temp = [handles.NumberBox(:).txt];
Id = find(temp==hObject);

% Check input and set flags
Str = get(hObject,'String');
if(~isempty(Str))
	Val = str2double(Str);
	if(~isnan(Val))
		handles.NumberBox(Id).Value = Val;
		handles.NumberBox(Id).ValueChanged=1;
	else
		set(hObject,'String',handles.NumberBox(Id).Value);
	end
else
	handles.NumberBox(Id).Value = [];
	handles.NumberBox(Id).ValueChanged=1;
end

guidata(gcf,handles);

% Cell type table functions
function btnAddCellType_Callback(hObject, eventdata, handles)
% This function adds a line to uitable that contains the celltypes
handles=guidata(gcbo);

CellTypes = get(handles.tblCellTypes,'Data');
CellTypes(end+1,1:6) = {true,'New',0,'-','o','[0 0 0]'};
set(handles.tblCellTypes,'Data',CellTypes);

guidata(gcbo, handles);

function btnRemCellType_Callback(hObject, eventdata, handles)
% This function adds a line to uitable that contains the celltypes
handles=guidata(gcbo);

CellTypes = get(handles.tblCellTypes,'Data');
if(size(CellTypes,1)>0)
	set(handles.tblCellTypes,'Data',CellTypes(1:(end-1),:));
end

guidata(gcbo, handles);


% Set, Save and Close
function mnLoadSetFile_Callback(hObject, eventdata, handles)
[FileName,PathName,FilterIndex] = uigetfile({'*.mat','Preset'},'Locate file');

if(PathName~=0)
    LoadPresetFromFile(gcbf,[PathName FileName]);
end
        
function mnSaveSetFile_Callback(hObject, eventdata, handles)
handles = guidata(gcbo);
[FileName,PathName,FilterIndex] = uiputfile({'*.mat','*.mat Preset'},'Save');

% If a file is selected
if(PathName~=0)
    Preset = SaveSettings(handles);
    save([PathName FileName],'Preset')
end

function LoadPresetFromFile(h,File)
handles = guidata(h);

% If a file is selected
try 
    File = load(File);
catch
    warning('Error loading file');
    return;
end
if(~isfield(File,'Preset'))
    warning('Invalid preset file');
    return;
end
T = isfield(File.Preset,{'RadioSelected','FilePath','NumberBox','CellTypes'});
if(nnz(1-T) == 0)
    try,
        handles = LoadPreset(handles,File.Preset,1);
        guidata(h,handles);
    catch
        warning('Invalid preset file');
    end
else
    warning('Invalid preset file');
end

function handles = LoadPreset(handles, Preset, New)
% This function loads a preset file into the GUI
% The New flag determines whether a different file has been loaded and
% the according Changed flags have to be modified.

% Set all the radio buttons to the selected ones:
for iTab = 1:length(Preset.RadioSelected)
    handles = SelectRadio(handles,iTab,Preset.RadioSelected(iTab));
end

% Set FileSelectors
for iSelect = 1:length(Preset.FilePath)
    handles = SetFileSelector(handles,iSelect,Preset.FilePath{iSelect});
    if(New)
        handles.FileSelector(iSelect).PathChanged = 1;
    end
end

% Set NumberBoxes
for iBox = 1:length(Preset.NumberBox)
    handles = SetNumberBox(handles,iBox,Preset.NumberBox{iBox});
    if(New)
        handles.NumberBox(iBox).ValueChanged = 1;
    end

end

if(isfield(Preset,'ConnectionListEndian')) % Support for v2.1 and older
    set(handles.popConLstFormat,'Value',Preset.ConnectionListEndian);
end
if(isfield(Preset,'ConnectionListFormat'))
    set(handles.popConLstFormat,'Value',Preset.ConnectionListFormat);
end

if(isfield(Preset,'SpikeTimesOffset'))
    set(handles.chkSpkTmsOffset,'Value',Preset.SpikeTimesOffset);
end

% Set CellTypes Array
if(~verlessthan('matlab','7.6'))
    set(handles.tblCellTypes,'Data',Preset.CellTypes);
end

function Settings = SaveSettings(handles)
% This function saves the settings made in the current window
Settings.RadioSelected = handles.RadioSelected;
Settings.FilePath = {handles.FileSelector(:).Path};
Settings.NumberBox = {handles.NumberBox(:).Value};
Settings.ConnectionListFormat = get(handles.popConLstFormat,'Value');
Settings.SpikeTimesOffset = get(handles.chkSpkTmsOffset,'Value');
if(verlessthan('matlab','7.6'))
    Settings.CellTypes = load(DefaultCellTypes.mat);
else
    Settings.CellTypes = get(handles.tblCellTypes,'Data');
end
  

function Close(hObject, eventdata, handles)
handles = guidata(gcbf);
try
    MainHandles = guidata(handles.MainFig);
    MainHandles.DataLoaded = 0;
    guidata(handles.MainFig,MainHandles);
end
delete(gcbf)

function SaveClose(hObject, eventdata, handles)
% This function loads the data according to all the selected options.
handles = guidata(gcbf);
MainHandles = guidata(handles.MainFig);

% Check whether given data is sufficient
disp('Checking input...')
ValidData = 1;

% === Positions tab
switch get(handles.pnlPositions,'SelectedObject')
	case handles.rdoPositionsFile,
		% Check if files are valid
		if(handles.FileSelector(handles.FilePathCllPosId).PathValid==0)
			ValidData = 0;
		end
	case handles.rdoPositionsStrc,

	case handles.rdoPositionsRand,
end

% === Network tab
switch get(handles.pnlNetwork,'SelectedObject')
	case handles.rdoNetworkNone,
	
	case handles.rdoNetworkNeuroSim,
		% Check if files are valid
		if(handles.FileSelector(handles.FilePathConCntId).PathValid==0)
			ValidData = 0;
		end
		if(handles.FileSelector(handles.FilePathConLstId).PathValid==0)
			ValidData = 0;
		end

	case handles.rdoNetworkMatrix,
		% Check if file is valid
		if(handles.FileSelector(handles.FilePathConMatId).PathValid==0)
			ValidData = 0;
		end
end

% === Spike data tab
switch get(handles.pnlSpikeData,'SelectedObject')
	case handles.rdoSpikeDataNone,
	
	case handles.rdoSpikeDataVm,
		% Check if file is valid
		if(handles.FileSelector(handles.FilePathVmId).PathValid==0)
			ValidData = 0;
		end
		% Check if the required Numberboxes are filled out
		if(isempty(handles.NumberBox(handles.NumberSampRateVm).Value))
			ValidData = 0;
		end
		if(isempty(handles.NumberBox(handles.NumberThresVm).Value))
			ValidData = 0;
		end

	case handles.rdoSpikeDataSpkTms,
		% Check if file is valid
		if(handles.FileSelector(handles.FilePathSpkTmsId).PathValid==0)
			ValidData = 0;
        end
        
        if(isempty(handles.NumberBox(handles.SpkTmsNumberColumnTime).Value))
            ValidData = 0;
        end
        if(isempty(handles.NumberBox(handles.SpkTmsNumberColumnNeur).Value))
            ValidData = 0;
        end
        
end

% === EEG/LFP tab
switch get(handles.pnlEEGData,'SelectedObject')
	case handles.rdoEEGDataNone,
	
	case handles.rdoEEGDataIm,
		% Check if file is valid
		if(handles.FileSelector(handles.FilePathImId).PathValid==0)
			ValidData = 0;
		end
		% Check if the required Numberboxes are filled out
		if(isempty(handles.NumberBox(handles.NumberSampRateIm).Value))
			ValidData = 0;
		end

	case handles.rdoEEGDataEEG,
		% Check if file is valid
		if(handles.FileSelector(handles.FilePathEEGId).PathValid==0)
			ValidData = 0;
		end
		% Check if the required Numberboxes are filled out
		if(isempty(handles.NumberBox(handles.NumberSampRateEEG).Value))
			ValidData = 0;
		end
end

if(ValidData==0)
	msgbox('Incomplete form. Provide more data.');
	return;
end

% Start reading data

if(isfield(MainHandles,'Data'))
	Data = MainHandles.Data;
else
	Data = struct([]);
end

MainHandles.ChangedNetwork = 0;
MainHandles.ChangedData = 0;

% First find a way to determine the number of neurons in the given dataset
if(get(handles.pnlCellTypes,'SelectedObject') == handles.rdoNeuronsDiff)
	% CellTypes are given. Determine number of neurons by adding up the number fields
	if(verlessthan('matlab','7.6'))
		CellTypes = load(DefaultCellTypes.mat);
	else
		CellTypes = get(handles.tblCellTypes,'Data');
	end
	nCells = sum([CellTypes{:,3}]);
elseif(get(handles.pnlNetwork,'SelectedObject') == handles.rdoNetworkNeuroSim)
	% A NeuroSim network is given. Determine number of neurons by looking at ConnectionCount.nwk
	ConnectionCount = load(handles.FileSelector(handles.FilePathConCntId).Path);
	nCells = length(ConnectionCount);
elseif(get(handles.pnlPositions,'SelectedObject') == handles.rdoPositionsFile)
	% Neuron positions are given. Determine number of neurons by looking at
	% number of positions
	CellPositions = load(handles.FileSelector(handles.FilePathCllPosId).Path);
	nCells = size(CellPositions,1);
elseif(get(handles.pnlNetwork,'SelectedObject') == handles.rdoNetworkMatrix)
	% A connection matrix is given. Determine number of neurons by looking at the size of matrix
	ConnectionMatrix = load(handles.FileSelector(handles.FilePathConMatIf).Path);
	nCells = size(ConnectionMatrix,1);
elseif(get(handles.pnlSpikeData,'SelectedObject') == handles.rdoSpikeDataVm)
	% Determine nCells by the number of columns of Vm
	Vm = load(handles.FileSelector(handles.FilePathVmId).Path);
	nCells = size(Vm,2);
elseif(get(handles.pnlSpikeData,'SelectedObject') == handles.rdoSpikeDataSpkTms)
	% Determine nCells by the highest neuron ID.
	SpikeTimes = load(handles.FileSelector(handles.FilePathSpkTmsId).Path);
	ColN = handles.NumberBox(handles.SpkTmsNumberColumnNeur).Value;
    nCells = max(SpikeTimes(:,ColN)) + get(handles.chkSpkTmsOffset,'Value');
else
    % No way can be found to determine total number of cells!
    warning('Number of cells could not be determined from given data.');
end


% This one is only interesting if the number of cells is known
if(exist('nCells'))
    if(nCells > 0)
        % Store number of cells.
        Data(1).nCells = nCells;

        % Celltypes tab first.
        disp('Handling cell positions...')
        switch get(handles.pnlCellTypes,'SelectedObject')
            case handles.rdoNeuronsNoDiff,
                % No distinction
                Data.CellTypesRaw = {true, 'Cell', Data.nCells, '-', 'o', '[0 0 1]'};

            case handles.rdoNeuronsDiff,
                % Distinction between celltypes
                if(verlessthan('matlab','7.6'))
                    % Matlab version too old, see if preference file is available, return warning otherwise.
                    if(exist('DefaultCellTypes.mat') == 2)
                        Data.CellTypesRaw = load('DefaultCellTypes.mat')
                    else
                        warning('The file DefaultCellTypes.mat does not exist. \n Cells are treated as if \''No distinction\'' option was chosen');
                        Data.CellTypesRaw = {true, 'Cell', Data.nCells, '-', 'o', '[0 0 1]'};
                    end
                else
                    % Matlab version high enough, read settings from uitable
                    Data.CellTypesRaw = get(handles.tblCellTypes,'Data');
                    if(isempty(Data.CellTypesRaw))
                        warning('No cell types specified. \n Cells are treated as if \''No distinction\'' option was chosen');
                        Data.CellTypesRaw = {true, 'Cell', Data.nCells, '-', 'o', '[0 0 1]'};
                    end
                end
        end


        % Positions tab is next. Only interesting when nCells is known
        switch get(handles.pnlPositions,'SelectedObject')
            case handles.rdoPositionsFile,
                % Read file if necessary
                if(~exist('CellPositions'))
                    CellPositions = load(handles.FileSelector(handles.FilePathCllPosId).Path);
                end
                % Check format
                if(size(CellPositions,1)==nCells && size(CellPositions,2)==3)
                    Data.CellPositions = CellPositions;
                else
                    warning('Incosistent size of cell positions. \n Cells are treated as if \''Structured\'' option was chosen');

                    % Order neurons neatly in layers for every indicated celltype
                    nType = size(Data.CellTypesRaw,1);
                    Data.CellPositions = zeros(0,3);
                    for iType = 1:nType
                        n = Data.CellTypesRaw{iType,3};
                        nRoot = ceil(sqrt(n));
                        x = mod(0:(n-1),nRoot);
                        y = floor((0:(n-1))/nRoot);
                        Pos = zeros(n,3);
                        Pos(:,1) = x/(nRoot-1);
                        Pos(:,2) = y/(nRoot-1);
                        if(nType > 1)
                            Pos(:,3) = (iType-1)/(nType-1);
                        else
                            Pos(:,3) = 0;
                        end
                        Data.CellPositions = [Data.CellPositions; Pos];
                    end
                end

            case handles.rdoPositionsStrc,
                % Order neurons neatly in layers for every indicated celltype
                nType = size(Data.CellTypesRaw,1);
                Data.CellPositions = zeros(0,3);
                for iType = 1:nType
                    n = Data.CellTypesRaw{iType,3};
                    nRoot = ceil(sqrt(n));
                    x = mod(0:(n-1),nRoot);
                    y = floor((0:(n-1))/nRoot);
                    Pos = zeros(n,3);
                    Pos(:,1) = x/(nRoot-1);
                    Pos(:,2) = y/(nRoot-1);
                    if(nType > 1)
                        Pos(:,3) = (iType-1)/(nType-1);
                    else
                        Pos(:,3) = 0;
                    end
                    Data.CellPositions = [Data.CellPositions; Pos];

                end
            case handles.rdoPositionsRand,
                % Pick random numbers. Dimensions do not matter, so the range (0,1) should be ok
                Data.CellPositions = rand(nCells,3);
        end

        % Network tab
        switch get(handles.pnlNetwork,'SelectedObject')
            case handles.rdoNetworkNone,
                % No network is given. Delete all possible
                if(isfield(Data,'Network'))
%                     if(isfield(Data.Network,'ConnectionCount'))
%                         Data.Network = rmfield(Data.Network,'ConnectionCount');
%                     end
%                     if(isfield(Data.Network,'ConnectionList'))
%                         Data.Network = rmfield(Data.Network,'ConnectionList');
%                     end
%                     if(isfield(Data.Network,'ConnectionMatrix'))
%                         Data.Network = rmfield(Data.Network,'ConnectionMatrix');
%                     end
                    Data = rmfield(Data,'Network');
                end
            case handles.rdoNetworkNeuroSim,
                disp('Reading NeuroSim network...')
                Error = 0;
                if(~isfield(Data,'Network'))
                    Data.Network = [];
                end
                % Read files if they have changed.
                if(~isfield(Data.Network,'ConnectionCount') || handles.FileSelector(handles.FilePathConCntId).PathChanged==1)
                    % Read ConnectionCount to a temporary variable and check number of elements before copying
                    if(~exist('ConnectionCount'))
                        ConnectionCount = load(handles.FileSelector(handles.FilePathConCntId).Path);
                    end
                    if(numel(ConnectionCount) == Data.nCells)			
                        Data.Network.ConnectionCount = ConnectionCount(:);
                    else
                        Error = 1;
                    end
                end

                % Try reading ConnectionList.
                if(~isfield(Data.Network,'ConnectionList') || handles.FileSelector(handles.FilePathConLstId).PathChanged==1)
                    switch(get(handles.popConLstFormat,'Value'))
                        case 1
                            Format = 'n';
                        case 2
                            Format = 'b';
                        case 3
                            Format = 'l';
                        case 4
                            Format = 'a';
                    end
                    
                    try
                        [Data.Network.ConnectionMatrix, Data.Network.ConnectionDetails] = ReadConnectionList(...
                                    handles.FileSelector(handles.FilePathConLstId).Path,Data.Network.ConnectionCount, Format);
                    catch
                        Error = 1;
                    end
                end

                if(Error == 1)
%                     % Error during reading one of the files. Clean up
%                     warning('Error while reading network. \n Treated as if \''No network\'' option was chosen');
%                     if(isfield(Data.Network,'ConnectionCount'))
%                         Data.Network = rmfield(Data.Network,'ConnectionCount');
%                     end
%                     if(isfield(Data.Network,'ConnectionList'))
%                         Data.Network = rmfield(Data.Network,'ConnectionList');
%                     end
                    if(isfield(Data,'Network'))
                        Data = rmfield(Data,'Network');
                    end
                end


            case handles.rdoNetworkMatrix,
                disp('Reading connection matrix...')
                if(~isfield(Data,'Network'))
                    Data.Network = [];
                end
                % Read connectionmatrix
                if(~isfield(Data.Network,'ConnectionMatrix') || handles.FileSelector(handles.FilePathConMatId).PathChanged==1)
                    if(~exist('ConnectionMatrix'))
                        ConnectionMatrix = load(handles.FileSelector(handles.FilePathConMatId).Path);
                    end
                    if(size(ConnectionMatrix,1)==Data.nCells && size(ConnectionMatrix,2)==Data.nCells)
                        Data.Network.ConnectionMatrix = ConnectionMatrix;
                    else
                        warning('Size of connection matrix does not match number of cells. \n Network treated as if \''No network\'' option was chosen');

                        % Possibly remove previous network
                        if(isfield(Data.Network,'ConnectionMatrix'))
                            Data.Network = rmfield(Data.Network,'ConnectionMatrix');
                        end
                    end
                end

                % Delete other networks
                if(isfield(Data.Network,'ConnectionCount'))
                    Data.Network = rmfield(Data.Network,'ConnectionCount');
                end
                if(isfield(Data.Network,'ConnectionDetails'))
                    Data.Network = rmfield(Data.Network,'ConnectionDetails');
                end
        end

        % Spike data tab
        switch get(handles.pnlSpikeData,'SelectedObject')
            case handles.rdoSpikeDataNone,
                % No data is given. Delete all possible
                if(isfield(Data,'Vm'))
                    Data = rmfield(Data,'Vm');
                end
                if(isfield(Data,'SpikeTimes'))
                    Data = rmfield(Data,'SpikeTimes');
                end

            case handles.rdoSpikeDataVm,
                disp('Reading membrane potentials...')
                Error = 0;
                if(~isfield(Data,'Vm') || handles.FileSelector(handles.FilePathVmId).PathChanged == 1)
                    Data.Vm.SamplingRate = handles.NumberBox(handles.NumberSampRateVm).Value;
                    Data.Vm.Duration = handles.NumberBox(handles.NumberDurationVm).Value;
                    tmp = handles.NumberBox(handles.NumberThresVm).Value;
                    if(~isempty(tmp))
                        Data.Vm.Threshold = tmp;
                    else
                        Data.Vm.Threshold = 0;
                    end	

                    if(~isempty(Data.Vm.Duration))
                        % Duration is given. Try reading it with the fast data reader
                        try
                            Data.Vm.Data = readASCII(handles.FileSelector(handles.FilePathVmId).Path,...
                                                        Data.Vm.SamplingRate*Data.Vm.Duration,...
                                                        Data.nCells);
                            % Redefine duration to prevent inconsistencies:
                            Data.Vm.Duration = size(Data.Vm.Data,1)/Data.Vm.SamplingRate;

                        catch
                            Error = 1;
                        end
                    else
                        % No duration given. Read file using generic reader and check later
                        if(~exist('Vm'))
                            try
                                Vm = readASCII(handles.FileSelector(handles.FilePathVmId).Path,...
                                                Inf,...
                                                Data.nCells);
                            catch
                                Error = 1;
                            end
                        end
                        if(size(Vm,2) == Data.nCells && Error == 0)
                            Data.Vm.Data = Vm;
                            Data.Vm.Duration = size(Vm,1)/Data.Vm.SamplingRate;
                        else
                            Error = 1;
                        end	
                    end
                end

                % Check if errors are produced. If so; clean up
                if(Error == 1)
                    % File incorrect. Give warning and clean up
                    warning('Invalid file for Vm.dat. Data treated as if ''No spike data'' option was chosen');
                    Data = rmfield(Data,'Vm');				
                end	

                % Clear other 
                if(isfield(Data,'SpikeTimes'))
                    Data = rmfield(Data,'SpikeTimes');
                end

            case handles.rdoSpikeDataSpkTms,
                disp('Reading spikes...')
                
                if(handles.NumberBox(handles.SpkTmsNumberColumnNeur).ValueChanged == 1 || ...
                        handles.NumberBox(handles.SpkTmsNumberColumnTime).Value == 1)
                    ColumnsChanged = 1;
                else
                    ColumnsChanged = 0;
                end
               
                
                if(~isfield(Data,'SpikeTimes') || ...
                        handles.FileSelector(handles.FilePathSpkTmsId).PathChanged == 1 || ...
                        ColumnsChanged == 1)
                    if(~exist('SpikeTimes'))
                        temp = load(handles.FileSelector(handles.FilePathSpkTmsId).Path);
                    else
                        temp = SpikeTimes;
                    end
                

                    % Column numbers of Neurons IDs and Time

                    ColN = handles.NumberBox(handles.SpkTmsNumberColumnNeur).Value;
                    ColT = handles.NumberBox(handles.SpkTmsNumberColumnTime).Value;

                    Data.SpikeTimes = temp(:,[ColT, ColN]);
                    if(get(handles.chkSpkTmsOffset,'Value') == 1)
                        Data.SpikeTimes(:,2) = Data.SpikeTimes(:,2)+1;
                    end
                end    

                % Clear other
                if(isfield(Data,'Vm'))
                    Data = rmfield(Data,'Vm');
                end
        end

    else
        warning('Number of neurons is non-positive');
        % cleanup: delete all data fields:
        Data = struct([]);

    end
end

% EEG Tab
switch get(handles.pnlEEGData,'SelectedObject')
	case handles.rdoEEGDataNone,
		% Clear all data
		if(isfield(Data,'EEG'))
			Data = rmfield(Data,'EEG');
		end

	case handles.rdoEEGDataIm,
		if(~isfield(Data,'EEG') || handles.FileSelector(handles.FilePathImId).PathChanged==1)
			% Read EEG data	
			Data(1).EEG.SamplingRate = handles.NumberBox(handles.NumberSampRateIm).Value;
			Data.EEG.Duration = handles.NumberBox(handles.NumberDurationIm).Value;

			NumNeur = handles.NumberBox(handles.NumberNumNeurIm).Value;

            Error = 0;
			if(~isempty(Data.EEG.Duration) && ~isempty(NumNeur))
				% Duration is given. Try reading it with the fast data reader
				try
					disp('reading EEG...')
					Im = readASCII(handles.FileSelector(handles.FilePathImId).Path,...
									Data.EEG.SamplingRate*Data.EEG.Duration,...
									NumNeur);

				catch
					% File incorrect. Give warning and clean up
					warning('Invalid file for EEG.dat. Data treated as if \''No EEG data\'' option was chosen');
					Error = 1;
				end
			else
				% No duration given. Read file using generic reader and check later
                disp('Reading EEG...')
                Im = load(handles.FileSelector(handles.FilePathImId).Path);
                Data.EEG.Duration = size(Im,1)/Data.EEG.SamplingRate;
                if(~isempty(NumNeur))
                    if(size(Im,2) ~= NumNeur)
                        warning('Inconsistent number of neurons for EEG.dat');
                        Error = 1;
                    end
                end
                if(exist('nCells'))
                    if(size(Im,2) > nCells)
                        warning('Inconsistent number of neurons for EEG.dat');
                        Error = 1;
                    end
                end
                              
            end
            
            if(Error == 0)            
                % if CellPositions exist try converting Im data to EEG. Use identical depths otherwise
                try
                    Data.EEG.Data = MakeEEG(Im, Data.Network.CellPositions);
                catch
                    Data.EEG.Data = MakeEEG(Im, ones(size(Im,2),3));
                end
                % Redefine time to prevent inconsistencies:
                Data.EEG.Duration = length(Data.EEG.Data)/Data.EEG.SamplingRate;
            else
                Data = rmfield(Data,'EEG');
            end
                
		end
		
	case handles.rdoEEGDataEEG,
		if(~isfield(Data,'EEG') || handles.FileSelector(handles.FilePathEEGId).PathChanged==1)
			% Read EEG data	
			Data(1).EEG.SamplingRate = handles.NumberBox(handles.NumberSampRateEEG).Value;
			Data.EEG.Duration = handles.NumberBox(handles.NumberDurationEEG).Value;
			
			if(~isempty(Data.EEG.Duration))
				% Duration is given. Try reading it with the fast data reader
				try
                    disp('Reading EEG...')
					Data.EEG.Data = readASCII(handles.FileSelector(handles.FilePathEEGId).Path,...
												1,...
												Data.EEG.SamplingRate*Data.EEG.Duration);
				catch
					% File incorrect. Give warning and clean up
					warning('Invalid file for EEG.dat. Data treated as if \''No EEG data\'' option was chosen');
					Data = rmfield(Data,'EEG');
				end
			else
				% No duration given. Read file using generic reader and check later
                disp('Reading EEG...')
				tmp = load(handles.FileSelector(handles.FilePathEEGId).Path);
				if(size(tmp,2) == 1)
					Data.EEG.Data = tmp;
					Data.EEG.Duration = size(tmp,1)/Data.EEG.SamplingRate;
				else
					% File incorrect. Give warning and clean up
					warning('Invalid file for EEG.dat. Data treated as if \''No EEG data\'' option was chosen');
					Data = rmfield(Data,'EEG');
				end	
			end
		end
end

if(exist('Data'))
    disp('Done!')
    MainHandles.Data = Data;
    MainHandles.DataLoaded = 1;
else
	disp('Data not available')
    MainHandles.DataLoaded = 0;

end


MainHandles.Settings = SaveSettings(handles);

guidata(handles.MainFig,MainHandles);
delete(gcbf)