% PURPOSE  : 	Marking epochs containing flatline activity that persists for a given period of time.
%
% FORMAT   :
%
% EEG  = pop_artflatline( EEG , 'Channel',  chan, 'Duration',  dur, 'Flag',  f
% lag, 'Threshold', ampth, 'Twindow', twin );
%
% EXAMPLE  :
%
% EEG  = pop_artflatline( EEG , 'Channel',  1:16, 'Duration',  499, 'Flag',
% 1, 'Threshold', [ -2 2], 'Twindow', [ -200 798] );
%
%
% INPUTS   :
%
% EEG       - input dataset
% twin      - time period in ms to apply this tool (start end). Example [-200 800]
% ampth     - peak-to-peak threshold (in uV). Amplitude Tolerance.
% dur       - duration of the artifact in ms
% chan      - channel(s) to search artifacts.
% flag      - flag value between 1 to 8 to be marked when an artifact is found. (1 value)
%
%
% OUTPUTS  :
%
% EEG       - output dataset
%
% See also pop_artbarb pop_artblink pop_artderiv pop_artdiff pop_artmwppth pop_artstep artifactmenuGUI.m markartifacts.m
%
% *** This function is part of ERPLAB Toolbox ***
% Author: Javier Lopez-Calderon & Steven Luck
% Center for Mind and Brain
% University of California, Davis,
% Davis, CA
% 2009

%b8d3721ed219e65100184c6b95db209bb8d3721ed219e65100184c6b95db209b
%
% ERPLAB Toolbox
% Copyright © 2007 The Regents of the University of California
% Created by Javier Lopez-Calderon and Steven Luck
% Center for Mind and Brain, University of California, Davis,
% javlopez@ucdavis.edu, sjluck@ucdavis.edu
%
% 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/>.

function [EEG com] = pop_artflatline(EEG, varargin)
% function [EEG com] = pop_artflatline(EEG, twin, ampth, dur, chan, flag)

com = '';

if nargin<1
        help pop_artflatline
        return
end
if length(EEG)>1
        msgboxText =  'Unfortunately, this function does not work with multiple datasets';
        title = 'ERPLAB: multiple inputs';
        errorfound(msgboxText, title);
        return
end
if isempty(EEG.data)
        msgboxText =  'pop_artflatline() cannot read an empty dataset!';
        title = 'ERPLAB: pop_artflatline() error';
        errorfound(msgboxText, title);
        return
end
if isempty(EEG.epoch)
        msgboxText =  'pop_artflatline has been tested for epoched data only';
        title = 'ERPLAB: pop_artflatline error';
        errorfound(msgboxText, title);
        return
end
if isfield(EEG, 'EVENTLIST')
        if isfield(EEG.EVENTLIST, 'eventinfo')
                if isempty(EEG.EVENTLIST.eventinfo)
                        msgboxText = ['EVENTLIST.eventinfo structure is empty!\n'...
                                'You will not be able to perform ERPLAB''s\n'...
                                'artifact detection tools.'];
                        title = 'ERPLAB: Error';
                        errorfound(sprintf(msgboxText), title);
                        return
                end
        else
                msgboxText =  ['EVENTLIST.eventinfo structure was not found!\n'...
                        'You will not be able to perform ERPLAB''s\n'...
                        'artifact detection tools.'];
                title = 'ERPLAB: Error';
                errorfound(sprintf(msgboxText), title);
                return
        end
else
        msgboxText =  ['EVENTLIST structure was not found!\n'...
                'You will not be able to perform ERPLAB''s\n'...
                'artifact detection tools.'];
        title = 'ERPLAB: Error';
        errorfound(sprintf(msgboxText), title);
        return
end

