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

% Last Modified by GUIDE v2.5 11-Apr-2018 18:59:36

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @plot_controller_OpeningFcn, ...
    'gui_OutputFcn',  @plot_controller_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 plot_controller is made visible.
function plot_controller_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 plot_controller (see VARARGIN)

% Choose default command line output for plot_controller
handles.output = hObject;
if ~sum(size(varargin))
    error('OpenBMI: No data input');
elseif ~isfield(varargin{1},'x')
    error('OpenBMI: Data must have fields named ''x''');
else
    handles.data=varargin{1};
end
% Update handles structure
guidata(hObject, handles);
initialize_gui(hObject, handles, false);
% UIWAIT makes plot_controller wait for user response (see UIRESUME)
% uiwait(handles.figure1);

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

% Get default command line output from handles structure
varargout{1} = handles.output;

function initialize_gui(hObject, handles, isreset)
% If the metricdata field is present and the reset flag is false, it means
% we are we are just re-initializing a GUI by calling it from the cmd line
% while it is up. So, bail out as we dont want to reset the data.
% set(handles.time_seg_start, 'String', handles.data.ival(1));
% set(handles.time_seg_end, 'String', handles.data.ival(end));
set(handles.time_seg, 'String', sprintf('%d ~ %d', handles.data.ival(1), handles.data.ival(end)));
set(handles.sampling_rate,'String',handles.data.fs);
set(handles.num_class,'String',size(handles.data.class, 1));
set(handles.chan_num,'String',length(handles.data.chan));

chan=handles.data.chan(1);
for i=2:length(handles.data.chan)
    chan=strcat(chan,{', '},handles.data.chan(i));
end
set(handles.chan_info,'String',chan);

% Update handles structure
guidata(hObject, handles);
RESET(hObject,handles);

function RESET(hObject, handles, isreset)
% handles     structure with handles and user data (see GUIDATA)
% init        initialization
% Initialize plot type
set(handles.check_ERP,'Value',false);
set(handles.check_SSVEP, 'Value', false);
set(handles.check_MI,'Value',false);
set(handles.check_Topo,'Value',false);

% Initialize channel
handles.selected_chan={'Cz','Oz'};
str={};
for i=1:length(handles.selected_chan)
    str=[str; sprintf('%s',handles.selected_chan{i})];
end
% sprintf('%s',selected_chan{1});
set(handles.chan_listbox, 'String', str);

% Initialize interval
str ={};

ival = handles.data.ival([1, end]);
if ival(1) < 0, ival(1) = 0; end
selected_ival = linspace(ival(1), ival(2), 6);
handles.selected_ival=[selected_ival(1),selected_ival(2);...
    selected_ival(2),selected_ival(3);selected_ival(3),selected_ival(4);...
    selected_ival(4),selected_ival(5); selected_ival(5),selected_ival(6)];
ival=handles.selected_ival;
for i = 1:size(ival,1)
    str = [str; sprintf('%d ~ %d',ival(i,1), ival(i,2))];
end
set(handles.ival_listbox, 'String', str);

% Initialize num_class
str = {};
handles.selected_class=handles.data.class(:,2);

for i=1:length(handles.selected_class)
    str = [str; sprintf('%s', handles.selected_class{i})];
end

set(handles.inputToggle, 'Value', false);
set(handles.inputToggle, 'String', 'Direct');
set(handles.pop_range, 'Visible', 'on');
set(handles.maxTopo, 'Visible', 'off');
set(handles.minTopo, 'Visible', 'off');
set(handles.maxTopo, 'String', '0');
set(handles.minTopo, 'String', '0');
set(handles.tildeTopo, 'Visible', 'off');
set(handles.selToggle, 'Value', false);
set(handles.selToggle, 'String', 'Select');
set(handles.maxSelect, 'Enable', 'off');%
set(handles.minSelect, 'Enable', 'off');
set(handles.maxSelect, 'String', '0');
set(handles.minSelect, 'String', '0');
set(handles.ylimToggle, 'Value', false);
set(handles.ylimToggle, 'String', 'Select');
set(handles.maxYlim, 'Enable', 'off');
set(handles.minYlim, 'Enable', 'off');
set(handles.maxYlim, 'String', '0');
set(handles.minYlim, 'String', '0');

set(handles.class_listbox,'String', str);

set(handles.pop_range, 'Value', 1);
set(handles.pop_color, 'Value', 1);
set(handles.pop_quality, 'Value', 1);
set(handles.pop_orient, 'Value', 1);

% Initialize baseline
set(handles.baseline_start, 'String', string(handles.data.ival(1)));
set(handles.baseline_end, 'String', '0');

set(handles.note_txt,'String', {'';'';'Welcome'});

% Update handles structure
guidata(hObject, handles);

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

% --- Executes on button press in select_chan_btn.
function select_chan_btn_Callback(hObject, eventdata, handles)
% hObject    handle to select_chan_btn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
try
    [~,selected_chan]=GUI_selectChannels(handles.data.chan,handles.selected_chan);
    if length(selected_chan) > 5
        set(handles.note_txt, 'String', {'';'';'Don''t you think that selected channels are too many?'});
        return;
    else
        handles.selected_chan = selected_chan;
    end
catch
    return;
end
str={};
for i=1:length(handles.selected_chan)
    str=[str; sprintf('%s',handles.selected_chan{i})];
end
set(handles.chan_listbox, 'String', str);
set(handles.note_txt, 'String', {'';'';'Channels are selected'});

clear tmp;
% Update handles structure
guidata(hObject, handles);

