%  locate_variables locate variables in an array
%
%  ::
%
%
%  Args:
%
%  Returns:
%     :
%
%  Note:
%
%  Example:
%
%     See also:
%


function is_empty = isempty(obj)

is_empty = length(obj) == 0 || isempty(obj(1).XYZ) || length(obj(1).XYZ) == 0;

end


function varargout = SwitchTarget(varargin)
% SWITCHTARGET MATLAB code for SwitchTarget.fig
%      SWITCHTARGET, by itself, creates a new SWITCHTARGET or raises the existing
%      singleton*.
%
%      H = SWITCHTARGET returns the handle to a new SWITCHTARGET or the handle to
%      the existing singleton*.
%
%      SWITCHTARGET('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in SWITCHTARGET.M with the given input arguments.
%
%      SWITCHTARGET('Property','Value',...) creates a new SWITCHTARGET or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before SwitchTarget_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to SwitchTarget_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 SwitchTarget

% Last Modified by GUIDE v2.5 23-May-2012 10:45:04

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

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

% --- Executes just before SwitchTarget is made visible.
function SwitchTarget_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 SwitchTarget (see VARARGIN)

% Choose default command line output for SwitchTarget
handles.output = hObject;

handles.JLabelhObject = varargin{1};
[handles.ntargets_per_page] = myparse(varargin(2:end),'ntargets_per_page',100);

JLabelHandles = guidata(handles.JLabelhObject);
handles.JLDObj = JLabelHandles.guidata.data;
% set(handles.axes1,'axes',off);
handles.tablePos = get(handles.table,'Position');
handles.switchFlyPos = get(handles.pushSwitchfly,'Position');
handles.updatePos = get(handles.pushbutton_update,'Position');
handles.closePos = get(handles.pushClose,'Position');
handles.figurePos = get(handles.figure1,'Position');
handles.pagePos = get(handles.popupmenu_Page,'Position');

% initialize page number
handles.page_number = [];

% added an extra guidata here, as sometimes I was getting an error that
% figurePos wasn't getting set
guidata(hObject,handles);
handles = updateTable(handles);
guidata(hObject,handles);

function [exp,target] = GlobalTarget2LocalTarget(handles,globaltarget)

exp = find(handles.cs_ntargets >= globaltarget,1,'first');
if exp == 1,
  target = globaltarget;
else
  target = globaltarget - handles.cs_ntargets(exp-1);
end

function [globaltarget] = LocalTarget2GlobalTarget(handles,exp,target)

if exp == 1,
  globaltarget = target;
else
  globaltarget = handles.cs_ntargets(exp-1)+target;
end

function [page,row] = GlobalTarget2PageRow(handles,globaltarget)

page = ceil(globaltarget/handles.ntargets_per_page);
row = globaltarget - (page-1)*handles.ntargets_per_page;

function [globaltarget] = PageRow2GlobalTarget(handles,page,row)

globaltarget = handles.ntargets_per_page*(page-1)+row;

function [exp,target] = PageRow2LocalTarget(handles,page,row)

[exp,target] = GlobalTarget2LocalTarget(handles,PageRow2GlobalTarget(handles,page,row));

% -------------------------------------------------------------------------
function handles = updateTable(handles)
% Initialize the table

%MERGESTUPDATED

set(handles.pushbutton_update,'enable','off');
handles.curExp = handles.JLDObj.GetExp();
handles.curFly = handles.JLDObj.GetFlies();

% which fly out of all flies
handles.cs_ntargets = cumsum(handles.JLDObj.nflies_per_exp);
handles.curFlyGlobal = LocalTarget2GlobalTarget(handles,handles.curExp,handles.curFly);

% which page, row
[handles.current_target_page_number,handles.current_target_row] = GlobalTarget2PageRow(handles,handles.curFlyGlobal);

% set page number if not already set
if isempty(handles.page_number),
  handles.page_number = handles.current_target_page_number;
end

% set page number options
handles.npages = ceil(handles.cs_ntargets(end)/handles.ntargets_per_page);
handles.pagestrs = cell(1,handles.npages);
for i = 1:handles.npages,
  exp1 = PageRow2LocalTarget(handles,i,1);
  tmp = min(PageRow2GlobalTarget(handles,i,handles.ntargets_per_page),handles.cs_ntargets(end));
  exp2 = GlobalTarget2LocalTarget(handles,tmp);
  if exp1 >= exp2,
    handles.pagestrs{i} = sprintf('%d (Exp %d)',i,exp1);
  else
    handles.pagestrs{i} = sprintf('%d (Exps %d-%d)',i,exp1,exp2);
  end
  if i == handles.current_target_page_number,
    handles.pagestrs{i} = ['* ',handles.pagestrs{i},' *'];
  end

end

if handles.page_number > handles.npages,
  handles.page_number = handles.npages;
end

set(handles.popupmenu_Page,'String',handles.pagestrs,'Value',handles.page_number);

fieldList = {};
nCls = handles.JLDObj.nclassifiers;
iCls2LblNames = handles.JLDObj.iCls2LblNames;
if ~handles.JLDObj.IsGTMode()
  fieldList(end+1,:) = { @(gs,cs)gs.trajLength  'Trajectory| Length'};
  fieldList(end+1,:) = { @(gs,cs)gs.firstframe  'Start frame'};
  fieldList(end+1,:) = { @(gs,cs)gs.sexfrac     'Sex|(% male)'};
  fieldList(end+1,:) = { @(gs,cs)gs.nbouts      'Bouts|labeled'};
  fieldList(end+1,:) = { @(gs,cs)gs.totalframes 'Frames|labeled'};

  for iCls = 1:nCls
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).posframes sprintf('Frames|labeled|%s',iCls2LblNames{iCls}{1})}; %#ok<*AGROW>
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).negframes sprintf('Frames|labeled|%s',iCls2LblNames{iCls}{2})};
  end
  if nCls>1
    fieldList(end+1,:) = { @(gs,cs)gs.posframes   'Frames|labeled|pos'};
    fieldList(end+1,:) = { @(gs,cs)gs.negframes   'Frames|labeled|neg'};
  end
  for iCls = 1:nCls
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).nscorepos sprintf('%s| predicted | (current)',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).nscoreneg sprintf('%s| predicted | (current)',iCls2LblNames{iCls}{2})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).nscoreframes sprintf('%s|predicted | total | (current)',iCls2LblNames{iCls}{1})};
  end
  for iCls = 1:nCls
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).nscorepos_loaded sprintf('%s| predicted | (imported)',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).nscoreneg_loaded sprintf('%s| predicted | (imported)',iCls2LblNames{iCls}{2})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).nscoreframes_loaded sprintf('%s|predicted | total | (imported)',iCls2LblNames{iCls}{1})};
  end
  for iCls = 1:nCls
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).errorsPos sprintf('%s|errors',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).errorsNeg sprintf('%s|errors',iCls2LblNames{iCls}{2})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).validatedErrorsPos sprintf('%s|validation|errors',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).validatedErrorsNeg sprintf('%s|validation|errors',iCls2LblNames{iCls}{2})};
  end
  for iCls = 1:nCls
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).one2two sprintf('%s|switched to|%s',iCls2LblNames{iCls}{1},iCls2LblNames{iCls}{2})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).two2one sprintf('%s|switched to|%s',iCls2LblNames{iCls}{2},iCls2LblNames{iCls}{1})};
  end
else
  fieldList(end+1,:) = { @(gs,cs)gs.trajLength,'Trajectory| Length'};
  fieldList(end+1,:) = { @(gs,cs)gs.firstframe,'Start frame'};
  fieldList(end+1,:) = { @(gs,cs)gs.sexfrac,'Sex|(% male)'};
  for iCls = 1:nCls
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_posframes,sprintf('Ground Truthing|Frames|labeled|%s',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_negframes,sprintf('Ground Truthing|Frames|labeled|%s',iCls2LblNames{iCls}{2})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_suggestion_frames,sprintf('Ground Truthing|Frames|Suggested|%s',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_nbouts,sprintf('Ground Truthing|Bouts|labeled|%s',iCls2LblNames{iCls}{1})};
    fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_totalframes,sprintf('Ground Truthing|Frames|labeled|total|%s',iCls2LblNames{iCls}{1})};
%     fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_posframes,sprintf('Ground Truthing|Frames|labeled|%s',iCls2LblNames{iCls}{1}) };
%     fieldList(end+1,:) = { @(gs,cs)cs(iCls).gt_negframes,sprintf('Ground Truthing|Frames|labeled|%s',iCls2LblNames{iCls}{2}) };
  end
end

colFormat{1} = 'char';
colFormat{2} = 'numeric';
for ndx = 1:size(fieldList,1)
  colFormat{2+ndx} = 'numeric';
end

% reorganize cached data
newCachedTableData = cell(handles.cs_ntargets(end),size(fieldList,1)+2);
newCachedDataExpi = zeros(1,handles.cs_ntargets(end));
newCachedDataTarget = zeros(1,handles.cs_ntargets(end));
newCachedExpDirs = handles.JLDObj.expdirs;