%
% Gui is working...
%
if nargin==1
        prompt    = {'Test period (start end) [ms]','Amplitude tolerance (single value, e.g. 2):', 'Duration [ms]', 'Channel(s)'};
        dlg_title = 'Blocking';
        dur1      = round(1000*(EEG.xmax-EEG.xmin)/2); % a half epoch default
        defx      = {1000*[EEG.xmin EEG.xmax] 2 dur1 1:EEG.nbchan 0};
        def       = erpworkingmemory('pop_artflatline');
        
        if isempty(def)
                def = defx;
        else
                
                if def{1}(1)<EEG.xmin*1000
                        def{1}(1) = single(EEG.xmin*1000);
                end
                if def{1}(2)>EEG.xmax*1000
                        def{1}(2) = single(EEG.xmax*1000);
                end
                
                if def{3}>(def{1}(2) - def{1}(1)) % ms
                        def{3}= single(1000*EEG.pnts/EEG.srate);
                end
                
                def{4} = def{4}(ismember(def{4},1:EEG.nbchan));
        end
        
        answer = artifactmenuGUI(prompt,dlg_title,def,defx);
        
        if isempty(answer)
                disp('User selected Cancel')
                return
        end
        
        testwindow = answer{1};
        ampth      = answer{2};
        dur        = answer{3}; % in ms
        chanArray  = unique(answer{4}); % avoids repeated channels
        flag       = answer{5};
        
        if   numel(ampth)==1
                ampth(1) = -abs(ampth);
                ampth(2) = abs(ampth);
        elseif numel(ampth)==2
                ampth = sort(ampth);
        else
                msgboxText =  'You have to specify either 1 or 2 values for voltage limits. E.g. -100 100';
                title = 'ERPLAB: Flag input error';
                errorfound(msgboxText, title);
                return
        end
        if numel(dur)~=1
                msgboxText =  'You have to specify 1 value for duration of blocking/flat line.';
                title = 'ERPLAB: duration input error';
                errorfound(msgboxText, title);
                return
        end
        if dur>((EEG.xmax-EEG.xmin)*1000)
                msgboxText =  'Duration cannot be greater than epoch size.';
                title = 'ERPLAB: duration input error';
                errorfound(msgboxText, title);
                return
        end
        if dur<=0
                msgboxText =  'Duration cannot be <= 0.';
                title = 'ERPLAB: duration input error';
                errorfound(msgboxText, title);
                return
        end
        if ~isempty(find(flag<1 | flag>16, 1))
                msgboxText{1} =  'ERROR, flag cannot be greater than 16 nor lesser than 1';
                title = 'ERPLAB: Flag input';
                errorfound(msgboxText, title);
                return
        end        
        erpworkingmemory('pop_artflatline', {answer{1} answer{2} answer{3} answer{4} answer{5}});
        EEG.setname = [EEG.setname '_ad']; %suggest a new name
        [EEG com] = pop_artflatline(EEG, 'Twindow', testwindow, 'Threshold', ampth,...
                'Duration', dur, 'Channel', chanArray, 'Flag', flag, 'Review', 'on' );
        return
else
        p = inputParser;
        p.FunctionName  = mfilename;
        p.CaseSensitive = false;
        p.addRequired('EEG');
        
        t1 = single(EEG.xmin*1000);
        t2 = single(EEG.xmax*1000);
        p.addParamValue('Twindow', [t1 t2], @isnumeric);
        p.addParamValue('Threshold', 100, @isnumeric);
        p.addParamValue('Duration', 1000, @isnumeric);
        p.addParamValue('Channel', 1:EEG.nbchan, @isnumeric);
        p.addParamValue('Flag', 1, @isnumeric);
        p.addParamValue('Review', 'off', @ischar); % to open a window with the marked epochs
        
        p.parse(EEG, varargin{:});
        
        testwindow =  p.Results.Twindow;
        ampth      =  p.Results.Threshold;
        dur        =  p.Results.Duration;
        chanArray  =  p.Results.Channel; % avoids repeated channels
        flag       =  p.Results.Flag;
        
        if strcmpi(p.Results.Review, 'on')% to open a window with the marked epochs
                eprev = 1;
        else
                eprev = 0;
        end
        if ~isempty(find(chanArray<1 | chanArray>EEG.nbchan, 1))
                error('ERPLAB says: error at pop_artflatline(). Channel indices cannot be greater than EEG.nbchan')
        end
        if ~isempty(find(flag<1 | flag>16, 1))
                error('ERPLAB says: error at pop_artflatline(). Flag cannot be greater than 16 or lesser than 1')
        end