% --- Executes on selection change in chan_listbox.
function chan_listbox_Callback(hObject, eventdata, handles)
% hObject    handle to chan_listbox (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 chan_listbox contents as cell array
%        contents{get(hObject,'Value')} returns selected item from chan_listbox

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

% Hint: listbox 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

% --- Executes on button press in select_ival_btn.
function select_ival_btn_Callback(hObject, eventdata, handles)
% hObject    handle to select_ival_btn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
try
    ival = select_interval(handles.selected_ival);
    if ~isempty(ival)&&(min(ival(:)) < handles.data.ival(1) || max(ival(:)) > handles.data.ival(end))
        set(handles.note_txt,'String', {'';'';'Please select intervals between segmented data'});
        return;
    end
    if ~isempty(ival)
        ival = sort(ival,2);
        [~, sort_] = sort(ival,1);
        ival = ival(sort_(:,1),:);
    else
        ival = handles.data.ival([1, end]);
%         if ival(1) < 0, ival(1) = 0; end % ival 0 to max -> min to max
    end
catch
    return;
end
handles.selected_ival=ival;
% str=sprintf('%d ~ %d',handles.selected_ival(1,1), handles.selected_ival(1,2));
% for i=2:length(handles.selected_ival(:,1))
%     str=sprintf('%s\n%d ~ %d',str,handles.selected_ival(i,1), handles.selected_ival(i,2));
% end
str = {};
for i = 1:size(ival,1)
    str = [str; sprintf('%d ~ %d', ival(i,1), ival(i,2))];
end

set(handles.ival_listbox, 'String',str);
set(handles.note_txt, 'String', {'';'';'Itervals are selected'});

% Update handles structure
guidata(hObject, handles);

% --- Executes on selection change in ival_listbox.
function ival_listbox_Callback(hObject, eventdata, handles)
% hObject    handle to ival_listbox (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 ival_listbox contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ival_listbox

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

% Hint: listbox 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

% --- Executes on button press in select_class_btn.
function select_class_btn_Callback(hObject, eventdata, handles)
% hObject    handle to select_class_btn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
try
    handles.selected_class=select_class(handles.data.class(:,2),handles.selected_class);
catch
    return;
end
str={};
for i=1:length(handles.selected_class)
    str=[str; sprintf('%s',handles.selected_class{i});];
end
set(handles.class_listbox, 'String', str);
clear tmp;
set(handles.note_txt, 'String', {'';'';'Classes are selected'});

% Update handles structure
guidata(hObject, handles);

% --- Executes on selection change in class_listbox.
function class_listbox_Callback(hObject, eventdata, handles)
% hObject    handle to class_listbox (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 class_listbox contents as cell array
%        contents{get(hObject,'Value')} returns selected item from class_listbox

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

% Hint: listbox 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

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

% Hint: get(hObject,'Value') returns toggle state of check_ERP

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

% Hint: get(hObject,'Value') returns toggle state of check_MI

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

%% Update baseline range
baseline=[str2double(get(handles.baseline_start,'String')), str2double(get(handles.baseline_end,'String'))];
if baseline(1) > baseline(2)
    baseline = flip(baseline);
    set(handles.baseline_start,'String', baseline(1));
    set(handles.baseline_end, 'String', baseline(2));
end
%% Select time
if get(handles.selToggle, 'Value')
    selTime = [str2double(get(handles.minSelect, 'String')), str2double(get(handles.maxSelect, 'String'))];
    if selTime(1) > selTime(2)
        selTime = flip(selTime);
        set(handles.minSelect, 'String', selTime(1));
        set(handles.maxSelect, 'String', selTime(2));
    end
else
    selTime = [handles.data.ival(1), handles.data.ival(end)];
end
%% Ylim range
if get(handles.ylimToggle, 'Value')
    ylimRange = [str2double(get(handles.minYlim, 'String')), str2double(get(handles.maxYlim, 'String'))];
else
    ylimRange = [];
end
%% Get plots
if get(handles.check_ERP,'Value'), ERPPlot = 'on'; else ERPPlot = 'off'; end
if get(handles.check_SSVEP,'Value'), SSVEPPlot = 'on'; else SSVEPPlot = 'off'; end
if get(handles.check_MI,'Value'), MIPlot = 'on'; else MIPlot = 'off'; end
if get(handles.check_Topo,'Value'), TopoPlot = 'on'; else TopoPlot = 'off'; end
if ~sum(ismember({ERPPlot, MIPlot, SSVEPPlot, TopoPlot}, 'on'))
    set(handles.note_txt, 'String', {'';'';'Choose at least one plot type'});
    return;
end
%% Patch
if get(handles.check_patch,'Value'), Patch = 'on'; else Patch = 'off'; end
%% Topography range
if get(handles.inputToggle, 'Value')
    p_range = [str2double(get(handles.minTopo, 'String')), str2double(get(handles.maxTopo, 'String'))];
    if p_range(1) > p_range(2)
        p_range = flip(p_range);
        set(handles.minTopo,'String', p_range(1));
        set(handles.maxTopo,'String', p_range(2));
    end
else
    switch get(handles.pop_range, 'Value')
        case 1
            p_range = 'sym';
        case 2
            p_range = '0tomax';
        case 3
            p_range = 'minto0';
        case 4
            p_range = 'mintomax';
        case 5
            p_range = 'mean';
    end
end
%% Topography color
switch get(handles.pop_color, 'Value')
    case 1
        cm = 'parula';
    case 2
        cm = 'jet';
    case 3
        cm = 'hsv';
end
%% Topography quality
switch get(handles.pop_quality, 'Value')
    case 1
        quality = 'high';
    case 2
        quality = 'medium';
    case 3
        quality = 'low';
end

%% Interval check
if sum(handles.selected_ival(:,1) < selTime(1)) || sum(handles.selected_ival(:,2) > selTime(2))
    set(handles.note_txt, 'String', {'';'';'Choose intervals between selected time'});
    return;
end

%% Start visualization
set(handles.note_txt, 'String', {'';'';'Wait for Drawing'}); drawnow;
try
    options = {'Interval', handles.selected_ival;...
        'Channels',handles.selected_chan;'Class',handles.selected_class;...
        'TimePlot', ERPPlot; 'TopoPlot', TopoPlot; 'ErdPlot', MIPlot;...
         'Range', p_range; 'baseline', baseline;...
        'Colormap', cm; 'Patch', Patch; 'Quality', quality; ...
        'SelectTime', selTime; 'TimeRange', ylimRange};
    [avSMT, rSMT] = untitled_function(handles.data);
    output = vis_plotController(avSMT, rSMT, options);
catch error
    close gcf;
    output = {'';'Unexpected Error Occurred in';...
        sprintf('%s (line: %d)', error.stack(1).name, error.stack(1).line);...
        error.message};
end
set(handles.note_txt, 'String', output);
% visual_scalpPlot_fin(handles.data, {'Interval', handles.selected_ival;'Channels',{'Cz', 'POz','Oz'};'num_class',{'target','non-target'}});
% visual_scalpPlot_fin(handles.data, {'Interval', [-100 0 150 250 400];'Channels',{'Cz', 'POz','Oz'}});
% Update handles structure
% guidata(hObject, handles);

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

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

% Hints: get(hObject,'String') returns contents of time_seg_start as text
%        str2double(get(hObject,'String')) returns contents of time_seg_start as a double

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of time_seg_end as text
%        str2double(get(hObject,'String')) returns contents of time_seg_end as a double

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of freq_band_start as text
%        str2double(get(hObject,'String')) returns contents of freq_band_start as a double

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of freq_band_end as text
%        str2double(get(hObject,'String')) returns contents of freq_band_end as a double

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of baseline_start as text
%        str2double(get(hObject,'String')) returns contents of baseline_start as a double
input = get(handles.baseline_start, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.baseline_start, 'String', string(handles.data.ival(1)));
    return;
end
if str2double(input) < handles.data.ival(1) || str2double(input) > handles.data.ival(end)
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input between the segmentation range'});
    set(handles.baseline_start, 'String', string(handles.data.ival(1)));
    return;
end

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of baseline_end as text
%        str2double(get(hObject,'String')) returns contents of baseline_end as a double
input = get(handles.baseline_end, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.baseline_end, 'String', '0');
    return;
end
if str2double(input) < handles.data.ival(1) || str2double(input) > handles.data.ival(end)
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input between the segmentation range'});
    set(handles.baseline_end, 'String', string(handles.data.ival(end)));
    return;
end

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

% Hint: edit 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

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

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

% Hints: get(hObject,'String') returns contents of baseline_start as text
%        str2double(get(hObject,'String')) returns contents of baseline_start as a double

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

% Hint: edit 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

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

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
% hObject    handle to slider1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

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

% Hints: get(hObject,'String') returns contents of baseline_end as text
%        str2double(get(hObject,'String')) returns contents of baseline_end as a double

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

% Hint: edit 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

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

% Hint: get(hObject,'Value') returns toggle state of check_SSVEP

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

% Hint: get(hObject,'Value') returns toggle state of check_Topo

% --- Executes on selection change in pop_range.
function pop_range_Callback(hObject, eventdata, handles)
% hObject    handle to pop_range (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 pop_range contents as cell array
%        contents{get(hObject,'Value')} returns selected item from pop_range

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

% --- Executes on selection change in popupmenu10.
function popupmenu10_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu10 (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 popupmenu10 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu10

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

% --- Executes on selection change in popupmenu11.
function popupmenu11_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu11 (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 popupmenu11 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu11

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

% --- Executes on selection change in pop_color.
function pop_color_Callback(hObject, eventdata, handles)
% hObject    handle to pop_color (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 pop_color contents as cell array
%        contents{get(hObject,'Value')} returns selected item from pop_color

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

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

% Hint: get(hObject,'Value') returns toggle state of check_patch

% --- Executes on selection change in pop_quality.
function pop_quality_Callback(hObject, eventdata, handles)
% hObject    handle to pop_quality (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 pop_quality contents as cell array
%        contents{get(hObject,'Value')} returns selected item from pop_quality

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

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

% Hints: get(hObject,'String') returns contents of minYlim as text
%        str2double(get(hObject,'String')) returns contents of minYlim as a double
input = get(handles.minYlim, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.minYlim, 'String', '0');
    return;
end
% --- Executes during object creation, after setting all properties.
function minYlim_CreateFcn(hObject, eventdata, handles)
% hObject    handle to minYlim (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of maxYlim as text
%        str2double(get(hObject,'String')) returns contents of maxYlim as a double
input = get(handles.maxYlim, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.maxYlim, 'String', '0');
    return;
end

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

% Hint: edit 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

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

% Hint: get(hObject,'Value') returns toggle state of inputToggle
if get(handles.inputToggle, 'Value')
    set(handles.pop_range, 'Visible', 'off');
    set(handles.maxTopo, 'Visible', 'on');
    set(handles.minTopo, 'Visible', 'on');
    set(handles.tildeTopo, 'Visible', 'on');
    set(handles.inputToggle, 'String', 'Options');
else
    set(handles.pop_range, 'Visible', 'on');
    set(handles.maxTopo, 'Visible', 'off');
    set(handles.minTopo, 'Visible', 'off');
    set(handles.tildeTopo, 'Visible', 'off');
    set(handles.inputToggle, 'String', 'Direct');
end

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

% Hints: get(hObject,'String') returns contents of minTopo as text
%        str2double(get(hObject,'String')) returns contents of minTopo as a double
input = get(handles.minTopo, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.minTopo, 'String', '0');
    return;
end

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of maxTopo as text
%        str2double(get(hObject,'String')) returns contents of maxTopo as a double
input = get(handles.maxTopo, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.maxTopo, 'String', '0');
    return;
end

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of minSelect as text
%        str2double(get(hObject,'String')) returns contents of minSelect as a double
input = get(handles.minSelect, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.minSelect, 'String', string(handles.data.ival(1)));
    return;
end
if str2double(input) < handles.data.ival(1) || str2double(input) > handles.data.ival(end)
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input between the segmentation range'});
    set(handles.minSelect, 'String', string(handles.data.ival(1)));
    return;
end

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

% Hint: edit 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

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

% Hints: get(hObject,'String') returns contents of maxSelect as text
%        str2double(get(hObject,'String')) returns contents of maxSelect as a double
input = get(handles.maxSelect, 'String');
[~, len] = regexp(input, '^-?[0-9]+');

if ~isequal(len, length(input))
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input the number'});
    set(handles.maxSelect, 'String', string(handles.data.ival(end)));
    return;
end
if str2double(input) < handles.data.ival(1) || str2double(input) > handles.data.ival(end)
    set(handles.note_txt, 'String',{'';sprintf('[%s] is not acceptable', input);'please input between the segmentation range'});
    set(handles.maxSelect, 'String', string(handles.data.ival(end)));
    return;
end

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

% Hint: edit 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

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

% Hint: get(hObject,'Value') returns toggle state of selToggle
if get(handles.selToggle, 'Value')
    set(handles.maxSelect, 'Enable', 'on');
    set(handles.minSelect, 'Enable', 'on');
    set(handles.selToggle, 'String', 'Deselect');
else
    set(handles.maxSelect, 'Enable', 'off');
    set(handles.minSelect, 'Enable', 'off');
	set(handles.selToggle, 'String', 'Select');
end

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

% Hint: get(hObject,'Value') returns toggle state of ylimToggle
if isequal(get(handles.ylimToggle, 'String'), 'Select')
    set(handles.maxYlim, 'Enable', 'on');
    set(handles.minYlim, 'Enable', 'on');
    set(handles.ylimToggle, 'String', 'Deselect');
    set(handles.ylimToggle, 'Value', true);
else
    set(handles.maxYlim, 'Enable', 'off');
    set(handles.minYlim, 'Enable', 'off');
    set(handles.ylimToggle, 'String', 'Select');
    set(handles.ylimToggle, 'Value', false);
end

% --- Executes on selection change in pop_orient.
function pop_orient_Callback(hObject, eventdata, handles)
% hObject    handle to pop_orient (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 pop_orient contents as cell array
%        contents{get(hObject,'Value')} returns selected item from pop_orient

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


% HLP_ARGSTRUCT2LINEARCELL - Linearize configation output of arg_guipanel
%
% Usage:
%   >> cellval = hlp_argstruct2linearcells( cfg );
%
% Inputs:
%   cfg  - output configuration structure from arg_guipanel
%
% Output:
%   cellval - cell array of output values
%
% Author: Arnaud Delorme, SCCN & CERCO, CNRS, 2013-

% Copyright (C) 2013 Arnaud Delorme
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function cellval = hlp_argstruct2linearcell(cfg);

    cellval = {};
    if isstruct(cfg)
        ff = fieldnames(cfg);
        for iField = 1:length(ff)
            if ~strcmpi(ff{iField}, 'arg_direct')
                if strcmpi(ff{iField}, 'arg_selection')
                    cellval = { cfg.arg_selection cellval{:} };
                else
                    val = cfg.(ff{iField});
                    if isstruct(val)
                        val = hlp_argstruct2linearcell(val);
                        cellval = { cellval{:} ff{iField} val{:} };
                    elseif iscell(val)
                        cellval = { cellval{:} ff{iField} vararg2str(val) };
                    else
                        cellval = { cellval{:} ff{iField} val };
                    end
                end
            end
        end
    else
        cellval = cfg;
    end


function [np_info] = np_readfileinfo (filename, option)
%
% function [np_info] = np_readfileinfo (filename, option)
%
% Purpose:
%
% np_readfileinfo reads out header information from a NEURO PRAX
% data file (*.EEG).
%
% Syntax:
%
%   [np_info] = np_readfileinfo(filename);
%   [np_info] = np_readfileinfo(filename,'NO_MINMAX');
%
% Input data:
%
%   filename        -   the complete filename with path
%                       (e. g.  C:\Document...\20030716103637.EEG)
%   option          -   if option = 'NO_MINMAX' then physical minima
%   (optional)          and maxima off all channels will not be calculated
%                       (faster for long recordings)
%
% Output data:
%
%   np_info         -   structure
%
%      np_info.filename       -   filename of *.EEG file
%      np_info.pathname       -   pathname of *.EEG file
%      np_info.name           -   patient's name
%      np_info.firstname      -   patient's firstname
%      np_info.birthday       -   patient's birthday
%      np_info.ID             -   identification number
%      np_info.date           -   start date of the recording (format: 'dd-mmm-yyyy')
%      np_info.time           -   start time of the recording (format: 'hh:mm:ss')
%      np_info.duration       -   duration of the recording (global for splitted EEG files!)
%      np_info.setup          -   electrode setup
%      np_info.pmtype         -   type of primary montage
%      np_info.algorithm      -   used algorithm for measurement
%      np_info.channels       -   cell-array with channel names
%      np_info.channeltypes   -   cell-array with channel types
%      np_info.units          -   cell-array with channel units
%      np_info.PhysMin        -   physical minimum for each channel (global for splitted EEG files!)
%      np_info.PhysMax        -   physical maximum for each channel (global for splitted EEG files!)
%      np_info.N              -   number of samples per channel (global for splitted EEG files!)
%      np_info.K              -   number of channels
%      np_info.fa             -   sampling frequency
%      np_info.fp_data        -   filepointer to data
% --- additional SPLITTING information ---
%      np_info.SPLIT_Z        -   number of splitted EEG files (=Z; Z = 1 : no splitting)
%      np_info.SPLIT_filename -   all filenames of splitted EEG file (Zx1 cell-array)
%      np_info.SPLIT_N        -   samples of splitted EEG file (Zx1 array)
%      np_info.SPLIT_fp_data  -   file pointers of splitted EEG file (Zx1 array)
%      np_info.SPLIT_PhysMin  -   physical minimum for each channel and each file (ZxK array)
%      np_info.SPLIT_PhysMax  -   physical maximum for each channel and each file (ZxK array)
%
% Version:  1.3. (2005-09-19)
%
% (1) The field 'units' will be read correctly from the channel header.
%
% (2) The sampling frequency (fa) is identical for all channels and is set
%     to the value of the first channel.
%
% (3) The channel types will be read from the channel header directly.
%
% (4) The field 'time' is set to the correct recording time.
%
% (5) Additional structure fields:
%     setup      -   the electrode setup (previously "primmon")
%     pmtype     -   the type of the primary montage
%     algorithm  -   the feedback algorithm
%
% (6) No longer available: the structure field "primmon".
%
% (7) Splitted EEG files will be supported.
%
% See also: np_readdata, np_readmarker
%
% eldith GmbH
% Gustav-Kirchhoff-Str. 5
% D-98693 Ilmenau
% Germany
% 02.02.2005

if (1==nargin),
    option='';
end

% -------------------------------------------------------------------------
% Initialisierung der Struktur
% -------------------------------------------------------------------------
np_info=struct('filename','','pathname','','name','','firstname','','birthday','','ID',0,'date','00.00.00',...
               'time','00:00:00','duration','','setup','','pmtype','','algorithm','','channels','','channeltypes','',...
               'units','','PhysMin',0,'PhysMax',0,'N',0,'K',0,'fa',0,'fp_data',0,...
               'SPLIT_Z',1,'SPLIT_filename','','SPLIT_N',[],'SPLIT_fp_data',[],...
               'SPLIT_PhysMin',[],'SPLIT_PhysMax',[]);

% -------------------------------------------------------------------------
% alle zusammengeh�renden EEG-Dateien ermitteln (z.B. bei SPLITTING)
% -------------------------------------------------------------------------
[pa,fn,ex]=fileparts(filename);
if strcmp(pa,''),
    pa=pwd;
end
MaskEEGFileNames=[pa filesep fn(1:14) '*.EEG'];
d=dir(MaskEEGFileNames);
e=cell(length(d),1);
for i=1:length(d)
    e{i}=[pa filesep d(i).name];
end
filenames=sort(e);

% -------------------------------------------------------------------------
% SPLIT-Procedures
% -------------------------------------------------------------------------
np_info.SPLIT_Z=length(filenames);
np_info.SPLIT_filename=cell(np_info.SPLIT_Z,1);
np_info.SPLIT_N=zeros(np_info.SPLIT_Z,1);
np_info.SPLIT_fp_data=zeros(np_info.SPLIT_Z,1);

for Z=1:np_info.SPLIT_Z
    % Infos f�r n�chste EEG-Datei lesen
    np_splitted_info=np_read_splitted_fileinfo(filenames{Z},option);

    % fixe Daten in np_info eintragen
    if (1==Z),
        np_info.filename=np_splitted_info.filename;
        np_info.pathname=np_splitted_info.pathname;
        np_info.name=np_splitted_info.name;
        np_info.firstname=np_splitted_info.firstname;
        np_info.birthday=np_splitted_info.birthday;
        np_info.ID=np_splitted_info.ID;
        np_info.date=np_splitted_info.date;
        np_info.time=np_splitted_info.time;
        np_info.setup=np_splitted_info.setup;
        np_info.pmtype=np_splitted_info.pmtype;
        np_info.algorithm=np_splitted_info.algorithm;
        np_info.K=np_splitted_info.K;
        np_info.fa=np_splitted_info.fa;
        np_info.fp_data=np_splitted_info.fp_data;
        np_info.channels=np_splitted_info.channels;
        np_info.channeltypes=np_splitted_info.channeltypes;
        np_info.units=np_splitted_info.units;
        np_info.PhysMin=zeros(1,np_splitted_info.K);
        np_info.PhysMax=zeros(1,np_splitted_info.K);
        np_info.SPLIT_PhysMin=zeros(np_info.SPLIT_Z,np_splitted_info.K);
        np_info.SPLIT_PhysMax=zeros(np_info.SPLIT_Z,np_splitted_info.K);
    end

    % SPLIT-Infos zusammenstellen
    np_info.SPLIT_filename{Z}=np_splitted_info.filename;
    np_info.SPLIT_N(Z)=np_splitted_info.N;
    np_info.SPLIT_fp_data(Z)=np_splitted_info.fp_data;
    np_info.SPLIT_PhysMin(Z,:)=np_splitted_info.PhysMin;
    np_info.SPLIT_PhysMax(Z,:)=np_splitted_info.PhysMax;

    % Samplez�hler erh�hen
    np_info.N=np_info.N+np_info.SPLIT_N(Z);

end

% global duration berechnen
np_info.fa;
np_info.duration=num2str(np_info.N./np_info.fa);

% physikalische Minima und Maxima berechnen
if (1~=strcmp(upper(option),'NO_MINMAX')),
    for k=1:np_info.K
        np_info.PhysMin(k)=+1e38;
        np_info.PhysMax(k)=-1e38;
        for Z=1:np_info.SPLIT_Z
            np_info.PhysMin(k)=min([np_info.PhysMin(k) np_info.SPLIT_PhysMin(Z,k)]);
            np_info.PhysMax(k)=max([np_info.PhysMax(k) np_info.SPLIT_PhysMax(Z,k)]);
        end
    end
end


function [tagName, hexString] = tag2strings(tag, dcmobj)
%"tag2strings"
%   Convert a decimal representation of a Dicom tag into two strings, the
%   tagName which is a decription of the field, and a hexString which gives
%   the tag in hex form '(xxxx,yyyy)'.
%
%   A dcmobj must be passed in to provide a link to the dicomdictionary.
%
%JRA 06/13/06
%
% 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/>.

%Usage:
%   [tagName, hexString] = tag2strings(tag, dcmobj)

hexString    = char(org.dcm4che2.util.TagUtils.toString(tag));
tagName      = char(dcmobj.nameOf(tag));


classdef (ConstructOnLoad, Abstract)ZmapCatalogAddon < matlab.mixin.Copyable
    % ZMAPCATALOGADDON is a base class for add-ons to a zmap catalog. For example, Moment Tensors
    properties(Abstract, Constant)
        Type
    end

    methods
        function obj = ZmapCatalogAddon()
        end

        function subsetInPlace(obj, idx)
            pef = obj.possibly_empty_fields();
            for ii =1: numel(pef)
                fn = pef{ii};
                if ~isempty(obj.(fn))
                    obj.(fn) = obj.(fn)(idx,:);
                end
            end
        end

        function newobj = subset(obj, idx)
            newobj=copy(obj);
            newobj.subsetInPlace(idx)
        end

        function disp(obj)
            display_helper(obj)
        end

    end
    methods (Abstract, Static, Hidden)
    	pef = possibly_empty_fields()
        s = display_order()
    end
end


function tocStatus( id, fracDone )
% Used to display the progress of a long process.
%
% For more information see ticStatus.
%
% USAGE
%  tocStatus( id, fracDone )
%
% INPUTS
%  id          - unique id of progress indicator
%  fracDone    - value in (0,1] indicating percent operation completed
%
% OUTPUTS
%
% EXAMPLE
%
% See also TICSTATUS
%
% Piotr's Image&Video Toolbox      Version 2.50
% Copyright 2012 Piotr Dollar.  [pdollar-at-caltech.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the Simplified BSD License [see external/bsd.txt]

global TT_STATUS TT_FREE_IDS

%%% error check
if( length(TT_STATUS)<id || TT_FREE_IDS(id)==1 )
  error('MATLAB:tocStatus:callTicstatusFirst', ...
    'You must call TICSTATUS before calling TOCSTATUS.');
end
[fracDone,er] = checkNumArgs( fracDone, [1 1], -1, 1 );
if(~isempty(er)), error(er); end
if( fracDone>1 ); error(['fracDone: ' num2str(fracDone) ' > 1'] ); end;

%%% get parameters
updateFreq  = TT_STATUS(id).updateFreq;
updateMinT  = TT_STATUS(id).updateMinT;
erasePrev   = TT_STATUS(id).erasePrev;
msg         = TT_STATUS(id).msg;
t0          = TT_STATUS(id).t0;
tLast       = TT_STATUS(id).tLast;
lenPrev     = TT_STATUS(id).lenPrev;

%%% update if enough time has passed
if( etime( clock, tLast )> updateFreq || (fracDone==1 && lenPrev>0) )
  tLast = clock;
  elptime = etime(clock,t0);
  fracDone = max( fracDone, .00001 );
  esttime = elptime/fracDone - elptime;
  if( lenPrev || (elptime/fracDone)>updateMinT )
    if( ~lenPrev ); fprintf('\n'); end

    % create display message
    fracdoneS = num2str(fracDone*100,'%.1f');
    if( elptime/fracDone < 600 )
      elptimeS  = num2str(elptime,'%.1f');
      esttimeS  = num2str(esttime,'%.1f');
      timetypeS = 's';
    else
      elptimeS  = num2str(elptime/60,'%.1f');
      esttimeS  = num2str(esttime/60,'%.1f');
      timetypeS = 'm';
    end
    if( ~isempty(msg) ); msg = [msg '   ']; end
    msg = [msg 'completed=' fracdoneS '%% [elapsed=' elptimeS ];
    msg = [msg timetypeS ' / remaining~=' esttimeS timetypeS ']' ];

    % erase previous display and create new display
    if( erasePrev ) % undo previous disp
      fprintf( repmat('\b', [1 lenPrev] ) ); end
    fprintf( msg );  % fprintf( [msg '\n'] );
    lenPrev = length( msg ) - 1; %note %% (+1 if using \n)
    TT_STATUS(id).tLast = tLast;
    TT_STATUS(id).lenPrev = lenPrev;
  end
end

%%% free id if done
if( fracDone==1 )
  if(lenPrev); fprintf('\n'); end
  TT_FREE_IDS(id) = 1;
end


function ADMINcopyfolderstructure(ORIGINALFOLDER, MIRRORFOLDER)
%
% ADMINcopyfolderstructure(ORIGINALFOLDER, MIRRORFOLDER)
%
% ORIGINALFOLDER
% MIRRORFOLDER  -> here goes the new folders

% create list of folders
folders = genpath(ORIGINALFOLDER);
h = [findstr(folders,  pathsep)];
h = [0 h];
Nfolders = length(h)-1
for i = 1:Nfolders
    tmp = folders(h(i)+1:h(i+1)-1);
    tmp = strrep(tmp, ORIGINALFOLDER, ''); tmp = tmp(2:end);
    Folder{i} = tmp;
end

% make new folders
for f = 1:Nfolders
    folder = fullfile(MIRRORFOLDER, Folder{f});

    if ~exist(folder, 'dir')
        mkdir(folder);
    else
        disp('folders already exist in target folder')
    end
end


%show_dose_temp.m

global planC
indexS = planC{end};

planC{indexS.IM}(1).IMDosimetry.beams = [IMwQIB.beams];

planC{indexS.IM}.IMDosimetry.goals = IMwQIB(1).goals;

planC{indexS.IM}.IMDosimetry.params = IMwQIB(1).params;

planC{indexS.IM}.IMDosimetry.isFresh = 1;

planC{indexS.IM}.IMDosimetry.name = 'Eclipse Leaf Seq';

planC{indexS.IM}.IMDosimetry.solutions = [];

planC{indexS.IM}.IMDosimetry.assocScanUID = planC{indexS.scan}(1).scanUID;

planC{indexS.IM}.IMDosimetry.solutions = [beamletWeightC{:}];

[dose3D] = getIMDose(planC{indexS.IM}(1).IMDosimetry, [beamletWeightC{:}], structNumsV);

showIMDose(dose3D,'QIB reCalc')


function [lineData, logFooter, linesFooter] = tapas_physio_read_physlogfiles_siemens_raw(...
    fileNameLog)
% Read in raw data/footer lines of logfiles, without data selection/sorting
%
% [lineData, linesFooter] = tapas_physio_read_physlogfiles_siemens_raw(...
%        fileNameLog)
%
% IN
%   fileNameLog     file name of physiological log, e.g. *.ecg
%
% OUT
%   lineData        all recording amplitude samples are saved in first line
%                   of file
%   logFooter       struct() of read-out meta information from log file, i.e.
%                   LogStart/StopTimeSeconds
%                   ScanStart/StopTimeSeconds
%                   => uses MDH time stamp in log file to sync to DICOMs
%   linesFooter     all meta-information (e.g. sampling start/stop) is
%                   saved in remaining lines of log file
%
% EXAMPLE
%   tapas_physio_read_physlogfiles_siemens_raw
%
%   See also

% Author: Lars Kasper
% Created: 2016-02-29
% Copyright (C) 2016 TNU, Institute for Biomedical Engineering,
%                    University of Zurich and ETH Zurich.
%
% This file is part of the TAPAS PhysIO Toolbox, which is released under the terms of the GNU General Public
% License (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/>.

fid             = fopen(fileNameLog);

if verLessThan('matlab', '8.5') % use buffer size for speed-up, as long as it exists
    C               = textscan(fid, '%s', 'Delimiter', '\n', 'bufsize', 1e9);
else
    C               = textscan(fid, '%s', 'Delimiter', '\n');
end

fclose(fid);

linesFooter = C{1}(2:end);
lineData = C{1}{1};

%Get time stamps from footer:

logFooter.LogStartTimeSeconds =   str2num(char(regexprep(linesFooter(~cellfun(@isempty,strfind(linesFooter,...
    'LogStartMDHTime'))),'\D',''))) / 1000;
logFooter.LogStopTimeSeconds =    str2num(char(regexprep(linesFooter(~cellfun(@isempty,strfind(linesFooter,...
    'LogStopMDHTime'))),'\D',''))) / 1000;

% MPCU  = Computer who controls the scanner => physio logging happens here
% MDH   = Compute who is the host; console => DICOM time stamp here!
%
% - according to Chris Rorden, PART
% (http://www.mccauslandcenter.sc.edu/crnl/tools/part) - MDH is the time we
% should use for phys logging synchronization, since DICOM conversion uses
% this clock

% This is just a different time-scale (of the phys log computer), it does
% definitely NOT match with the Acquisition time in the DICOM-headers
logFooter.ScanStartTimeSeconds = str2num(char(regexprep(linesFooter(~cellfun(@isempty,strfind(linesFooter,...
    'LogStartMPCUTime'))),'\D','')));
logFooter.ScanStopTimeSeconds = str2num(char(regexprep(linesFooter(~cellfun(@isempty,strfind(linesFooter,...
    'LogStopMPCUTime'))),'\D','')));


classdef lsl_outlet < handle
	% A stream outlet.
	% Outlets are used to make streaming data (and the meta-data) available on the lab network.

    properties (Hidden)
        LibHandle = 0;       % this is a handle to the liblsl library (to call its functions)
        OutletHandle = 0;    % this is a handle to an lsl_outlet object within the library.
        SampleRate = 0;      % copy of the sample rate...
    end

    methods

        function self = lsl_outlet(info, chunksize, maxbuffered)
            % Outlet = lsl_outlet(Streaminfo, ChunkSize, MaxBuffered)
            % Establish a new stream outlet. This makes the stream discoverable.
            %
            % In:
            %   Streaminfo : The lsl_streaminfo object to use for creating this stream. Stays constant over the lifetime of the outlet.
            %
            %   ChunkSize :  Optionally the desired chunk granularity (in samples) for transmission. If 0,
            %                each push operation yields one chunk. Stream recipients can have this setting bypassed.
            %                (default: 0)
            %
            %   MaxBuffered : Optionally the maximum amount of data to buffer (in seconds if there is a nominal
            %                 sampling rate, otherwise x100 in samples). Stream recipients can elect to use
            %                 a smaller (but not larger) buffer size than the one specified here.
            %                 (default: 360)
            %

            if ~exist('chunksize','var') || isempty(chunksize) chunksize = 0; end
            if ~exist('maxbuffered','var') || isempty(maxbuffered) maxbuffered = 360; end
            self.LibHandle = info.LibHandle;
            self.SampleRate = info.nominal_srate();
            self.OutletHandle = lsl_create_outlet(info.LibHandle,info.InfoHandle,chunksize,maxbuffered);
        end

        function delete(self)
            % Destroy the outlet when it is deleted.
            % The outlet will no longer be discoverable after destruction and all paired inlets will
            % stop delivering data.

            lsl_destroy_outlet(self.LibHandle,self.OutletHandle);
        end

        function push_sample(self,sampledata,timestamp,pushthrough)
            % push_sample(SampleData,Timestamp,Pushthrough)
            % Push a sample into the outlet.
            %
            % In:
            %   SampleData : either a numeric vector (as double, converted implicitly) with as many
            %                elements as the stream has channels, or a cell array of strings of the
            %                same size (if the stream is string-formatted).
            %
            %   Timestamp : Optionally the capture time of the most recent sample, in agreement with lsl_local_clock();
            %               if 0, the current time is used.
            %
            %   Pushthrough : Whether to push the chunk through to the receivers instead of buffering it with subsequent samples.
			%	 			  Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag.
            %                 (default: 1)

            if ~exist('timestamp','var') || isempty(timestamp) timestamp = 0; end
            if ~exist('pushthrough','var') || isempty(pushthrough) pushthrough = 1; end
            lsl_push_sample(self.LibHandle,self.OutletHandle,sampledata,timestamp,pushthrough);
        end

        function push_chunk(self,chunkdata,timestamps,pushthrough)
            % push_sample(ChunkData,Timestamps,Pushthrough)
            % Push a chunk into the outlet.
            %
            % In:
            %   ChunkData : Numeric matrix with one column for each sample that shall be
            %               transmitted. May also be empty.
            %
            %   Timestamps : Optionally the capture time of the most recent sample, in agreement with lsl_local_clock();
            %                if 0, the current time is used. The time stamps of other samples are automatically
            %                derived based on the sampling rate of the stream, or replicated if the stream is irregular-rate
            %                If this is a vector, it is assumed that it contains one time stamp for each sample. (default: 0)
            %
            %   Pushthrough : Whether to push the chunk through to the receivers instead of buffering it with subsequent samples.
			%	 			  Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag.
            %                 (default: 1)

            if ~exist('timestamps','var') || isempty(timestamps) timestamps = 0; end
            if ~exist('pushthrough','var') || isempty(pushthrough) pushthrough = 1; end

            if timestamps == 0
                timestamps = lsl_local_clock(self.LibHandle); end

            if isscalar(timestamps)
                if self.SampleRate == 0
                    timestamps = [timestamps; -ones(size(chunkdata,2)-1,1)];
                else
                    % otherwise infer the timestamp of the first sample in the chunk and let the
                    % library deduce the timestamps for the remaining samples (using -1.0 as the
                    % stamps).
                    timestamps = [timestamps - (size(chunkdata,2)-1)/self.SampleRate; -ones(size(chunkdata,2)-1,1)];
                end
            end

            lsl_push_chunk(self.LibHandle,self.OutletHandle,chunkdata,timestamps,pushthrough);
        end

        % === Miscellaneous Features ===

        function result = have_consumers(self)
            % Check whether consumers are currently registered.
            % While it does not hurt, there is technically no reason to push samples if there is no consumer.

            result = lsl_have_consumers(self.LibHandle,self.OutletHandle);
        end

        function success = wait_for_consumers(self,timeout)
            % Wait until some consumer shows up (without wasting resources).
            %
            % In:
            %   Timeout : Timeout for the operation. (default: 60)
            %
            % Out:
            %   Success : True if the wait was successful, false if the timeout expired.

            if ~exist('timeout','var') || isempty(timeout) timeout = 60; end
            success = lsl_wait_for_consumers(self.LibHandle,self.OutletHandle,timeout);
        end

        function result = info(self)
            % Retrieve the stream info provided by this outlet.
            % This is what was used to create the stream (and also has the Additional Network Information fields assigned).

            result = lsl_streaminfo(self.LibHandle,lsl_get_info(self.LibHandle,self.OutletHandle));
        end

        function h = get_libhandle(self)
            % get the library handle (e.g., to query the clock)
            h = self.LibHandle;
        end
    end
end


function [nev] = neuralynx_read_nev(filename, varargin)
% READ_NEURALYNX_NEV reads the event information from the *.nev file in a Neuralynx dataset directory
% Use as
%   nev = read_neuralynx_hdr(datadir, ...)
%   nev = read_neuralynx_hdr(eventfile, ...)
%
% Optional input arguments should be specified in key-value pairs and may include
%   implementation  should be 1, 2 or 3 (default = 3)
%   value           number or list of numbers
%   mintimestamp    number
%   maxtimestamp    number
%   minnumber       number
%   maxnumber       number
%
% The output structure contains all events and timestamps.

% @=============================================================================
% 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.
% =============================================================================@
%
% Copyright (C) 2005, Robert Oostenveld
% 19-Jun-2015 Edited by Francois Tadel for the integration in Brainstorm

% get the optional input arguments
% flt_value        = ft_getopt(varargin, 'value');
% flt_mintimestamp = ft_getopt(varargin, 'mintimestamp');
% flt_maxtimestamp = ft_getopt(varargin, 'maxtimestamp');
% flt_minnumber    = ft_getopt(varargin, 'minnumber');
% flt_maxnumber    = ft_getopt(varargin, 'maxnumber');
% implementation   = ft_getopt(varargin, 'implementation', 3);
flt_value        = [];
flt_mintimestamp = [];
flt_maxtimestamp = [];
flt_minnumber    = [];
flt_maxnumber    = [];
implementation   = 3;

% if ft_filetype(filename, 'neuralynx_ds')
%   % replace the directory name by the filename
%   if     exist(fullfile(filename, 'Events.Nev'))
%     filename = fullfile(filename, 'Events.Nev');
%   elseif exist(fullfile(filename, 'Events.nev'))
%     filename = fullfile(filename, 'Events.nev');
%   elseif exist(fullfile(filename, 'events.Nev'))
%     filename = fullfile(filename, 'events.Nev');
%   elseif exist(fullfile(filename, 'events.nev'))
%     filename = fullfile(filename, 'events.nev');
%   end
% end

% The file starts with a 16*1024 bytes header in ascii, followed by a
% number of records (c.f. trials).
%
% The format of an event record is
%   int16 PktId
%   int16 PktDataSize
%   int64 TimeStamp
%   int16 EventId
%   int16 TTLValue
%   int16 CRC
%   int32 Dummy
%   int32 Extra[0]
%   ...
%   int32 Extra[7]
%   char EventString[0]
%   ...
%   char EventString[127]
% PktId is usually 0x1002.
% PktDataSize is random data.
% Dummy is random data.
% CRC may contain random data.
% Extra is user-defined data.
% TTLValue is the value sent to the computer on a parallel input port.

fid = fopen(filename, 'rb', 'ieee-le');

headersize = 16384;
offset     = headersize;
if ~isempty(flt_minnumber)
  offset = offset + (flt_minnumber-1)*184;
end

nev = [];

if implementation==1
  if ~isempty(flt_maxnumber)
    warning('filtering on maximum number not yet implemneted');
  end
  % this is the slow way of reading it
  % it also does not allow filtering
  fseek(fid, offset, 'bof');
  while ~feof(fid)
    nev(end+1).PktStart     = fread(fid, 1, 'int16');
    nev(end  ).PktId        = fread(fid, 1, 'int16');
    nev(end  ).PktDataSize  = fread(fid, 1, 'int16');
    nev(end  ).TimeStamp    = fread(fid, 1, 'uint64');
    nev(end  ).EventId      = fread(fid, 1, 'int16');
    nev(end  ).TTLValue     = fread(fid, 1, 'uint16');
    nev(end  ).CRC          = fread(fid, 1, 'int16');
    nev(end  ).Dummy        = fread(fid, 1, 'int32');
    nev(end  ).Extra        = fread(fid, 8, 'int32');
    nev(end  ).EventString  = fread(fid, 128, 'char');
  end
end

if implementation==2
  if ~isempty(flt_maxnumber)
    warning('filtering on maximum number not yet implemneted');
  end
  % this is a faster way of reading it and it is still using the automatic type conversion from Matlab
  fp = offset;
  fseek(fid, fp+ 0, 'bof'); PktStart       = fread(fid, inf, 'uint16', 184-2);
  num = length(PktStart);
  fseek(fid, fp+ 2, 'bof'); PktId          = fread(fid, num, 'uint16', 184-2);
  fseek(fid, fp+ 4, 'bof'); PktDataSize    = fread(fid, num, 'uint16', 184-2);
  fseek(fid, fp+ 6, 'bof'); TimeStamp      = fread(fid, num, 'uint64=>uint64', 184-8);
  fseek(fid, fp+14, 'bof'); EventId        = fread(fid, num, 'uint16', 184-2);
  fseek(fid, fp+16, 'bof'); TTLValue       = fread(fid, num, 'uint16', 184-2);
  fseek(fid, fp+18, 'bof'); CRC            = fread(fid, num, 'uint16', 184-2);
  fseek(fid, fp+22, 'bof'); Dummy          = fread(fid, num, 'int32' , 184-4);
  % read each of the individual extra int32 values and concatenate them
  fseek(fid, fp+24+0*4, 'bof'); Extra1     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+1*4, 'bof'); Extra2     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+2*4, 'bof'); Extra3     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+3*4, 'bof'); Extra4     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+4*4, 'bof'); Extra5     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+5*4, 'bof'); Extra6     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+6*4, 'bof'); Extra7     = fread(fid, num, 'int32', 184-4);
  fseek(fid, fp+24+7*4, 'bof'); Extra8     = fread(fid, num, 'int32', 184-4);
  Extra = [Extra1 Extra2 Extra3 Extra4 Extra5 Extra6 Extra7 Extra8];
  % read the complete data excluding header as char and cut out the piece with the EventString content
  fseek(fid, fp, 'bof'); EventString        = fread(fid, [184 num], 'char');
  EventString = char(EventString(57:184,:)');
end

if implementation==3
  % this is an even faster way of reading it
  if isempty(flt_minnumber)
    flt_minnumber = 1;
  end
  if isempty(flt_maxnumber)
    flt_maxnumber = inf;
  end
  if fseek(fid, offset, 'bof')~=0
    error(ferror(fid));
  end
  buf = fread(fid, (flt_maxnumber-flt_minnumber+1)*184, 'uint8=>uint8');
  [PktStart, PktId , PktDataSize , TimeStamp , EventId , TTLValue , CRC , Dummy , Extra1 , Extra2 , Extra3 , Extra4 , Extra5 , Extra6 , Extra7 , Extra8 , EventString] = ...
    cstructdecode(buf, 'int16', 'int16', 'int16', 'uint64', 'int16', 'uint16', 'int16', 'int32', 'int32', 'int32', 'int32', 'int32', 'int32', 'int32', 'int32', 'int32', 'char128');
  % the cstructdecode function does not respect the byte order for other-endian numbers
  if 0 % bigendian
    PktStart     = swapbytes(PktStart);
    PktId        = swapbytes(PktId);
    PktDataSize  = swapbytes(PktDataSize);
    TimeStamp    = swapbytes(TimeStamp);
    EventId      = swapbytes(EventId);
    TTLValue     = swapbytes(TTLValue);
  % CRC          = swapbytes(CRC);
  % Dummy        = swapbytes(Dummy);
  % Extra1       = swapbytes(Extra1);
  % Extra2       = swapbytes(Extra2);
  % Extra3       = swapbytes(Extra3);
  % Extra4       = swapbytes(Extra4);
  % Extra5       = swapbytes(Extra5);
  % Extra6       = swapbytes(Extra6);
  % Extra7       = swapbytes(Extra7);
  % Extra8       = swapbytes(Extra8);
  end
end

fclose(fid);

if implementation~=1
  % make a selection of events
  sel = true(size(TTLValue));
  if ~isempty(flt_mintimestamp)
    sel = sel & (TimeStamp>=flt_mintimestamp);
  end
  if ~isempty(flt_maxtimestamp)
    sel = sel & (TimeStamp<=flt_maxtimestamp);
  end
  if ~isempty(flt_value)
    tmp = false(size(sel));
    for i=1:length(flt_value)
      tmp = tmp | (TTLValue==flt_value(i));
    end
    sel = sel & tmp;
  end

  % restructure the data into a struct array, by first making cell-arrays out of it ...
  numsel = sum(sel);
  PktStart      = mat2cell(PktStart(sel)     , ones(1,numsel), 1);
  PktId         = mat2cell(PktId(sel)        , ones(1,numsel), 1);
  PktDataSize   = mat2cell(PktDataSize(sel)  , ones(1,numsel), 1);
  TimeStamp     = mat2cell(TimeStamp(sel)    , ones(1,numsel), 1);
  EventId       = mat2cell(EventId(sel)      , ones(1,numsel), 1);
  TTLValue      = mat2cell(TTLValue(sel)     , ones(1,numsel), 1);
  % CRC           = mat2cell(CRC(sel)          , ones(1,numsel), 1);
  % Dummy         = mat2cell(Dummy(sel)        , ones(1,numsel), 1);
  % Extra1        = mat2cell(Extra1(sel)       , ones(1,numsel), 1);
  % Extra2        = mat2cell(Extra2(sel)       , ones(1,numsel), 1);
  % Extra3        = mat2cell(Extra3(sel)       , ones(1,numsel), 1);
  % Extra4        = mat2cell(Extra4(sel)       , ones(1,numsel), 1);
  % Extra5        = mat2cell(Extra5(sel)       , ones(1,numsel), 1);
  % Extra6        = mat2cell(Extra6(sel)       , ones(1,numsel), 1);
  % Extra7        = mat2cell(Extra7(sel)       , ones(1,numsel), 1);
  % Extra8        = mat2cell(Extra8(sel)       , ones(1,numsel), 1);
  EventString   = mat2cell(EventString(sel,:), ones(1,numsel), 128);
  EventNumber   = mat2cell(find(sel) + flt_minnumber - 1, ones(1,numsel), 1); % this helps in the external filtering for BCI
  % ... and then convert the cell-arrays into a single structure
  nev = struct(...
    'PktStart'    , PktStart     , ...
    'PktId'       , PktId        , ...
    'PktDataSize' , PktDataSize  , ...
    'TimeStamp'   , TimeStamp    , ...
    'EventId'     , EventId      , ...
    'TTLValue'    , TTLValue     , ...
    'EventString' , EventString  , ...
    'EventNumber' , EventNumber);
end

% remove null values and convert to strings
for i=1:length(nev)
  nev(i).EventString = nev(i).EventString(find(nev(i).EventString));
  nev(i).EventString = char(nev(i).EventString(:)');
end


function out = full(fa)
% Convert to numeric form
% FORMAT full(fa)
% fa - a file_array
%__________________________________________________________________________
% Copyright (C) 2018 Wellcome Trust Centre for Neuroimaging

%
% $Id: full.m 7501 2018-11-30 12:16:58Z guillaume $

[vo{1:ndims(fa)}] = deal(':');
out = subsref(fa,struct('type','()','subs',{vo}));


function str=civilizedStringFromCellArrayOfStrings(c,separator)

if ~exist('separator','var')
  separator=',';
end

n=length(c);
if n==0
  str='';
elseif n==1
  str=c{1};
elseif n==2
  str=[c{1} ' and ' c{2}];
else
  str='';
  for i=1:n-1
    str=[str c{i} separator ' '];
  end
  str=[str 'and ' c{n}];
end

end


function [id,OK] = selector(idList,NameList,Caption)
% [id,OK] = selector(idList,NameList,Caption,view)
% [id,OK] = selector(idList,NameList,Caption)
% [id,OK] = selector(idList,NameList)
% User should pick one item from a list

if(nargin==2)
  Caption = 'Select:';
end

c=0;

c=c+1;
uiStruct(c).string = Caption;
uiStruct(c).fieldName = 'main';
uiStruct(c).list = NameList;
uiStruct(c).choice = 1;
uiStruct(c).style = 'popupmenu';

height = 1;
vSkip = 0.3;
pos = [35,10,100,length(uiStruct)*(height+vSkip)+3];
x = 1;
y = length(uiStruct)*(height+vSkip)+1;
editWidth = 50;
stringWidth = pos(3)-editWidth-2;
for uiNum = 1:length(uiStruct)
  uiStruct(uiNum).stringPos = [x,y,stringWidth,height];
  uiStruct(uiNum).editPos = [x+stringWidth-1,y,editWidth,height];
  uiStruct(uiNum).value = 1;
  y = y-(height+vSkip);
end
outStruct = generaldlg(uiStruct,pos);

if ~isempty(outStruct)
  id = idList(strcmp(NameList,outStruct.main));
  OK = 1;
else
  id = 0;
  OK = 0;
end


%
% Initialization for AMICO
%
% NB: DO NOT MODIFY THIS FILE!
%     Make a copy of it, adapt to your paths and rename it to "AMICO_Setup.m"
%

global AMICO_code_path AMICO_data_path

% Path definition: adapt these to your needs
% ==========================================
AMICO_code_path = fileparts(mfilename('fullpath'));
AMICO_data_path = fullfile(AMICO_code_path,'exports');
if(~exist(AMICO_data_path,'dir'))
    mkdir(AMICO_data_path);
end


function g = modelLatentGradients(model)

% MODELLATENTGRADIENTS Gradients of the latent variables for dynamics models in the GPLVM.

% FGPLVM

fhandle = str2func([model.type 'LatentGradients']);
g = fhandle(model);


function cvx_setnpos( x )

global cvx___
x  = x.basis_;
xc = x(1,:);
x  = x(2:end,:);
tt = ( xc <= 0 ) & ( sum( x ~= 0 ) == 1 );
[ tx, dummy ] = find( x(:,tt) ); %#ok
tx = tx + 1;
persistent mneg;
if isempty( mneg ),
    mneg = int8([1,2,2,22,5,5,6,8,8,9,11,11,12,22,22,22,22,22,22,22,22,22]);
end
cvx___.classes(tx) = mneg(cvx___.classes(tx));

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.