if isfield(handles,'cachedTableData'),

  % reindexing for experiments
  [ism,old2newexpi] = ismember(handles.cachedExpDirs,newCachedExpDirs);

  % move data from old to new
  for oldexpi = find(ism(:)'),
    newexpi = old2newexpi(oldexpi);
    oldidx = find(handles.cachedDataExpi == oldexpi);
    if isempty(oldidx),
      continue;
    end
    [targets_curr,order] = sort(handles.cachedDataTarget(oldidx));
    oldidx = oldidx(order);
    newidx = LocalTarget2GlobalTarget(handles,newexpi,targets_curr);
    newCachedTableData(newidx,:) = handles.cachedTableData(oldidx,:);
    newCachedDataExpi(newidx) = newexpi;
    newCachedDataTarget(newidx) = handles.cachedDataTarget(oldidx);
  end

end

% overwrite
handles.cachedTableData = newCachedTableData;
handles.cachedDataExpi = newCachedDataExpi;
handles.cachedDataTarget = newCachedDataTarget;
handles.cachedExpDirs = newCachedExpDirs;

tableData = {};
tableExpi = [];
tableTarget = [];
count = 1;

[exp_start,target_start] = PageRow2LocalTarget(handles,handles.page_number,1);
tmp = min(PageRow2GlobalTarget(handles,handles.page_number,handles.ntargets_per_page),handles.cs_ntargets(end));
[exp_end,target_end] = GlobalTarget2LocalTarget(handles,tmp);

for selExp = exp_start:exp_end,
  if selExp == exp_start,
    startcurr = target_start;
  else
    startcurr = 1;
  end
  endcurr = handles.JLDObj.nflies_per_exp(selExp);
  if selExp == exp_end,
    endcurr = min(endcurr,target_end);
  end
  for flyNum = startcurr:endcurr,
    [genStats,clsStats] = handles.JLDObj.GetFlyStats(selExp,flyNum);
    tableData{count,1} = handles.JLDObj.expnames{selExp};
    tableData{count,2} = flyNum;
    for ndx = 1:size(fieldList,1)
      fcn = fieldList{ndx,1};
      tableData{count,2+ndx} = fcn(genStats,clsStats);
    end
    tableExpi(count) = selExp;
    tableTarget(count) = flyNum;
    count = count+1;
  end
end
handles.tableData = tableData;

% store in global cache
start_target = PageRow2GlobalTarget(handles,handles.page_number,1);
end_target = start_target + numel(tableExpi) - 1;
handles.cachedTableData(start_target:end_target,:) = tableData;
handles.cachedDataExpi(start_target:end_target) = tableExpi;
handles.cachedDataTarget(start_target:end_target) = tableTarget;

set(handles.table,'Data',tableData);
set(handles.table,'ColumnName',{});
drawnow();
set(handles.table,'ColumnName',...
  {'Experiment Name','Target|Number',fieldList{:,2}});
handles.fieldList = fieldList;
set(handles.table,'ColumnEditable',false);
set(handles.table,'ColumnFormat',colFormat);
set(handles.table,'CellSelectionCallback',@tableSelect);
set(handles.pushbutton_update,'enable','on');

% Update handles structure

% UIWAIT makes SwitchTarget wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% -------------------------------------------------------------------------
function initTable(hObject)
% Use java objects to tweak the table. Found this online at
% http://www.mathworks.com/matlabcentral/newsreader/view_thread/298335

handles = guidata(hObject);
jscrollpane = findjobj(handles.table);
jtable = jscrollpane.getViewport.getView;
jtable.setSortable(false);

colWidth = repmat({70},1,13);
colWidth{1} = 300;
set(handles.table,'ColumnWidth',colWidth);

uitablepeer  = findjobj(hObject,'-nomenu','class','uitablepeer');
set(uitablepeer,'MouseClickedCallback',@MouseClickHandler);

% rowHeaderViewport=jscrollpane.getComponent(4);
% rowHeader=rowHeaderViewport.getComponent(0);
% rowHeader.setSize(80,360);
%
% %resize the row header
% newWidth=0; %100 pixels.
% rowHeaderViewport.setPreferredSize(java.awt.Dimension(newWidth,0));
% height=rowHeader.getHeight;
% rowHeader.setPreferredSize(java.awt.Dimension(newWidth,height));
% rowHeader.setSize(newWidth,height);

% --- Outputs from this function are returned to the command line.
function varargout = SwitchTarget_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
% set double click callback

varargout{1} = handles.output;

function tableSelect(hObject,eventData)

handles = guidata(hObject);
jscrollpane = findjobj(handles.table);
jtable = jscrollpane.getViewport.getView;

if(size(eventData.Indices,1)==1)
  ndx = jtable.getActualRowAt(eventData.Indices(1,1)-1)+1;

  start_target = PageRow2GlobalTarget(handles,handles.page_number,1);
  handles.curExp = handles.cachedDataExpi(start_target + ndx - 1);
  handles.curFly = handles.tableData{ndx,2};
end

guidata(hObject,handles);

% --- Executes on button press in pushSwitchfly.
function pushSwitchfly_Callback(hObject, eventdata, handles)
% hObject    handle to pushSwitchfly (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
JLabelHandles = guidata(handles.JLabelhObject);
JLabelHandles = JLabel('SetCurrentMovie',JLabelHandles,handles.curExp);
guidata(handles.JLabelhObject,JLabelHandles);
JLabelHandles = JLabel('SetCurrentFlies',JLabelHandles,handles.curFly);
guidata(handles.JLabelhObject,JLabelHandles);
return

% --- Executes on button press in pushClose.
function pushClose_Callback(hObject, eventdata, handles)
% hObject    handle to pushClose (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
delete(handles.figure1);

% --- Executes when figure1 is resized.
function figure1_ResizeFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

if ~isfield(handles,'figurePos'),
  return;
end

oldClosePosRight = handles.figurePos(3)-handles.closePos(1);
guiPos = get(handles.figure1,'Position');
newClosePos = [guiPos(3)-oldClosePosRight handles.closePos(2:4)];
set(handles.pushClose,'Position',newClosePos);

oldSwitchPosRight = handles.figurePos(3)-handles.switchFlyPos(1);
newSwitchFlyPos = [guiPos(3)-oldSwitchPosRight handles.switchFlyPos(2:4)];
set(handles.pushSwitchfly,'Position',newSwitchFlyPos);

oldUpdatePosRight = handles.figurePos(3)-handles.updatePos(1);
newUpdatePos = [guiPos(3)-oldUpdatePosRight handles.updatePos(2:4)];
set(handles.pushbutton_update,'Position',newUpdatePos);

newTableWidth = guiPos(3)- handles.figurePos(3)+handles.tablePos(3);
newTableHeight = guiPos(4)- handles.figurePos(4)+handles.tablePos(4);
set(handles.table,'Position',[handles.tablePos(1:2) newTableWidth newTableHeight]);

% --- Executes on button press in pushbutton_update.
function pushbutton_update_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_update (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
handles = updateTable(handles);
guidata(hObject,handles);

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

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

handles.page_number = get(hObject,'Value');
start_target = PageRow2GlobalTarget(handles,handles.page_number,1);
end_target = min(handles.cs_ntargets(end),start_target+handles.ntargets_per_page-1);
if all(handles.cachedDataExpi(start_target:end_target) ~= 0),
  handles.tableData = handles.cachedTableData(start_target:end_target,:);
  set(handles.table,'Data',handles.tableData);
  set(handles.table,'ColumnName',{});
  set(handles.table,'ColumnName',...
    {'Experiment Name','Target|Number',handles.fieldList{:,2}});
else
  handles = updateTable(handles);
end
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function popupmenu_Page_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu_Page (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

% From http://www.mathworks.com/matlabcentral/newsreader/view_thread/270514

function MouseClickHandler(handle,cbData)
  % handle ~ java object UITablePeer
  % cbData ~ callback data for the MouseClickedCallback event

  if get(cbData,'ClickCount') == 2
      curfig = findall(0,'type','figure','name','SwitchTarget');
      if numel(curfig)~=1,
        return;
      end

      pushSwitchfly_Callback(curfig,[],guidata(curfig));
  end


function AddShortcutCategories(categories)
%ADDSHORTCUTCATEGORIES  Adds a new category of shortcut.
%
% If CATEGORY is a character array, ADDSHORTCUTCATEGORIES(CATEGORY) adds
% a new category of shortcut named CATEGORY.
%
% If CATEGORY is a cell array of strings,
% ADDSHORTCUTCATEGORIES(CATEGORY) adds a new category of shortcut for
% each string in CATEGORY.
%
% Examples:
%
% Provide sample usage code here
%
% See also: List related files here

% $Author: rcotton $	$Date: 2010/10/01 13:58:56 $	$Revision: 1.1 $
% Copyright: Health and Safety Laboratory 2010

if ischar(categories)
   categories = cellstr(categories);
end

shortcutUtils = GetShortcutUtils();
cellfun(@(category) shortcutUtils.addNewCategory(category), categories);

end


function isUpdated = bst_update(AskConfirm)
% BST_UPDATE:  Download and install the latest version of Brainstorm.
%
% USAGE:  isUpdated = bst_update(AskConfirm)
%         isUpdated = bst_update()
%
% INPUT:
%    - AskConfirm: {0,1}, If 1, ask user confirmation before proceeding to update

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2009-2022

% Java imports
import org.brainstorm.icon.*;
% Parse inputs
if (nargin == 0) || isempty(AskConfirm)
    AskConfirm = 0;
end
isUpdated = 0;

% === ASKING CONFIRMATION ===
if AskConfirm
    res = java_dialog('confirm', ['Download latest Brainstorm update ?' 10 10 ...
                                  'To turn off automatic updates, edit software preferences.' 10 10], 'Update');
    if ~res
        return
    end
end

% === DOWNLOAD NEW VERSION ===
% Get update zip file
urlUpdate  = 'http://neuroimage.usc.edu/bst/getupdate.php?c=UbsM09&src=1';
[installDir, bstDir] = fileparts(fileparts(fileparts(fileparts(mfilename('fullpath')))));
zipFile    = fullfile(installDir, 'brainstorm_update.zip');

% Check permissions
if ~file_attrib(installDir, 'w') || ~file_attrib(fullfile(installDir, bstDir), 'w')
    strMsg = 'Error: Installation folder is read-only...';
    if ispc
        strMsg = [strMsg 10 10 ...
                  'On some Windows computers, the user folders Documents and Downloads' 10 ...
                  'and the system folder C:\Programs\ are seen as read-only by Matlab.' 10 ...
                  'Try with admin privileges (right-click on Matlab > Run as Administrator)' 10 ...
                  'and if you still cannot update, move the brainstorm3 folder somewhere else.'];
    end
    disp(['BST> ' strrep(strMsg, char(10), [char(10) 'BST> '])]);
    if AskConfirm
        java_dialog('msgbox', [strMsg 10 10], 'Update');
    end
    return
end

% Download file
errMsg = gui_brainstorm('DownloadFile', urlUpdate, zipFile, 'Brainstorm update');
% If file was not downloaded correctly
if ~isempty(errMsg)
    disp('BST> Update: Unable to download updates.');
    disp(['BST>     ' strrep(errMsg, char(10), [10 'BST>     '])]);
    if AskConfirm
        java_dialog('msgbox', ['Could not download new packages:' 10 errMsg 10 10 ...
                               'Software was not updated.' 10 10], 'Update');
    end
    return
end

% === STOP BRAINSTORM ===
if isappdata(0, 'BrainstormRunning')
    bst_exit();
end

% === DELETE THE PREVIOUS INSTALLATION ===
% New progress bar
jProgressBar = javax.swing.JProgressBar();
jProgressBar.setIndeterminate(1);
jProgressBar.setStringPainted(0);
jLabel = javax.swing.JLabel('Installing new version...');
jPanel = gui_river();
jPanel.add('p hfill vfill', jLabel);
jPanel.add('p hfill', jProgressBar);
jDialog = javax.swing.JFrame('Brainstorm update');
jDialog.setAlwaysOnTop(1);
jDialog.setResizable(0);
jDialog.setPreferredSize(java.awt.Dimension(350, 130));
jDialog.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
jDialog.getContentPane().add(jPanel);
jDialog.pack();
jDialog.setLocationRelativeTo([]);
jDialog.setVisible(1);
jDialog.getContentPane().repaint();
jDialog.setIconImage(IconLoader.ICON_APP.getImage());
disp('BST> Update: Removing previous installation...');

% Go to zip folder (to make sure we are not in a folder we are deleting)
cd(installDir);
% Try the folders separately
warning('off', 'MATLAB:RMDIR:RemovedFromPath');
try
    rmdir(fullfile(installDir, bstDir, 'toolbox'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'external'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'bin'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'anatomy', 'ICBM152'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'eeg', 'ICBM152'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'anatomy', 'Colin27'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'eeg', 'Colin27'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'anatomy', 'MNI_Colin27'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'eeg', 'MNI_Colin27'), 's');
end
try
    rmdir(fullfile(installDir, bstDir, 'defaults', 'eeg', 'NotAligned'), 's');
end
warning('on', 'MATLAB:RMDIR:RemovedFromPath');

% === UNZIP FILE ===
disp('BST> Update: Unzipping...');
% Unzip update file
unzip(zipFile);
% Delete temporary update file
delete(zipFile);
% If the current install folder is not named 'brainstorm3': Copy files to destination folder
if ~strcmp(bstDir, 'brainstorm3')
    % Replace all old files with new files
    copyfile(fullfile(installDir, 'brainstorm3'), fullfile(installDir, bstDir), 'f');
    % Delete downloaded files
    rmdir(fullfile(installDir, 'brainstorm3'), 's');
end
% Add some folders to the path again
addpath(fullfile(installDir, bstDir, 'toolbox', 'misc'));
addpath(fullfile(installDir, bstDir, 'toolbox', 'core'));
addpath(fullfile(installDir, bstDir, 'toolbox', 'io'));
addpath(fullfile(installDir, bstDir, 'toolbox', 'gui'));

% === DISPLAY RELEASE NOTES ===
% Close waitbar
jDialog.setVisible(0);
jDialog.dispose();
% Display the latest updates
bst_mutex('create', 'ReleaseNotes');
jFrame = view_text({fullfile(installDir, bstDir, 'doc', 'updates.txt'), ...
                    fullfile(installDir, bstDir, 'doc', 'updates_2020.txt')}, 'Release notes', 1);
java_setcb(jFrame, 'WindowClosingCallback', @(h,ev)bst_mutex('release', 'ReleaseNotes'));
bst_mutex('waitfor', 'ReleaseNotes');

% === RESET ENVIRONMENT ===
% Delete the brainstorm.jar to force downloading a new one when Brainstorm restarts
jarFile = fullfile(installDir, bstDir, 'java', 'brainstorm.jar');
if exist(jarFile, 'file')
    delete(jarFile);
    % The brainstorm.jar file could not be deleted because it was still in use: delete it at next startup
    if exist(jarFile, 'file')
        % Create file to indicate that brainstorm.jar should be deleted
        UpdateFile = fullfile(installDir, bstDir, 'java', 'outdated_jar.txt');
        fid = fopen(UpdateFile, 'w');
        fwrite(fid, ['delete(''' jarFile ''');']);
        fclose(fid);
    end
end
% Update is finished
disp('BST> Update: Done.');

% === RESTART MATLAB ===
h = msgbox(['Brainstorm was updated successfully.' 10 10 ...
            'Matlab will now close.' 10 ...
            'Restart Matlab and run brainstorm.m to finish the installation.' 10 10], 'Update');
waitfor(h);
exit;


function test_suite=test_assert_true()
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_assert_true_exceptions

    assertExceptionThrown(@()assertTrue(...
                                false),...
                                        'assertTrue:falseCondition');
    assertExceptionThrown(@()assertTrue(...
                                struct),...
                                        'assertTrue:invalidCondition');
    assertExceptionThrown(@()assertTrue(...
                                [true true]),...
                                        'assertTrue:invalidCondition');

function test_assert_true_passes
    assertTrue(true);


%kImportAny 'Generic Routine Interface (glue)'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros ImportAny.pane file
%
% Parameters:
% InputFile: i1 'Name of Input Image', required: 'input filename #1'
% OutputFile: o1 'Output Filename ', required: 'output filename #1'
%
% Example: o1 = kImportAny(i1, {'i1','';'o1',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% ImportAny - Imports any Imageformat using convert
%
%  DESCRIPTION
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1996-2003, Rainer Heintzmann,  All rights reserved.
%

function varargout = kImportAny(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kImportAny(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'o1', '__output'};
maxval={0,0};
minval={0,0};
istoggle=[0,0];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'conviff"  '],Inputs,narglist);


function uninstallGibbon

% function uninstallGibbon
%-------------------------------------------------------------------------
% Change log:
% 2022/03/16 Created based on installGibbon
%-------------------------------------------------------------------------

%% Add GIBBON library path so functions are known to use here
gibbonPath=fileparts(mfilename('fullpath')); %Get the GIBBON path
addpath(fullfile(gibbonPath,'lib')); %Add gibbon lib path so gibbon functions used here are known

%% Settings

W=60; %Scrollbar width
squareSizeMax=1200;

%% Open figure

%Force groot units to be pixels
graphicalRoot=groot;
grootUnits=graphicalRoot.Units;
if ~strcmp(grootUnits,'pixels')
    graphicalRoot.Units='pixels';
end

screenSizeGroot = get(groot,'ScreenSize');

figStruct.Name='uninstalling GIBBON';

hf = cFigure(figStruct);
hf.NumberTitle='off';

squareSize=round([min(screenSizeGroot(3:4)) min(screenSizeGroot(3:4))]); % width, height
squareSize(squareSize>squareSizeMax)=squareSizeMax;

hf.Units='pixels';
windowSize=[2*W (screenSizeGroot(4)-squareSize(2))-2*W squareSize(1) squareSize(2)]; % left bottom width height

hf.Position=windowSize; % left bottom width height

%Remove tool and menu bars
ht = findobj(allchild(hf),'flat','Type','uitoolbar');
delete(ht);
ht = findobj(allchild(hf),'flat','Type','uimenu');
delete(ht);

set(hf,'ResizeFcn',{@resizeAll,{hf}});

hf.UserData.W=W;
hf.UserData.gibbonPath=gibbonPath;

% Reset groot units if a change was needed
if ~strcmp(grootUnits,'pixels')
    graphicalRoot.Units=grootUnits;
end

%% Initilize text fields

textPositionInstall=[W hf.Position(4)-W hf.Position(3)-W*2 round(W/1.5)];

top_title='uninstalling GIBBON';
hTextTitle = uicontrol(hf,'Style','text','String',top_title,...
    'Position',textPositionInstall,...
    'BackgroundColor',[1 1 1],'HorizontalAlignment','Left','FontSize',18,'FontWeight','normal');

hf.UserData.uihandles.hTextTitle=hTextTitle;

top_statement='Removing gibbon paths. Please wait...';
textPositionStatement=textPositionInstall;
textPositionStatement(2)=textPositionInstall(2)-W;

hTextStatement = uicontrol(hf,'Style','text','String',top_statement,...
    'Position',textPositionStatement,...
    'BackgroundColor',[1 1 1],'HorizontalAlignment','Left','FontSize',12,'FontWeight','bold');

hf.UserData.uihandles.hTextStatement=hTextStatement;

%% Add image

imagePath=fullfile(gibbonPath,'docs','img','GIBBON_overview.jpg');
M=importdata(imagePath);

figure(hf);
image(M);
axis tight; axis equal; axis off;
hAxis=gca;

hAxis.Units='pixels';
% [left bottom width height]
axisHeight=hf.Position(4)-7*W;
axisWidth=hf.Position(3)-2*W;
hAxis.Position=[round((hf.Position(3)-axisWidth)/2) round((hf.Position(4)-axisHeight))-6*W axisWidth axisHeight];

hf.UserData.uihandles.hAxis=hAxis;

%%
drawnow;

%% Adding temp folder if it does not exist

tempPath=fullfile(gibbonPath,'data','temp');

if exist(tempPath,'file')
    rmdir(tempPath,'s');
end

%% Adding paths

[pathNames]=getSubPaths(gibbonPath);

%Remove "hidden" folders with . in path name
logicKeep=~gcontains(pathNames,'.');
pathNames=pathNames(logicKeep);

for q=1:1:numel(pathNames)
     pathNameNow=pathNames{q};
     rmpath(pathNameNow); %Remove path
     hTextStatement.String=[top_statement,' ',num2str(round(100*q/numel(pathNames))),'% complete'];
     drawnow;
end
rmpath(fullfile(gibbonPath,'lib'));

hTextStatement.String='Done removing toolbox paths';
drawnow;
pause(0.5);

%% Unzip compressed data
hf.UserData.uihandles.hTextStatement.String='Removing unzipped data';
drawnow;

zipFolder=fullfile(hf.UserData.gibbonPath,'data','DICOM/0001_human_calf');

files = dir(fullfile(zipFolder,'*.dcm'));
files={files(1:end).name};
files=sort(files(:));
if ~isempty(files)
    for q=1:numel(files)
        delete(fullfile(zipFolder,files{q}));
    end
end

hf.UserData.uihandles.hTextStatement.String='Done removing unzipped data'; drawnow;
pause(0.5);

%% Removing documentation integrating

% hf.UserData.uihandles.hTextStatement.String='Removing documentation'; drawnow;
%
% hf.UserData.uihandles.hTextStatement.String='Done removing documentation'; drawnow;
% pause(0.5);

%%

hf.UserData.uihandles.hTextTitle.String='Done. GIBBON has been uninstalled.';

hf.UserData.uihandles.hTextStatement.String='Documentation integration removal is not supported yet. ';

hDoneButton = uicontrol('Style', 'pushbutton', 'String', 'Done!','Position',[W hf.Position(4)-W*3.5   5*W round(W/1.5)],'Callback',{@closeDone,{hf}},'FontSize',12);
hf.UserData.uihandles.hBrowseButton=hDoneButton;

end

%% Resizing

function resizeAll(~,~,inputCell)
hf=inputCell{1};
W=hf.UserData.W;

%Reposition axis
axisHeight=hf.Position(4)-7*W;
axisWidth=hf.Position(3)-2*W;
hf.UserData.uihandles.hAxis.Position=[round((hf.Position(3)-axisWidth)/2) round((hf.Position(4)-axisHeight))-6*W axisWidth axisHeight];

%Reposition gui items
if isfield(hf.UserData.uihandles,'hTextTitle')
    hf.UserData.uihandles.hTextTitle.Position=      [W hf.Position(4)-W     hf.Position(3)-W*2 round(W/1.5)];
end

if isfield(hf.UserData.uihandles,'hTextStatement')
    hf.UserData.uihandles.hTextStatement.Position=  [W hf.Position(4)-2*W   hf.Position(3)-W*2 round(W/1.5)];
end

if isfield(hf.UserData.uihandles,'hTextInfo1')
    hf.UserData.uihandles.hTextInfo1.Position=      [W hf.Position(4)-3*W hf.Position(3)-W*2 round(W/1.5)];
end

if isfield(hf.UserData.uihandles,'hTextInput1')
    hf.UserData.uihandles.hTextInput1.Position=     [W hf.Position(4)-3.5*W   hf.Position(3)-W*2 round(W/1.5)];
end

if isfield(hf.UserData.uihandles,'hBrowseButton')
    hf.UserData.uihandles.hBrowseButton.Position=     [W hf.Position(4)-W*4.5   5*W                round(W/1.5)];
end

if isfield(hf.UserData.uihandles,'hconfirmButton')
    hf.UserData.uihandles.hconfirmButton.Position=     [W hf.Position(4)-W*5.5   5*W                round(W/1.5)];
end

if isfield(hf.UserData.uihandles,'hDoneButton')
    hf.UserData.uihandles.hDoneButton.Position=     [W hf.Position(4)-W*3.5   5*W                round(W/1.5)];
end

end

%% Close/done

function closeDone(~,~,inputCell)

hf=inputCell{1};
close(hf);

end
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2017  Kevin Mattheus Moerman
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


%ByteCodes Bytecode enumeration for the brick
%
% Notes::
% - bytecodes can be found in the EV3 documentation and source code
% (bytecodes.h)

classdef ByteCodes < uint8
    enumeration
        %VM
        Error (0) % = 0x00,
        Nop (1) % = 0x01,
        ProgramStop (2) % = 0x02,
        ProgramStart (3) % = 0x03,
        ObjectStop (4) % = 0x04,
        ObjectStart (5) % = 0x05,
        ObjectTrig (6) % = 0x06,
        ObjectWait (7) % = 0x07,
        Return (8) % = 0x08,
        Call (9) % = 0x09,
        ObjectEnd (10) % = 0x0A,
        Sleep (11) % = 0x0B,
        ProgramInfo (12) % = 0x0C,
        Label(13) % = 0x0D,
        Probe(14) % = 0x0E,
        Do(15) % = 0x0F,

        %Move
        InitBytes (47) %= 0x2F,

        %Branch
        Jr (64) %= 0x40,

        %VM
        Info (124) %= 0x7C,
        String (125) %= 0x7D,
%        MemoryWrite = 0x7E,
%        MemoryRead = 0x7F,

        %UI
        UIFlush (128) %= 0x80,
        UIRead (129) %= 0x81,
        UIWrite (130) %= 0x82,
        UIButton (131) %= 0x83,
        UIDraw (132) %= 0x84,

        %Timer
        TimerWait (133) %= 0x85,
        TimerReady (134) %= 0x86,
        TimerRead (135) %= 0x87,

        %Sound
        Sound (148) %= 0x94,
        SoundTest (149) %= 095,
        SoundReady (150) % = 0x96,

%       %Input
%       InputSample = 0x97,
        InputDeviceList (152) % = 0x98,
        InputDevice (153) %= 0x99,
        InputRead (154) % = 0x9a,
%       InputTest = 0x9b,
        InputReady (156) % = 0x9c,
        InputReadSI (157) % = 0x9d,
%       InputReadExt = 0x9e,
%       InputWrite = 0x9f,
%
%       %Output
%       OutputGetType = 0xa0,
        OutputSetType (161) % = 0xa1,
        OutputReset (162) % = 0xa2,
        OutputStop (163) % = 0xA3,
        OutputPower (164) % = 0xA4,
        OutputSpeed (165) % = 0xA5,
        OutputStart	(166) % = 0xA6,
        OutputPolarity (167) % = 0xA7,
        OutputRead (168) % = 0xA8,
        OutputTest (169) % = 0xA9,
        OutputReady (170) % = 0xAA,
%       OutputPosition = 0xAB, NOT IMPLEMENTED IN THE CODE
        OutputStepPower (172) % = 0xAC,
        OutputTimePower (173) % = 0xAD,
        OutputStepSpeed (174) % = 0xAE,
        OutputTimeSpeed (175) % = 0xAF,
        OutputStepSync (176) % = 0xB0,
        OutputTimeSync (177) % = 0xB1,
        OutputClrCount (178) % = 0xB2,
        OutputGetCount (179) % = 0xB3,
%
%       %Memory
%        File = 0xC0,
%        Array = 0xc1,
%        ArrayWrite = 0xc2,
%        ArrayRead = 0xc3,
%        ArrayAppend = 0xc4,
%        MemoryUsage = 0xc5,
%        FileName = 0xc6,
%

         %Communications
         COMGet (211) % = 0xD3,
         COMSet (212) % = 0xD4,

%       %Mailbox
         MailboxOpen (216) % = 0xD8,
         MailboxWrite (217) % = 0xD9,
         MailboxRead (218) % = 0xDA,
         MailboxTest (219) % = 0xDB,
         MailboxReady (220) % = 0xDC,
         MailboxClose (221) % = 0xDD,
    end
end


function report = edl_readreport(filename)
%EDL_READREPORT Reads in a EDL report
%
% $ Syntax $
%   - report = edl_readreport(filename)
%
% $ Description $
%   - report = edl_readreport(filename) reads in a EDL report from
%     a report xml file. The returned report is a struct with
%     following fields:
%       - attribs: the header attributes
%           - guid:     the GUID string identifying the report
%       - entries:  the report item entries
%         at least have following fields:
%           - internal_index:  the internal index
%
% $ History $
%   - Created by Dahua Lin, on Aug 14, 2006
%

%% Read in file

doctag = 'ExpReport';
nodetag = 'Entry';

S = edl_readprops(filename, nodetag);

%% Post-Processing

% doc tag
if ~strcmp(S.tag, doctag)
    error('edl:parseerror', ...
        'Invalid document tag %s for report', S.tag);
end

% doc attribs
if isempty(S.attribs)
    error('edl:parseerror', ...
        'The document element for report has no attributes');
end

attrnames = {'guid'};
tf = isfield(S.attribs, attrnames);
if ~all(tf)
    error('edl:parserror', ...
        'The required header %s does not exist', ...
        attrnames{find(~tf, 1)});
end

report.attribs = S.attribs;

% entries

report.entries = edl_check_internalindices(S.(nodetag));


function expdirs = setUpDir(rootdir,varargin)

[ips,doforce,annotate,features,dosoftlink,frontside,rotatesideview,rotatefrontview] = ...
  myparse(varargin,...
  'ips',[],...
  'doforce',false,...
  'annotate',true,...
  'features',true,...
  'dosoftlink',false,...
  'frontside',false,...
  'rotatesideview',0,...
  'rotatefrontview',0);

if frontside
  createDirFcn = @makeMoviesFrontSide;
else
  createDirFcn = @makeMovies;
end

fprintf('Creating JAABA directories within root directory %s...\n',rootdir);
expdirs = createDirFcn(rootdir,'doforce',doforce,'dosoftlink',dosoftlink,...
  'rotatefrontview',rotatefrontview,'rotatesideview',rotatesideview);

if annotate
  fprintf('Annotate interest points...\n');
  annotateAllDirs(rootdir,'ips',ips,'doforce',doforce,'frontside',frontside);
end

if features
  fprintf('Generating spatiotemporal features...\n');
  genAllFeatures(rootdir,'doforce',doforce,'frontside',frontside);
end


function  makeVideoFrame(Fig,filename,FigOpt,ExpOpt)

% MAKEVIDEOFRAME  Export figure to image.
%   MAKEVIDEOFRAME(FIG,FNAME,FIGOPT,EXPOPT) exports the constents of figure
%   FIG to an image with name filename, using FIGOPT and EXPOPT as options.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

dir = [ExpOpt.root 'figures/' ExpOpt.site '/' ExpOpt.lmkTypes '/images/'];
if ~isdir(dir)
    mkdir(dir);
end
filepath = [dir filename];
imgFrame(Fig.fig,filepath);

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   SLAMTB is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


% Publicly accessible dependent properties of an object.
%
% See also: meta.property

% Copyright 2010 Levente Hunyadi
function dependent = getdependentproperties(obj)

dependent = {};
if isstruct(obj)  % structures have no dependent properties
    return;
end

try
    clazz = metaclass(obj);
catch %#ok<CTCH>
    return;  % old-style class (i.e. not defined with the classdef keyword) have no dependent properties
end

k = 0;  % number of dependent properties found
n = numel(clazz.Properties);  % maximum number of properties
dependent = cell(n, 1);
for i = 1 : n
    property = clazz.Properties{i};
    if property.Abstract || property.Hidden || ~strcmp(property.GetAccess, 'public') || ~property.Dependent
        continue;  % skip abstract, hidden, inaccessible and independent properties
    end

    k = k + 1;
    dependent{k} = property.Name;
end
dependent(k+1:end) = [];  % drop unused cells


function [filename] = imgFilename(iid)
% function [filename] = imgFileName(iid)
%
% Return image filename.
%
% INPUT
%	iid		Image ID.
%
% OUTPUT
%	filename	Image filename.
%
% David Martin <dmartin@eecs.berkeley.edu>
% January 2003

filename = fullfile(bsdsRoot,'images','test',sprintf('%d.jpg',iid));
if length(dir(filename))==1, return; end

filename = fullfile(bsdsRoot,'images','train',sprintf('%d.jpg',iid));
if length(dir(filename))==1, return; end

error(sprintf('Could not find image %d in %s/images/{train,test}.', ...
              iid,bsdsRoot));


%
% Author: Javier Lopez-Calderon
%
function cleanerplab

p = which('eegplugin_erplab');
p = p(1:findstr(p,'eegplugin_erplab.m')-1);
direrp = {'functions', 'pop_functions', 'Guis'};
recycle on;

for i=1:length(direrp)
        tempname1 = fullfile(p,direrp{i},'*.m~');
        tempname2 = fullfile(p,direrp{i},'*.asv');
        delete(tempname1)
        delete(tempname2)
end
recycle off;
disp('Clear!')


function p = getcustompwd

% GETCUSTOMPWD determines the present working directory, ensuring that
% it is not the private directory of the distributed computing toolbox.

% Copyright (C) 2011-2012, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% these are for faster processing on subsequent calls
persistent previous_pwd previous_argout

t = pwd;

if isequal(t, previous_pwd)
  % don't do the processing again, but return the previous values from cache
  p = previous_argout;
  return
end

% don't use the present directory if it contains the peer code
% it will confuse the worker with a potentially different mex file
if strcmp(pwd, fileparts(mfilename('fullpath')))
  warning('will not change directory to %s', t);
  p = [];
else
  p = t;
end

% remember the current input and output arguments, so that they can be
% reused on a subsequent call in case the same input argument is given
previous_pwd    = t;
previous_argout = p;


%% Example
% This script is used to initialize the precise hand guiding functionality on KUKA
% robot remotely

% Mohammad SAFEEA, 22nd of Oct  2017

% TO use this example:
% 1- Start the server on KUKA
% 2- Start the client on Matlab
% 3- Run this script
% 4- To turn off the precise hand guiding, keep pressing the green button
% of the robot for more than 5 seconds (you can notice that the lights
% start to flash in blue) then the functionality is turned off
% automatically

PreciseHandGuidingExample();


function filter_spec = ext2filter_spec(exts)
%EXT2FILTER_SPEC Generates a filter specification from a list of file extensions.
% Usage:
%   filter_spec = ext2filter_spec(ext) % single extension
%   filter_spec = ext2filter_spec(exts)
%
% See also: uigetfile, uigetdir, uibrowse

if ischar(exts)
    exts = {exts};
end

if ~iscellstr(exts)
    error('Expected a string or cell array of strings.')
end

% Keep only characters afte the period
exts = regexprep(exts, '.*\.', '');

% Create filter specification string
filter_spec = ['*.' strjoin(exts, ';*.')];

end


function [Prefix, ViewName, Ext] = AfniPrefix (Prefix)
%
%   [Prefix, View, Ext] = AfniPrefix (Name)
%
%Purpose:
%   returns the afni prefix, view and extension from a brick name
%   No checking is done to make sure that View or Ext are acceptable
%   see PrefixStatus instead
%
%Input Parameters:
%   Name : 'elvis' or 'elvis+orig' or 'elvis+orig.HEAD'
%
%
%Output Parameters:
%   Prefix: 'elvis'
%   View: '+orig'
%   Ext: .HEAD
%
%Key Terms:
%
%More Info :
%   PrefixStatus
%
%
%
%     Author : Ziad Saad
%     Date : Tue Dec 4 15:24:09 EST 2001
%     SSCC/NIMH/ National Institutes of Health, Bethesda Maryland

%Define the function name for easy referencing
FuncName = 'AfniPrefix';

[Prefix, Ext] = RemoveExtension(Prefix, '.HEAD|.BRIK');
[Prefix, ViewName] = RemoveExtension(Prefix, '+orig|+acpc|+tlrc');

err = 0;
return;


function item = initialise(item, val, dflag)

% function item = initialise(item, val, dflag)
% This is a generic initialisation function to insert values into the val
% field of a cfg_item. It is usable for all leaf cfg_item classes
% (cfg_entry, cfg_files, cfg_menu). Assignment checks are done through
% subsasgn.
% dflag is ignored for leaf entries - the passed value is assigned
% unconditionally.
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: initialise.m 4898 2012-09-05 13:40:16Z volkmar $

rev = '$Rev: 4898 $'; %#ok

d1flag = false;
if ischar(val) && strcmp(val, '<DEFAULTS>')
    if isempty(item.def)
        % don't change anything if no .def field
        return;
    else
        try
            val = feval(item.def, {});
            d1flag = true;
        catch
            cfg_message('matlabbatch:initialise:defaults', ...
                    '%s: No matching defaults value found.', ...
                    subsasgn_checkstr(item,substruct('.','val')));
            val = '<UNDEFINED>';
        end;
    end;
end;

subs = substruct('.', 'val', '{}', {1});
if ischar(val) && strcmp(val, '<UNDEFINED>') % val may be <UNDEFINED>
    item.val = {};
else
    % Modify job before initialisation
    if ~d1flag && ~dflag && ~isempty(item.rewrite_job)
        val = feval(item.rewrite_job, val);
    end
    item = subsasgn(item, subs, val);
end;


function str=getSummaryStr(obj, format)

    formatters=struct();
    formatters.text=@obj2text;
    formatters.xml=@obj2xml;

    f=formatters.(format);

    str=f(obj);

function str=obj2text(obj)
    content=getSummaryContent(obj);

    % set outcome to 'failure', 'error', 'skipped', or 'passed'
    outcome_verbosity=2;
    outcome=getOutcomeStr(obj, outcome_verbosity);

    if isstruct(content)
        % error or failure
        stack_prefix='  ';
        stack_str=moxunit_util_stack2str(content.stack, stack_prefix);
        str=sprintf('%s: %s\n%s',...
                outcome,content.message,stack_str);

    elseif ischar(content)
        % skipped
        str=sprintf('%s: %s', outcome, content);

    elseif isequal(content,[])
        % passed
        str='';

    else
        assert(false,'this should not happen');
    end

function str=obj2xml(obj)
    test_=getTest(obj);

    prefix=sprintf('<testcase classname="%s" name="%s" time="%.3f"',...
                moxunit_util_escape_xml(get_classname(test_)),...
                moxunit_util_escape_xml(getName(test_)),...
                getDuration(obj));

    if isSuccess(obj)
        infix='';
        suffix=' />';
    else
        content=getSummaryContent(obj);

        % outcome is 'failure', 'error', or 'skipped'
        outcome_verbosity=2;
        outcome=getOutcomeStr(obj, outcome_verbosity);

        if isNonFailure(obj)
            % skipped
            % note: showing the reason is not supported
            infix=sprintf('>\n  <%s />',outcome);
        else
            % XXX currently the entire error message is shown, together
            % with the stack trace. It may be more convenient to show a
            % summary of this information
            raw_message=content.message;
            message=moxunit_util_remove_matlab_anchor_tag(raw_message);
            message=moxunit_util_escape_xml(message);

            raw_stack_str=moxunit_util_stack2str(content.stack);
            stack_str=moxunit_util_escape_xml(raw_stack_str);

            infix=sprintf('>\n  <%s message="%s">%s</%s>',...
                        outcome,message,stack_str,outcome);
        end

        suffix=sprintf('\n</testcase>');
    end

    str=sprintf('%s%s%s',prefix,infix,suffix);

function s=get_classname(test_)
    location=getLocation(test_);
    [pth,file_name]=fileparts(location);

    s=sprintf('%s',file_name);


function outStruct = mergeStructures(s1, s2)
% outStruct = mergeStructures(firstStruct, secondStruct)
%
% returns a structure with fields from both input structures.
% If both input structures have the same fields, the s2
% fields overwrite the s1 fields.
%
% ras, 09/06/2005, imported into mrVista 2.0
% ras, 07/21/2007, deals with struct arrays and empty structs.

% if s1 is empty, our job is easy: we can overwrite it with s2:
if isempty(s1)
	outStruct = s2;
	return
end

% deal with different sizes of structures:
% we can do this if s2 is a struct array, but not if
% s1 is (for now)
if length(s1) > 1
	error('firstStruct needs to be length 1 or empty.')
end

if length(s2) > 1
	% we allow only for up to 2 dimensions here
	for i = 1:size(s2, 1)
		for j = 1:size(s2, 2)
			outStruct(i,j) = mergeStructures(s1, s2(i,j));
		end
	end
	return
end

%% core part of merge:
% make sure all fields which belong to either s1 or s2 are assigned to
% outStruct:
outStruct = s1;

if ~isempty(s2)
	fieldNames = fieldnames(s2);
	for i = 1:length(fieldNames)
		f = fieldNames{i};
		outStruct.(f) = s2.(f);
	end
end

return


function db_insert_blob(tablename, fieldname, s)

% DB_INSERT_BLOB converts a Matlab variable of arbitrary type into
% a binary stream and inserts this stream into a binary blob in the
% database table.
%
% Use as
%   db_insert_blob(tablename, fieldname, s)

% Copyright (C) 2007, Robert Oostenveld
%
% $Log: db_insert_blob.m,v $
% Revision 1.1  2007/11/07 10:50:45  roboos
% created helper functions for easy access to a MySQL database table using a structure for representing the data
%

format = 'serialize';
cmd    = sprintf('insert into %s ( %s ) values ( "{M}" )', tablename, fieldname);
blob   = struct2msg(s, format);

% execute the query, this requires the mym version of the mysql mex file
mysql(str, blob);


function idx = cellregexp(cell_in,regexpstring)

    idx = logical(1 - cellfun(@isempty, regexp(cell_in, regexpstring)));
end


%  Insert text from a file
%
%  ::
%
%     document.include('option_name',option_value);
%
%  Args:
%
%     varargin: arguments need to come in pairs
%
%        - **filename** : name of the file to be included
%
%


function taser_about( )
%TASER_ABOUT Brings up the "About" window in the TASER menu
%
% Author: Tim Cox, NRL, and Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

fig_hand=figure('Name', 'Taser: About', 'NumberTitle', 'off', ...
    'MenuBar', 'none', 'Toolbar', 'none');

% Draw title
text_ax = axes('Parent',fig_hand,'Position',[0.05 .7 0.5 .3]);
axis(text_ax, 'off');
title_text = text(.5, 0.6, 'TASER', 'FontSize', 20, 'FontWeight', 'bold', 'FontAngle', 'italic', 'HorizontalAlignment', 'center', 'Parent', text_ax);
if isdeployed()&&exist('taser_compile_date','file')
    set(title_text,'Position',[.5 .7]); % Make room for version text
    text(.5, 0.4, ['Version ' taser_compile_date], 'FontSize', 12, 'HorizontalAlignment', 'center', 'Parent', text_ax)
end
text(.5, 0.2, 'Naval Research Laboratory', 'FontSize', 10, 'HorizontalAlignment', 'center', 'Parent', text_ax)
text(.5, 0.05, 'National Geospatial-Intelligence Agency', 'FontSize', 10, 'HorizontalAlignment', 'center', 'Parent', text_ax)

% Draw scroll bar with text info
license_ui = uicontrol(fig_hand, 'Style', 'edit',...
    'Units', 'normalized', ...
    'Position', [.05 .05 .55 .6], ...
    'min',0,'max',5,... % No effect, except max must be greater than min
    'HorizontalAlign','left',...
    'BackgroundColor',[1 1 1],...
    'enable','inactive');
scrollbar_string = '';
credits_path = fullfile(fileparts(mfilename('fullpath')),'taser_credits.txt');
if exist(credits_path,'file')
    fid = fopen(credits_path);
    scrollbar_string = fread(fid,Inf,'*char').';
    fclose(fid);
end
% Assumes this file is in Tools/MatlabWorkbench/about path of MATLAB SAR Toolbox
license_path = fullfile([fileparts(mfilename('fullpath')) filesep '..' filesep '..' filesep '..'],'license.txt');
if exist(license_path,'file')
    fid = fopen(license_path);
    fgetl(fid);
    license_strings = fread(fid,Inf,'*char').';
    fclose(fid);
    % Concatenate so that uicontrol will wrap properly.
    license_strings = regexprep(license_strings, '\r\n(?!\r\n)(?<!\r\n\r\n)', ''); % Single occurence only
    scrollbar_string = [scrollbar_string sprintf('\r\n\r\nLicense:\r\n\r\n') license_strings];
end
set(license_ui,'String',scrollbar_string);

% Draw seals
nga_ax = axes('Parent', fig_hand,'Position', [.6 .55 .4 .4]);
nrl_ax = axes('Parent', fig_hand,'Position', [.6 .05 .4 .4]);
image(imread(fullfile(fileparts(mfilename('fullpath')),'NGA_Seal.png'),...
    'BackgroundColor',get(fig_hand,'Color')),'Parent',nga_ax);
image(imread(fullfile(fileparts(mfilename('fullpath')),'NRL_Seal.png'),...
    'BackgroundColor',get(fig_hand,'Color')),'Parent',nrl_ax);
set([nga_ax nrl_ax], 'DataAspectRatio', [1 1 1]);
axis([nga_ax nrl_ax], 'off');

end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function Callbacks_glottal_pulse_GUI25(f,C)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x=C{1,1};
y=C{1,2};
a=C{1,3};
b=C{1,4};
u=C{1,5};
v=C{1,6};
m=C{1,7};
n=C{1,8};
lengthbutton=C{1,9};
widthbutton=C{1,10};
enterType=C{1,11};
enterString=C{1,12};
enterLabel=C{1,13};
noPanels=C{1,14};
noGraphicPanels=C{1,15};
noButtons=C{1,16};
labelDist=C{1,17};%distance that the label is below the button
noTitles=C{1,18};
buttonTextSize=C{1,19};
labelTextSize=C{1,20};
textboxFont=C{1,21};
textboxString=C{1,22};
textboxWeight=C{1,23};
textboxAngle=C{1,24};
labelHeight=C{1,25};
fileName=C{1,26};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%PANELS
for j=0:noPanels-1
uipanel('Parent',f,...
'Units','Normalized',...
'Position',[x(1+4*j) y(1+4*j) x(2+4*j)-x(1+4*j) y(3+4*j)-y(2+4*j)]);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%GRAPHIC PANELS
for i=0:noGraphicPanels-1
switch (i+1)
case 1
graphicPanel1 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 2
graphicPanel2 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 3
graphicPanel3 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 4
graphicPanel4 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
case 5
graphicPanel5 = axes('parent',f,...
'Units','Normalized',...
'Position',[a(1+4*i) b(1+4*i) a(2+4*i)-a(1+4*i) b(3+4*i)-b(2+4*i)],...
'GridLineStyle','--');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%TITLE BOXES
for k=0:noTitles-1
switch (k+1)
case 1
titleBox1 = uicontrol('parent',f,...
'Units','Normalized',...
'Position',[u(1+4*k) v(1+4*k) u(2+4*k)-u(1+4*k) v(3+4*k)-v(2+4*k)],...
'Style','text',...
'FontSize',textboxFont{k+1},...
'String',textboxString(k+1),...
'FontWeight',textboxWeight{k+1},...
'FontAngle',textboxAngle{k+1});
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%BUTTONS
for i=0:(noButtons-1)
enterColor='w';
if strcmp(enterType{i+1},'pushbutton')==1 ||strcmp(enterType{i+1},'text')==1
enterColor='default';
end
if (strcmp(enterLabel{1,(i+1)},'')==0 &&...
        strcmp(enterLabel{1,(i+1)},'...')==0) %i.e. there is a label
%creating a label for some buttons
uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i)-labelDist-labelHeight(i+1) ...
(m(2+2*i)-m(1+2*i)) labelHeight(i+1)],...
'Style','text',...
'String',enterLabel{i+1},...
'FontSize', labelTextSize(i+1),...
'HorizontalAlignment','center');
end
switch (i+1)
case 1
button1=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button1Callback);
case 2
button2=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button2Callback);
case 3
button3=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button3Callback);
case 4
button4=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button4Callback);
case 5
button5=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button5Callback);
case 6
button6=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button6Callback);
case 7
button7=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button7Callback);
case 8
button8=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button8Callback);
case 9
button9=uicontrol('Parent',f,...
'Units','Normalized',...
'Position',[m(1+2*i) n(1+2*i) (m(2+2*i)-m(1+2*i)) (n(2+2*i)-n(1+2*i))],...
'Style',enterType{i+1},...
'String',enterString{i+1},...
'FontSize', buttonTextSize(1+i),...
'BackgroundColor',enterColor,...
'HorizontalAlignment','center',...
'Callback',@button9Callback);
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%USER CODE FOR THE VARIABLES AND CALLBACKS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialize Variables
alpha1=25;
alpha2=10;
period=100;
nfft=1024;
fs=10000;
ivowel=1;
fsd=10000;
imp_train=[];
pulse_train=[];
zout=[];
g=[];
vowels='IY';

% Name the GUI
    set(f,'Name','glottal_pulse_GUI');

% CALLBACKS
% Callback for button1 -- alpha1, editable button value for glottal pulse
% opening cycle (in %)
 function button1Callback(h,eventdata)
     alpha1=str2num(get(button1,'string'))/100;
     if alpha1 < 0
         waitfor(msgbox('alpha1 must lie between 0 and 100'));
     elseif alpha1 > 1
         waitfor(msgbox('alpha1 must lie between 0 and 100'));
     end
 end

% Callback for button2 -- alpha2, editable button value for glottal pulse
% closing cycle (in %)
 function button2Callback(h,eventdata)
     alpha2=str2num(get(button2,'string'))/100;
     if alpha2 < 0
         waitfor(msgbox('alpha2 must lie between 0 and 100'));
     elseif (alpha2 > 1)
         waitfor(msgbox('alpha2 must lie between 0 and 100'));
     end
 end

% Callback for button3 -- period, editable button duration of pitch
% period (in samples) at fs=10000 Hz
 function button3Callback(h,eventdata)
     period=str2num(get(button3,'string'));
     if period < 10
         waitfor(msgbox('pitch period must lie between 10 and 250 samples'));
     elseif period > 250
         waitfor(msgbox('pitch period must lie between 10 and 250 samples'));
     end
 end

% Callback for button4 -- ivowel: editable button for vowel sound impulse
% response to be convolved with glottal pulse
 function button4Callback(h,eventdata)
     ivowel=get(button4,'val');
 end

% Callback for button9 -- Generate Excitation -- both Rosenberg pulse and
% periodic extension at designated pitch period
    function button9Callback(h,eventdata)
        button3Callback(h,eventdata);
        button4Callback(h,eventdata);

     alpha1=str2num(get(button1,'string'))/100;
     alpha2=str2num(get(button2,'string'))/100;

% form rosenberg glottal pulse, g
    n1=round(period*alpha1);
    n2=round(period*alpha2);
    g=[];
    x1=0:n1;
    g=[g 0.5*(1-cos(pi*x1/n1))];
    x2=1:n2;
    g=[g cos(pi*x2/(2*n2))];
    g=[g zeros(1,period-length(g))];

% plot g as a time domain signal over a single period in graphics Panel 1
    reset(graphicPanel2);
    axes(graphicPanel2);

    x=0:length(g)-1;
    plot(x,g,'b','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp);
    ylabel('Pulse Amplitude');axis tight; grid on;
    s1=sprintf('Rosenberg pulse -- period: %d,',period);
    s2=sprintf(' alpha1, alpha2: %6.3f, %6.3f ',alpha1,alpha2);
    stitle=strcat(s1,s2);
    legend('Rosenberg Pulse');

% display glottal pulse parameters in titleBox1
    set(titleBox1,'String',stitle);
    set(titleBox1,'FontSize',25);

% plot log magnitude spectrum of glottal pulse, g, in graphics Panel 1
    ge=[g zeros(1,nfft-length(g))];
    gs=20*log10(abs(fft(ge)));
    freq=0:fs/nfft:fs/2;
    x2=[0 fs/2];
    s2=[0 0];

    reset(graphicPanel1);
    axes(graphicPanel1);
    plot(freq,gs(1:nfft/2+1),'r','LineWidth',2);
    hold on;
    plot(x2,s2,'g','LineWidth',2);
    xlabel('Frequency in Hz'),ylabel('Log Magnitude (dB)');
    axis tight; grid on;legend('Rosenberg Pulse Spectrum');

% play out periodic pulse train of impulses spaced period samples apart,
% and of total length of fsd=10000 samples (fsd defined in list of
% variables at beginning of Callbacks)
    imp_train=zeros(1,fsd);
    imp_train(1:period:fsd)=1;

 % display impulse train for 1000 samples on Graphics Panel 5
    reset(graphicPanel5);
    axes(graphicPanel5);
    plot(0:1000,imp_train(1:1001),'r','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp),ylabel('Value'),axis tight, grid on; legend('Periodic Impulses');

% generate excitation pulses using Rosenberg pulse
    pulse_train=conv(g,imp_train);

% display glottal pulse train for 1000 samples on Graphics Panel 4
    reset(graphicPanel4);
    axes(graphicPanel4);
    plot(0:1000,pulse_train(1:1001),'b','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp),ylabel('Value'),axis tight, grid on; legend('Glottal Pulses');

% load vowel info (formants and bandwidths)
% load 'vowels_fmts_bw.mat'
    str=load('vowels_fmts_bw.mat');
    vowels=str.vowels;
    formants=str.formants;
    bandwidths=str.bandwidths;

% generate vowel impulse response
    fmts=formants(ivowel,:);
    fmts=[fmts 4500];
    yout=vowel_ir(fmts,bandwidths,fsd);

% convolve vowel impulse response with excitation
    zout=conv(yout,pulse_train);

% display periodic vowel sequence for 1000 samples on Graphics Panel 3
    reset(graphicPanel3);
    axes(graphicPanel3);
    plot(0:1000,zout(1:1001),'k','LineWidth',2);
    xpp=['Time in Samples; fs=',num2str(fs),' samples/second'];
    xlabel(xpp),ylabel('Value'),axis tight, grid on;

    xleg=['Vowel Response:',vowels(ivowel,:),'  Period:',num2str(period)];
    legend(xleg);
    end

% Callback for button5 -- Play Periodic Impulses
    function button5Callback(h,eventdata)
    soundsc(imp_train,fsd);
    end

% Callback for button6 -- Play Glottal Pulses
    function button6Callback(h,eventdata)
    soundsc(pulse_train,fsd);
    end

% Callback for button7 -- Play Vowel Excited by Glottal Pulses
    function button7Callback(h,eventdata)
    soundsc(zout,fsd);
    end

% Callback for button8 -- close GUI
 function button8Callback(h,eventdata)
     close(gcf);
 end
end


function title = p00_title ( problem, option )

%*****************************************************************************80
%
%% P00_TITLE sets the title for any problem.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the problem index.
%
%    Input, integer OPTION, the option index.
%
%    Output, string TITLE, the title of the problem.
%    TITLE will never be longer than 80 characters.
%
  if (  problem == 1 )
    title = p01_title ( option );
  elseif ( problem == 2 )
    title = p02_title ( option );
  elseif ( problem == 3 )
    title = p03_title ( option );
  elseif ( problem == 4 )
    title = p04_title ( option );
  elseif ( problem == 5 )
    title = p05_title ( option );
  elseif ( problem == 6 )
    title = p06_title ( option );
  elseif ( problem == 7 )
    title = p07_title ( option );
  elseif ( problem == 8 )
    title = p08_title ( option );
  elseif ( problem == 9 )
    title = p09_title ( option );
  elseif ( problem == 10 )
    title = p10_title ( option );
  elseif ( problem == 11 )
    title = p11_title ( option );
  elseif ( problem == 12 )
    title = p12_title ( option );
  elseif ( problem == 13 )
    title = p13_title ( option );
  elseif ( problem == 14 )
    title = p14_title ( option );
  elseif ( problem == 15 )
    title = p15_title ( option );
  elseif ( problem == 16 )
    title = p16_title ( option );
  elseif ( problem == 17 )
    title = p17_title ( option );
  elseif ( problem == 18 )
    title = p18_title ( option );
  elseif ( problem == 19 )
    title = p19_title ( option );
  elseif ( problem == 20 )
    title = p20_title ( option );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_TITLE - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized problem number = %d\n', problem );
    error ( 'P00_TITLE - Fatal error!' );
  end

  return
end


%APPEND_PDFS Appends/concatenates multiple PDF files
%
% Example:
%   append_pdfs(output, input1, input2, ...)
%   append_pdfs(output, input_list{:})
%   append_pdfs test.pdf temp1.pdf temp2.pdf
%
% This function appends multiple PDF files to an existing PDF file, or
% concatenates them into a PDF file if the output file doesn't yet exist.
%
% This function requires that you have ghostscript installed on your
% system. Ghostscript can be downloaded from: http://www.ghostscript.com
%
% IN:
%    output - string of output file name (including the extension, .pdf).
%             If it exists it is appended to; if not, it is created.
%    input1 - string of an input file name (including the extension, .pdf).
%             All input files are appended in order.
%    input_list - cell array list of input file name strings. All input
%                 files are appended in order.

% Copyright: Oliver Woodford, 2011

% Thanks to Reinhard Knoll for pointing out that appending multiple pdfs in
% one go is much faster than appending them one at a time.

% Thanks to Michael Teo for reporting the issue of a too long command line.
% Issue resolved on 5/5/2011, by passing gs a command file.

% Thanks to Martin Wittmann for pointing out the quality issue when
% appending multiple bitmaps.
% Issue resolved (to best of my ability) 1/6/2011, using the prepress
% setting

function append_pdfs(varargin)
% Are we appending or creating a new file
append = exist(varargin{1}, 'file') == 2;
if append
    output = [tempname '.pdf'];
else
    output = varargin{1};
    varargin = varargin(2:end);
end
% Create the command file
cmdfile = [tempname '.txt'];
fh = fopen(cmdfile, 'w');
fprintf(fh, '-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="%s" -f', output);
fprintf(fh, ' "%s"', varargin{:});
fclose(fh);
% Call ghostscript
ghostscript(['@"' cmdfile '"']);
% Delete the command file
delete(cmdfile);
% Rename the file if needed
if append
    movefile(output, varargin{1});
end


function [fileNameSourceArray, fileNameTargetArray, ...
    fileNameSourceMovedArray, fileNameTargetMovedArray] = tapas_uniqc_move_with_hdr(...
    fileNameSourceArray, fileNameTargetArray)
% Moves given files; for .nii (nifti-) files, also moves .mat-header,
% if existing; for given .img (analyze) files, also moves .hdr-header
%
%   [fileNameSourceArray, fileNameTargetArray] = tapas_uniqc_move_with_hdr(...
%    fileNameSourceArray, fileNameTargetArray)
%
% IN
%   fileNameSourceArray   cell of filenames to be moved (source)
%   fileNameTargetArray   cell of filenames to be moved to (targets)
% OUT
%   fileNameSourceArray   cell of filenames that were tried to be moved
%                   (includes   .mat files corresponding to .nii and
%                               .hdr files corresponding to .img)
%   fileNameSourceMovedArray   cell of source filenames that were actually moved
%                   (includes   .mat files corresponding to .nii and
%                               .hdr files corresponding to .img)
%   fileNameTargetMovedArray   cell of target filenames that were actually moved
%                   (includes   .mat files corresponding to .nii and
%                               .hdr files corresponding to .img)
%
% EXAMPLE
%   tapas_uniqc_move_with_hdr('from.nii', 'to.nii')
%
%   See also tapas_uniqc_delete_with_hdr copy_with_mat

% Author:   Saskia Klein & Lars Kasper
% Created:  2014-07-08
% Copyright (C) 2014 Institute for Biomedical Engineering
%                    University of Zurich and ETH Zurich
%
% This file is part of the TAPAS UniQC Toolbox, which is released
% under the terms of the GNU General Public Licence (GPL), version 3.
% You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version).
% For further details, see the file COPYING or
%  <http://www.gnu.org/licenses/>.
%

doMove = true;
[fileNameSourceArray, fileNameTargetArray, ...
    fileNameSourceMovedArray, fileNameTargetMovedArray] = tapas_uniqc_copy_with_hdr(...
    fileNameSourceArray, fileNameTargetArray, doMove);


function writefile(DS, filename)
%WRITEFILE Writes a dataset to a DSDML file
%
% $ Syntax $
%   - writefile(DS, filename)
%
% $ Arguments $
%   - DS:           the dataset object
%   - filename:     the name of the file to be written to
%
% $ Description $
%   - writefile(DS, filename) writes a dataset object to the DSDML file
%     with the filename specified.
%
% $ History $
%   - Created by Dahua Lin on Jul 23rd, 2006
%

import com.mathworks.xml.*;

%% Initialize the document

xdoc = XMLUtils.createDocument('DataSet');
xdoc.setVersion('1.0');
xdoc.setEncoding('UTF-8');

S = struct(DS);

%% Set headers

docelem = xdoc.getDocumentElement;
docelem.setAttribute('version', char(S.version));
docelem.setAttribute('name', char(S.name));
docelem.setAttribute('unit', char(S.unittype));
docelem.setAttribute('format', char(S.format));
if ~isempty(S.author)
    docelem.setAttribute('author', char(S.author));
end
if ~isempty(S.description)
    docelem.setAttribute('description', char(S.description));
end
if ~isempty(S.attribs)
    attrnames = fieldnames(S.attribs);
    nattrs = length(attrnames);
    for i = 1 : nattrs
        docelem.setAttribute(attrnames{i}, S.attribs.(attrnames{i}));
    end
end

%% Create unit nodes

switch S.unittype
    case 'Sample'
        n = length(S.units);
        for i = 1 : n
            docelem.appendChild(CreateSampleNode(xdoc, S.units(i)));
        end

    case 'SampleGroup'
        n = length(S.units);
        for i = 1 : n
            docelem.appendChild(CreateSampleGroupNode(xdoc, S.units(i)));
        end

    otherwise
        error('dsdml:invalidutype', ...
            'Invalid unit type %s', DS.unittype);
end

%% Write document
xmlwrite(filename, xdoc);

%% Node Creating functions

function sampleNode = CreateSampleNode(xdoc, sample)

sampleNode = xdoc.createElement('Sample');
sampleNode.setAttribute('class_id', int2str(sample.class_id));
if ~isempty(sample.filename)
    sampleNode.setAttribute('filename', sample.filename);
end
if ~isempty(sample.attribs)
    attrnames = fieldnames(sample.attribs);
    nattrs = length(attrnames);
    for i = 1 : nattrs
        sampleNode.setAttribute(attrnames{i}, sample.attribs.(attrnames{i}));
    end
end

function groupNode = CreateSampleGroupNode(xdoc, grp)

groupNode = xdoc.createElement('SampleGroup');
groupNode.setAttribute('class_id', int2str(grp.class_id));
if ~isempty(grp.attribs)
    attrnames = fieldnames(grp.attribs);
    nattrs = length(attrnames);
    for i = 1 : nattrs
        sampleNode.setAttribute(attrnames{i}, grp.attribs.(attrnames{i}));
    end
end
nsamples = length(grp.samples);
for i = 1 : nsamples
    groupNode.appendChild(CreateSampleNode(xdoc, grp.samples(i)));
end


function obj = iatgetDemoObject
% IATGETDEMOOBJECT Returns the object used by the motion detection demo.
%
%    IATGETDEMOOBJECT finds the VIDEOINPUT object used by the motion detection
%    demo and returns it.
%
%    See also VIDEOINPUT.

% DT 4/2004
% Copyright 2004 The MathWorks, Inc.

% Look for existing objects created by the demo.
obj = imaqfind('Tag', 'Motion Detection Object');

if isempty(obj)
    obj = localCreateObj;
    stop(obj)
    % Clear the callbacks.
    obj.TimerFcn = '';
    obj.FramesAcquiredFcn = '';
    obj.StartFcn = '';
    obj.StopFcn = '';
    obj.TriggerFcn = '';

    % Configure the object for manual trigger so that GETSNAPSHOT returns
    % quicker.
    triggerconfig(obj, 'Manual');

    % Configure the object to return YCbCr data which the demo requires.
    set(obj, 'ReturnedColorSpace', 'YCbCr');

    % Save the video resolution in the base workspace.
    videoRes = obj.ROIPosition;
    assignin('base', 'videoRes', [videoRes(4) videoRes(3)]);
else
    obj = obj{1};

    % Save the video resolution in the base workspace.
    videoRes = obj.ROIPosition;
    assignin('base', 'videoRes', [videoRes(4) videoRes(3)]);
end

function obj = localCreateObj
% localCreateObj searches for the first supported device with a
% default format.  Once found, it creates an object for that device and
% returns the object to the calling function.  Some devices do not have
% default formats and can not be used since the demo doesn't provide a
% method of specifying camera files.

% Determine the available adaptors.
info = imaqhwinfo;

adaptorName = [];
adaptorID = [];
adaptorIndex = 1;

% Search through all of the installed adaptors until an available adaptor
% with hardware that has a default format is found.
while (isempty(adaptorName) && isempty(adaptorID))

    if (adaptorIndex > length(info.InstalledAdaptors))
        error('imaq:motiondetection:nohardware', 'No hardware compatible with the motion detection demo was found.');
    end

    % Get information on the current adaptor.
    curAdaptor = info.InstalledAdaptors{adaptorIndex};
    adaptorInfo = imaqhwinfo(curAdaptor);

    % For the current adaptor, search through each installed device looking
    % for a device that has a default format.
    idIndex = 1;
    while (isempty(adaptorID) && (idIndex <= length(adaptorInfo.DeviceIDs)))
        curID = adaptorInfo.DeviceIDs{idIndex};
        if ~isempty(adaptorInfo.DeviceInfo(idIndex).DefaultFormat)
            adaptorName = curAdaptor;
            adaptorID = curID;
        end

        % If the current device doesn't have a default format check the
        % next one.
        idIndex = idIndex + 1;
    end

    % Check the next adaptor.
    adaptorIndex = adaptorIndex + 1;
end

% Create the object.
obj = videoinput(adaptorName, adaptorID);

% Configure the object's tag so that it can be found later by using
% IMAQFIND.
set(obj, 'Tag', 'Motion Detection Object');

% End of localCreateObj


function [scanArraySuperior, isCompress, isRemote] = getScanArraySuperior(scanIndex, planC)
%"getScanArray"
%   Returns the scanArray stored in a planC, in slot scanIndex.  The last
%   returned scanArray is cached in a persistent variable to avoid delays
%   in loading remotely stored or compressed scans.
%
%   If a scan array is compressed it is decompressed before being returned.
%
%   If planC is not passed in, the global planC is used.
%
%   If scanIndex is not valid, or if no valid planC can be found an error is
%   returned.
%
%   isCompress and isRemote are booleans to let the calling function know
%   if the scanArray was compressed and/or remote.
%
%   JRA 10/14/04
%
%Usage:
%   function scanArray = getScanArray(scanIndex, planC)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
% CERR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
% without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with CERR.  If not, see <http://www.gnu.org/licenses/>.

persistent lastScanStruct;
persistent lastScanArray;
persistent isLastScanCompressed;
persistent isLastScanRemote;

%Check if a scanStruct, not a scanIndex was passed.
if isstruct(scanIndex) && isfield(scanIndex, 'scanArray')

    scanStruct = scanIndex(1);

else
    %An index was passed, extract the scanStruct.
	if ~exist('planC','var')
        global planC
	end

	if ~iscell(planC)
        error('Cannot get scan. PlanC is not a valid cell array.');
	end

	indexS = planC{end};

	if scanIndex > length(planC{indexS.scan}) || scanIndex < 1
        error('Cannot get scan.  Requested scanIndex scan not exist.')
	end

    scanStruct = planC{indexS.scan}(scanIndex);

end

scanArraySuperior = scanStruct.scanArraySuperior;

%If remote or compressed, and struct is same as last time, return cached array.
if (isCompressed(scanArraySuperior) || ...
        ~isLocal(scanArraySuperior)) && isequal(scanStruct, lastScanStruct)
    scanArraySuperior = lastScanArray;
    isCompress = isLastScanCompressed;
    isRemote = isLastScanRemote;
    return;
%If remote or compressed and NOT the same as last time, clear cache.
elseif (isCompressed(scanArraySuperior) || ...
        ~isLocal(scanArraySuperior)) && ~isequal(scanStruct, lastScanStruct)
	lastScanArray           = [];
	lastScanStruct          = [];
	isLastScanCompressed    = [];
	isLastScanRemote        = [];
end

%To be output for calling function's use.
isCompress  = 0;
isRemote    = 0;

%Decompress and follow all file pointers until get to an array.
while isCompressed(scanArraySuperior) || ~isLocal(scanArraySuperior)
    if isCompressed(scanArraySuperior)
        scanArraySuperior   = decompress(scanArraySuperior);
        isCompress  = 1;
    elseif ~isLocal(scanArraySuperior)
        scanArraySuperior   = getRemoteVariable(scanArraySuperior);
        isRemote    = 1;
    end
end

lastScanArray           = scanArraySuperior;
lastScanStruct          = scanStruct;
isLastScanCompressed    = isCompress;
isLastScanRemote        = isRemote;

%temp


function [s] = getsubfield(s, f);

% GETSUBFIELD returns a field from a structure just like the standard
% Matlab GETFIELD function, except that you can also specify nested fields
% using a '.' in the fieldname. The nesting can be arbitrary deep.
%
% Use as
%   f = getsubfield(s, 'fieldname')
% or as
%   f = getsubfield(s, 'fieldname.subfieldname')
%
% See also GETFIELD, ISSUBFIELD, SETSUBFIELD

% Copyright (C) 2005, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.ru.nl/neuroimaging/fieldtrip
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id: getsubfield.m 2885 2011-02-16 09:41:58Z roboos $

if ~ischar(f)
  error('incorrect input argument for fieldname');
end

t = {};
while (1)
  [t{end+1}, f] = strtok(f, '.');
  if isempty(f)
    break
  end
end
s = getfield(s, t{:});


classdef AnnotationLoader < Algorithm
    properties (Access = public)
        fileName;
    end

    properties (Access = private)
        annotationsMap;
    end

    properties (Dependent)
        annotations;
    end

    methods
        function set.annotations(obj,annotations)
            obj.createAnnotationsMap(annotations);
        end
    end

    methods (Access = public)
        function obj = AnnotationLoader(fileName,annotations)
            if nargin > 0
                obj.fileName = fileName;
                if nargin > 1
                    obj.createAnnotationsMap(annotations);
                end
            end

            obj.name = 'annotationsLoader';
            obj.inputPort = DataType.kNull;
            obj.outputPort = DataType.kAnnotation;
        end

        function annotation = compute(obj,~)
            annotationFileName = Helper.RemoveFileExtension(obj.fileName);
            if isempty(obj.annotationsMap)
                defaultLabeling = DataLoader.LoadDefaultLabeling();
                annotation = DataLoader.LoadAnnotationSetFullPath(obj.fileName,defaultLabeling);
            else
                annotation = obj.annotationsMap(annotationFileName);
            end
        end

        function str = toString(obj)
            str = sprintf('%s_%s',obj.name, obj.fileName);
        end

        function fileNameProperty = getEditableProperties(obj)
            fileNameProperty = Property('fileName',obj.fileName);
        end
    end

    methods (Access = private)
        function createAnnotationsMap(obj,annotations)
            nAnnotations = length(annotations);

            annotationCells = cell(1,nAnnotations);
            annotationNames = cell(1,nAnnotations);

            for i = 1 : nAnnotations
                annotation = annotations(i);
                annotationName = annotation.fileName;
                annotationNames{i} = Helper.RemoveAnnotationsExtension(annotationName);
                annotationCells{i} = AnnotationSet(annotation.eventAnnotations,annotation.rangeAnnotations);
            end
            obj.annotationsMap = containers.Map(annotationNames,annotationCells);
        end
    end
end


function display_legend(plot_obj)
% Displays the legend on the plot.  Call this function after all
% curves and points have been plotted.  The only function that
% should be called after this one is the one for saving the plot.
% Legend entries for curves are stored with add_legend_entry.

if length(plot_obj.legend_strings) > 0
    figure(plot_obj.fh)
    legend(plot_obj.handles_vec,plot_obj.legend_strings)
end
end


function datapt = ma_GACentralBodyTasks(stateLogEntry, subTask, celBodyData)
%ma_GACentralBodyTasks Summary of this function goes here
%   Detailed explanation goes here

    switch subTask
        case 'CB_ID'
            datapt = stateLogEntry(8);
    end
end


function [str, tag, cind, ccnt] = gencode_item(item, tag, tagctx, stoptag, tropts)

% function [str, tag, cind, ccnt] = gencode_item(item, tag, tagctx, stoptag, tropts)
% Generate code to recreate a cfg_(m)choice item. This code does not deal with
% arrays of cfg_items, such a configuration should not exist with the
% current definition of a configuration tree.
%
% Traversal options
% struct with fields
% stopspec - match spec to stop forced setting of eflag
% dflag    - if set to true, don't create code for .val children (code
%            for .val field is created)
% clvl     - current level in tree
% mlvl     - maximum level to force settings - range 1 (top level only) to
%            Inf (all levels)
% cnt      - item count - used for unique tags
% mcnt     - (not evaluated here)
%
% This function is identical for cfg_choice and cfg_mchoice classes.
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: gencode_item.m 5678 2013-10-11 14:58:04Z volkmar $

rev = '$Rev: 5678 $'; %#ok

%% Parent object
% Generate generic object
itropts = tropts;
istoptag = stoptag;
if tropts.dflag
    % don't descend into .val tree of cfg_item
    itropts.clvl = 1;
    itropts.mlvl = 1;
    istoptag     = '';
end;
[str, tag, cind, ccnt] = gencode_item(item.cfg_item, tag, tagctx, istoptag, itropts);
tagctx = [tagctx {tag}];
% Check whether to generate code - ccnt == 0 means that generic object did
% not return code
if (tropts.clvl > tropts.mlvl || (~isempty(tropts.stopspec) && match(item, tropts.stopspec))) || ccnt == 0
    str = {};
    cind = [];
    ccnt = 0;
    return;
end;
% Reclassify generic object
str{cind} = sprintf('%s         = %s;', tag, class(item));
%% Values
% Generate values field
if numel(item.values) > 0
    % Traverse values{:} tree
    cstr = {};
    % Update clvl
    ctropts = tropts;
    ctropts.clvl = ctropts.clvl + 1;
    ctropts.cnt  = ctropts.cnt + ccnt;
    ctag = cell(size(item.values));
    for k = 1:numel(item.values)
        % tags are used as variable names and need to be unique in the
        % context of this .values tag. This includes the item's tag itself
        % and the tags of its immediate children.
        ctag{k} = genvarname(subsref(item.values{k}, substruct('.','tag')), ...
                             tagctx);
        [ccstr, ctag{k}, ccind, cccnt] = gencode_item(item.values{k}, ctag{k}, ...
                                              tagctx, stoptag, ctropts);
        tagctx = [tagctx ctag(k)];
        if ~isempty(ccstr)
            % Child has returned code
            cstr = [cstr(:)' ccstr(:)'];
            ctropts.cnt = ctropts.cnt + cccnt;
            ccnt = ccnt + cccnt;
        end;
    end;
    % Update position of class definition
    cind = cind+numel(cstr);
    % Prepend code of children
    str = [cstr(:)' str(:)'];
    str{end+1} = sprintf('%s.values  = {%s};', tag, sprintf('%s ', ctag{:}));
end;