end

% chArraystr = vect2colon(chanArray);

fs       = EEG.srate;
nch      = length(chanArray);
ntrial   = EEG.trials;
dursam   = dur*fs/1000; %ms to sample

[p1 p2 checkw] = window2sample(EEG, testwindow, fs);

if checkw==1
        error('ERPLAB says: error at pop_artflatline(), time window cannot be larger than epoch.')
elseif checkw==2
        error('ERPLAB says: error at pop_artflatline(), too narrow time window')
end
if nch>EEG.nbchan
        error('ERPLAB says: error at pop_artflatline(), number of tested channels cannot be greater than total.')
end
if isempty(EEG.reject.rejmanual)
        EEG.reject.rejmanual  = zeros(1,ntrial);
        EEG.reject.rejmanualE = zeros(EEG.nbchan, ntrial);
end

interARcounter = zeros(1,ntrial); % internal counter, for statistics
fprintf('channel #\n ');

%
% Tests RT info
%
isRT = 1; % there is RT info by default
if ~isfield(EEG.EVENTLIST.bdf, 'rt')
        isRT = 0;
else
        valid_rt = nnz(~cellfun(@isempty,{EEG.EVENTLIST.bdf.rt}));
        if valid_rt==0
                isRT = 0;
        end
end

for ch=1:nch
        
        fprintf('%g ',chanArray(ch));
        
        for i=1:ntrial;
                
                dataline = EEG.data(chanArray(ch), p1:p2 ,i);
                captured = flatline(dataline, ampth, dursam);
                
                if captured
                        interARcounter(i) = 1;      % internal counter, for statistics
                        % flaf 1 is obligatory
                        [EEG errorm]= markartifacts(EEG, flag, chanArray, ch, i, isRT);
                        if errorm==1
                                error(['ERPLAB says: There was not latency at the epoch ' num2str(i)])
                        elseif errorm==2
                                error('ERPLAB says: invalid flag (0<=flag<=16)')
                        end
                end
        end
end
fprintf('\n');

% performance
perreject = nnz(interARcounter)/ntrial*100;
fprintf('pop_artflatline() rejected a %.1f %% of total trials.\n', perreject);
EEG = eeg_checkset( EEG );

namefig = 'Blocking/Flat line detection view';
if eprev==1
        pop_plotepoch4erp(EEG, namefig)
end

% flagstr = vect2colon(flag);
%
% com = sprintf( '%s = pop_artflatline( %s, %s, %s, %s, %s, %s);', ...
%       inputname(1), inputname(1), testwindow, vect2colon(ampth), num2str(dur), chArraystr, flagstr);
skipfields = {'EEG'};
fn  = fieldnames(p.Results);
com = sprintf( '%s  = pop_artflatline( %s ', inputname(1), inputname(1));
for q=1:length(fn)
        fn2com = fn{q};
        if ~ismember(fn2com, skipfields)
                fn2res = p.Results.(fn2com);
                if ~isempty(fn2res)
                        if ischar(fn2res)
                                if ~strcmpi(fn2res,'off')
                                        com = sprintf( '%s, ''%s'', ''%s''', com, fn2com, fn2res);
                                end
                        else
                                if iscell(fn2res)
                                        fn2resstr = vect2colon(cell2mat(fn2res), 'Sort','on');
                                        fnformat = '{%s}';
                                else
                                        fn2resstr = vect2colon(fn2res, 'Sort','on');
                                        fnformat = '%s';
                                end
                                com = sprintf( ['%s, ''%s'', ' fnformat], com, fn2com, fn2resstr);
                        end
                end
        end
end
com = sprintf( '%s );', com);
%
% Completion statement
%
msg2end
return