function varargout = interFilterBands(varargin)
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
% %   G U I   H E L P   I N F O R M A T I O N                                   % 
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
% interPSD m-file for interPSD.fig                                               
%                                                                               
%       The GUI is part of the LFP Analysis Package 2006 and is to be                
%       Launched from the Fron_Panel Window of the Package
%       
%                                                                                
%       The software is designed to provide the user with the ability to
%       
%       filter an LFP to view the individual bands or save them to the
%       workspace. 
% 
%       Importantly, there is the ability to notch-filter the data and save
%       the result to the workspace. This can then be re-analysed usig any
%       of the other features of the package so that a large 50Hz/60Hz
%       noise component can be removed
% 
%       To filter the bands click which bands you wish and enter any cusom
%       bands into the popup box separated by spaces such as 27 66 44 77.
%       This would create two bands of 27-66 and 44-77 Hz.
% 
%       A notch filter can also be applied to this data by entering the
%       notch corners into the pop-up window. These are entered in teh same
%       way so that 49-51 creates a notch filter with a stop-band of 49-51
%       Hz. 
% 
%       To only notch filter the data, ensure that no filter bands are
%       selected. The notch filter is implemented with a 500th order FIR
%       filter, which ensures a linear phase response in the pass bands.
%                                                                               
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 

%  This Software is distributed under the GNU General Public Liscence           % 
%  a copy of this liscence sould be accompany this software.                    % 
%                                                                               % 
% Copyright (C) 2006  Richard Peter                                             %
%                                                                               %  
% 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 2 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, write to the Free Software                   %
% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA %
%                                                                               % 
%                                                                               % 
%  For further information contact Richard Peter at                             % 
%  infinitybeckon@hotmail.com                                                   % 
%                                                                               %   
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 

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

% Choose default command line output for interFilterBands
handles.output = hObject;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialisation Code Goes Here

%%%%%%%%%%%%%%%%
%Userdata

%Read in the variables that have been passed to it from the front panel
%window
handles.userdata = varargin{1};
handles.user_start = varargin{2};
handles.user_end = varargin{3};
handles.tstep = varargin{4};

%  handles.userdata = evalin('base', 'AD01(1:1000)');
%%%%%%%%%%%%%%%%5

handles.Numfigs = 0;
%Define required variables
handles.NotchVals = [];
handles.CustomBands = [];
handles.alreadyfiltered = 0;

% Reset all Toggle Buttons/Checkboxes
refresh_window(handles);


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

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


% --- Outputs from this function are returned to the command line.
function varargout = interFilterBands_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;


% --- Executes on button press in DeltaButn.
function DeltaBtn_Callback(hObject, eventdata, handles)
% hObject    handle to DeltaButn (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 DeltaButn


% --- Executes on button press in ThetaBtn.
function ThetaBtn_Callback(hObject, eventdata, handles)
% hObject    handle to ThetaBtn (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 ThetaBtn


% --- Executes on button press in AlphaBtn.
function AlphaBtn_Callback(hObject, eventdata, handles)
% hObject    handle to AlphaBtn (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 AlphaBtn


% --- Executes on button press in BetaBtn.
function BetaBtn_Callback(hObject, eventdata, handles)
% hObject    handle to BetaBtn (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 BetaBtn


% --- Executes on button press in GamLBtn.
function GamLBtn_Callback(hObject, eventdata, handles)
% hObject    handle to GamLBtn (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 GamLBtn


% --- Executes on button press in radiobutton6.
function GamHBtn_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton6 (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 radiobutton6


% --- Executes on button press in radiobutton8.
function GamVHBtn_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton8 (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 radiobutton8

% --- Executes on button press in CunstomBtn.
function CustomBtn_Callback(hObject, eventdata, handles)
% hObject    handle to CunstomBtn (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 CunstomBtn

if(get(hObject,'Value') == 0)
    % We first check whether the toggle button has been turned on, 
    %Now we launch the NotchSet GUI
    set(handles.ChooseBandsTgl, 'Value', 0);
end %End if

%Save the handles structure
guidata(hObject, handles);
% End of Function


% --- Executes when the user cheks the Select all Bands Callback
% --- This simply select all the pre-defined frequency Bands
function SelectAllBands_Callback(hObject, eventdata, handles)
%Check to see if the user has selected/deselected
if(get(hObject,'Value') == get(hObject,'Max'))
    % Then checkbox is checked- select all defalut frequency bands
    set(handles.AlphaBtn,'Value',1);
    set(handles.BetaBtn,'Value',1);
    set(handles.DeltaBtn,'Value',1);
    set(handles.ThetaBtn,'Value',1);
    set(handles.GamLBtn,'Value',1);
    set(handles.GamHBtn,'Value',1);
    set(handles.GamVHBtn,'Value',1);
else 
    % The user wants top deselect all Frequency Bands
    set(handles.AlphaBtn,'Value',0);
    set(handles.BetaBtn,'Value',0);
    set(handles.DeltaBtn,'Value',0);
    set(handles.ThetaBtn,'Value',0);
    set(handles.GamLBtn,'Value',0);
    set(handles.GamHBtn,'Value',0);
    set(handles.GamVHBtn,'Value',0);
end %End If

% save the handles structure 
guidata(hObject, handles);
% End of Function            

% --- Executes on button press in JnAdjBands.
function JnAdjBands_Callback(hObject, eventdata, handles)
% hObject    handle to JnAdjBands (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 JnAdjBands


% --- Executes on button press in ChooseBandsTgl.
function ChooseBandsTgl_Callback(hObject, eventdata, handles)
% hObject    handle to ChooseBandsTgl (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 ChooseBandsTgl
% {1 = Pressed, 0 = Not Pressed}
if(get(hObject,'Value') == 1)
    % We first check whether the toggle button has been turned on, 
    % Then set the radio Button to selected (1)
    set(handles.CustomBtn, 'Value', 1);
    % Then get the user's bands
    [handles.CustomFilters, Y] = CustomFilters(handles);
    set(handles.ChooseBandsTgl, 'Value', Y);
    handles;
else %If its Been Un-Pressed 
    % Set the radio Button to unselected (0)
    set(handles.CustomBtn, 'Value', 0);
end %End if

% Update handles structure
guidata(hObject, handles);

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

% Hints: contents = get(hObject,'String') returns DefaultFilterList contents as cell array
%        contents{get(hObject,'Value')} returns selected item from DefaultFilterList
if get(hObject, 'Value') == 7 | get(hObject, 'Value') == 9
    set(handles.JnAdjBands, 'Enable', 'off');
    set(handles.JnAdjBands, 'Value', 0);
else
    set(handles.JnAdjBands, 'Enable', 'on');
end

% --- Executes during object creation, after setting all properties.
function DefaultFilterList_CreateFcn(hObject, eventdata, handles)
% hObject    handle to DefaultFilterList (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, change
%       'usewhitebg' to 0 to use default.  See ISPC and COMPUTER.
usewhitebg = 1;
if usewhitebg
    set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in DefaultFilterBtn.
% Whether the user wants a default filter or not
function DefaultFilterBtn_Callback(hObject, eventdata, handles)

% Hint: get(hObject,'Value') returns toggle state of DefaultFilterBtn
if get(hObject, 'Value') == 1
set(handles.OwnFilterBtn, 'Value', 0);          %deselect own filter radio button
set(handles.DefaultFilterList, 'Enable', 'on'); %Disable Dropdown menu
set(handles.OwnFilterDrpDown, 'Enable', 'off'); %Enable Default filter list
else
set(handles.OwnFilterBtn, 'Value', 1);          %select own filter button
set(handles.DefaultFilterList, 'Enable', 'off');%Enable Drop down menu
set(handles.OwnFilterDrpDown, 'Enable', 'on');  %Disable Default filter list
end


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

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


% --- Executes during object creation, after setting all properties.
function OwnFilterDrpDown_CreateFcn(hObject, eventdata, handles)
% hObject    handle to OwnFilterDrpDown (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.
usewhitebg = 1;
if usewhitebg
    set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


% --- Executes on button press in OwnFilterBtn. 
% - Whether the user wants their own filter type
function OwnFilterBtn_Callback(hObject, eventdata, handles)
% hObject    handle to OwnFilterBtn (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 OwnFilterBtn
if get(hObject, 'Value') == 1
set(handles.DefaultFilterBtn, 'Value', 0);
set(handles.DefaultFilterList, 'Enable', 'off');
set(handles.OwnFilterDrpDown, 'Enable', 'on');
else
set(handles.DefaultFilterBtn, 'Value', 1);
set(handles.DefaultFilterList, 'Enable', 'on');
set(handles.OwnFilterDrpDown, 'Enable', 'off');
end

% --- Executes on button press in GetOwnFilterTgl.
function GetOwnFilterTgl_Callback(hObject, eventdata, handles)
% hObject    handle to GetOwnFilterTgl (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 GetOwnFilterTgl


% --- Executes on button press in DefaultWdowBtn.


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

% Hints: contents = get(hObject,'String') returns DefaultWdowList contents as cell array
%        contents{get(hObject,'Value')} returns selected item from DefaultWdowList
if get(hObject, 'Value') == 7 | get(hObject, 'Value') == 9
    set(handles.JnAdjBands, 'Enable', 'off');
end
    
    

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

usewhitebg = 1;
if usewhitebg
    set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


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

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



% --- Executes on button press in ViewFilterBtn.
% --- Her the user wants to view the filter they have selected
function ViewFilterBtn_Callback(hObject, eventdata, handles)
%This Function Uses fvtool to visualise the filters that are required.
%   FVTOOL(B,A) launches the Filter Visualization Tool and computes 
%   the Magnitude Response for the filter defined by numerator and denominator 
%   coefficients in vectors B and A. 

handles.Lims = [];
%First Get the frequencies that are required
handles.Lims = GenerateLims(handles);

%Next generate filters to allow only these frequencies
handles.Filters = GenerateFilters(handles);

% if size(handles.Filters) ~=0
if(size(handles.Lims, 1) ~= 0 )
    if(GetSelected(handles.DefaultFilterList)>110 && GetSelected(handles.DefaultFilterList)<16)
        %If the user wants a FIR filter use freqs
        for ii = 1:size(handles.Lims, 1)
            fighandle = figure(handles.Numfigs+1);
            handles.Numfigs = handles.Numfigs+1;
            freqz(handles.Filters{(2*ii)-1}, handles.Filters{(2*ii)}, 512);
        end
    else
        %If the user wants any other filter use fvtool
        for ii = 1:size(handles.Lims, 1)
             fvtool(handles.Filters{(2*ii)-1}, handles.Filters{2*ii});
        end
    end
else
        errordlg('You must select a frequency band',...
            'Incorrect Selection','modal')
        
end
% else
%     errordlg('You must select a frequency band',...
%             'Incorrect Selection','modal')
% end %if No filters
% --- Executes on button press in ViewWdowBtn.
function ViewWdowBtn_Callback(hObject, eventdata, handles)
% hObject    handle to ViewWdowBtn (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 GoBtn.
% When the user wants to plot they click this.
function GoBtn_Callback(hObject, eventdata, handles)
% hObject    handle to GoBtn (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if get(hObject, 'Value')
if get(handles.SetNotchTgl, 'Value') && ~handles.alreadyfiltered 
        handles.alreadyfiltered = 1;
        %The user wants to use filters
        Coeffs = fir1(500, [handles.NotchVals]/handles.tstep*2, 'stop');
        handles.filterddata = filtfilt(Coeffs, 1,  handles.userdata);
else
    handles.filterddata = handles.userdata; 
end
handles.Lims = [];
handles.Lims = GenerateLims(handles);

%Next generate filters to allow only these frequencies
handles.Filters = GenerateFilters(handles);
T = handles.Filters{1};
%Now Filter the data and plot it
handles.plotme = [];
if(size(handles.Lims, 1) ~= 0 ) && length(T)>0
    % the user wants to see some separate signals, so lets filter the
    % signal and then store it for plotting
    if get(handles.UseFiltfiltBtn, 'Value')==1 
        for ii = 1:size(handles.Lims, 1)
            handles.plotme(ii, :) = ...
                filtfilt(handles.Filters{2*ii -1}, ...
                handles.Filters{2*ii}, handles.filterddata);
        end
    else
        for ii = 1:size(handles.Lims, 1)
            handles.plotme(ii, :) = ...
                filter(handles.Filters{2*ii -1}, ...
                handles.Filters{2*ii}, handles.filterddata);
        end
    end
    %now the plotting bit...
    %We ned to make a new plot and keep track of how many there are...
    %then make an x-axis
    %Then plot each set of data on its own subplot
    %then set a title and x-limits for each axis
    % finally, if its the last axis then add an x- axis label
    fighandle = figure (handles.Numfigs+1); % Generate a figure and store handle
    handles.Numfigs=handles.Numfigs+1; %Increment the number of figures
    h = newplot(fighandle); %Generate a new plot in the figure
    Axislabels = getaxislabels(handles); %Get a cell array of axis labels
    %next make an x-axis to plot against
    f = linspace(handles.user_start, handles.user_end, length(handles.filterddata));
    m = 0;
    if get(handles.PlotOrigSig, 'Value')
        m=1; %if they want the original signal add 1 onto everything else...
        %Now make an x- axis
        dataaxis = linspace(handles.user_start, handles.user_end,length(handles.userdata));
        %Next get the handle for the subplot and plot it
        h = subplot(size(handles.Lims, 1)+m,1,1); % get the handle of the subplot
        plot(h, dataaxis, handles.userdata); %Plot the graph
        xlim(h, [handles.user_start, handles.user_end]);
        title(h, 'Original Data');
        ylabel(h,  'Signal (mV)');
    end
    
    
    for t = 1+m:size(handles.Lims, 1)+m
        h = subplot(size(handles.Lims, 1)+m,1,t); % get the handle of the subplot
        plot(h, f, handles.plotme(t-m, :)); %Plot the graph
        xlim(h, [handles.user_start, handles.user_end]);
        title(h, Axislabels{t-m});
        ylabel(h,  'Signal (mV)');
        if(t-m == size(handles.Lims, 1))
            xlabel(h, 'Time (s)'); %If its the last graph, label the x-axis
        end % if
    end % for
    set(hObject, 'Value', 0);
else
    errordlg('You must select a frequency band',...
        'Incorrect Selection','modal')
    set(hObject, 'Value', 0);
end

% Update handles structure
guidata(hObject, handles);
%End of Function
end 

%This Function Simply sets the Button values back to their default values.
%It is useful to know when a Window has been refreshed whilst designing 
function refresh_window(handles)
    %First set the frequecny bands Box...
    %FTo start check the SelectallBands box
    set(handles.SelectAllBands, 'Value', 0);
    %Now when we call its callback it will clear the selection of all the
    %Frequency Bands Radio buttons
    SelectAllBands_Callback(handles.SelectAllBands, handles, handles)
    %next the rest of the Frequency bands Panel
    set(handles.JnAdjBands, 'Value', 0);
    set(handles.CustomBtn, 'Value', 0);
    set(handles.ChooseBandsTgl,'Value', 0);
    set(handles.SetNotchTgl,'Value', 0);

    %Now set the Filter panel
    set(handles.DefaultFilterBtn,'Value', 1);
    set(handles.OwnFilterBtn,'Value', 0);
    set(handles.GetOwnFilterTgl,'Value', 0);
    %then Disable the Dropdown Menu
    set(handles.OwnFilterDrpDown,'Enable', 'off');
    set(handles.DefaultFilterList,'Enable', 'on');

    

% This Function Gets the Limits filters requested...
% Let us ensure that the output is a cell array of filter coefficients where 
% the top row is B coefficients and the second row is A coefficients called 
% 'Coefficients'.
%
% In addition an array (Lims) comprising a two column vector  of 
% frequency ranges. These will be the
% start and stop frequencies of each of the filters designed .
%
% The number of rows in the 2-column vector (Lims) will therefore equal the
% number of elements in the cell array of coefficients (Coefficients).

function [Lims] = GenerateLims(handles)
%First create boolean variables to describe the requirements:
Join = get(handles.JnAdjBands, 'Value');        %Join Adjacent bands?
CustomT = get(handles.ChooseBandsTgl, 'Value'); %User's Custom Bands?


%Next get the frequency bands that are selected...
%Bands is an array of start/stop frequencies
%BandBool is a bollean array of which bands are selected.
[Bands, BandBool] = GetFrequencyBands(handles);
Bands = Bands';
%Next we see how many filters are required (Numfilts)
LBool = bwlabel(BandBool);
Numfilts = max(LBool);


% If the user wants to join frequency bands
if Join ==1 && Numfilts>0
    %The user wants to join the frequency Bands together...
    ii = [];
    NewBands = [];
    for ii= 1:Numfilts
        F = find(LBool == ii);  %Finds all adjacent entries
        Min = min(Bands(F, 1)); %Find the minimum of the minimums 
        Max = max(Bands(F, 2)); %Find the maximum of the maximums
        NewBands(ii, (1: 2)) = [Min Max];
    end %For
    %NewBands are the uppr and lowe limits of each requested  band in a 
    % nx2 array. Where n is the number of required filters, Numfilts. 
    count = ii;
else
    count =1;
    NewBands = [];
    %F will store the place values of the bands that the user doesn't want 
    F = find(Bands(:, 1)== 999);
    
    if length(F) ==0
        F = 999;
    end
    %F is now the places of the unwanted frequency Bands within Bands
    for ii = 1:size(Bands, 1)
        if ii ~= F
            %If its not in F then add it to NewBands
           NewBands(count, (1: 2)) = Bands(ii, 1:2); 
           count = count+1;
        end % If 
    end %for ii
    %NewBands are the uppr and lower limits of each band in a nx2 array.
    % Where n is the number of required filters.

end %if Join =1

%If the User has defined custom Bands
if CustomT == 1
    NumCust = length(handles.CustomFilters); %NumCust=the number defined
    for ii = 1:2:NumCust           

        %Append each filter's limits to NewBands   
        NewBands(count, (1:2)) = handles.CustomFilters(ii:ii+1);
        %increment the count
        count = count+1;
    end %for
end %if

%set Lims to NewBands as these are the limits we wish to create filters for
Lims = NewBands; 

%End Of Function
    
    
% --- This function generates a 2xn array of frequency limits (from the
% --- frequency bands selected)
function [Bands Bool] = GetFrequencyBands(handles)
Bands = []; %initialise the Bnads Variable 
% %Now check to see if each band is required
Bool = Bandmask(handles);
 IndexSelected = GetSelected(handles.DefaultFilterList); %Find its index
 if(IndexSelected==7)
     %If the user wants a chebyshev filter...
     Freqs  = [0.55 7.5; 2.66 12; 5.7 19.7; 9.05 46; 22 68; 33 146.7; 76.5 189]' ;
 elseif IndexSelected==8
     Freqs  = [0.43 9.5; 2.18 14.5; 4.9 22.9; 7.52 55.5; 19 78; 27.1 171.5; 67.4 208.2]';
 elseif IndexSelected==10
    % The user wants a FIR filter. 
    %These next frequency limits shift the attenuation from -6dB at the
    %passband limits to -3dB.
     Freqs = [0.8 4.2; 3.8 8.2; 7.2 14.2; 13.8 30.2; 29.8 50.2; 49.8 100.2; 99.8 150.2]';
         
 else
     Freqs = [1 4; 4 8; 8 14; 14 30; 30 50; 50 100; 100 150]';
 end
Bands(1, :) = Freqs(1, :).*Bool;
Bands(1, :) = (Bands(1, :)==0).*999 +Bands(1, :);
Bands(2, :) = Freqs(2, :).*Bool;
handles;
% End Of Function

%the next function is called by the get axis labels function. it returns
%the corner frequencies of the selected frequency bands and a boolean of
%which bands were selecetd.
function [Bands Bool] = GetFrequencyBandLabels(handles)
Bands = []; %initialise the Bnads Variable 
% %Now check to see if each band is required
Bool = Bandmask(handles);
Freqs = [1 4; 4 8; 8 14; 14 30; 30 50; 50 100; 100 150]';
Bands(1, :) = Freqs(1, :).*Bool;
Bands(1, :) = (Bands(1, :)==0).*999 +Bands(1, :);
Bands(2, :) = Freqs(2, :).*Bool;
handles;
%End of Function


function Userfilter = GenerateFilters(handles)
if length(handles.Lims)==0
    Userfilter = [];
    return
else
    if(get(handles.DefaultFilterBtn, 'Value') == 1)
        % If the user wants a default filter we must make it
        Userfilter = {};
        IndexSelected = GetSelected(handles.DefaultFilterList); %Find its index
        if(IndexSelected>1 &&IndexSelected<6)
            %The user has Selected a butterworth filter.
            %for bandpass filters, butter returns a 2*n filter...
            %these increase in order from 2, 4, 6, 8,  ie 2* {1, 2, 3, 4}
            %Which happens to be the values of our index, how fortunate!
            for ii = 1:size(handles.Lims, 1)
                W = [handles.Lims(ii, 1:2)]./500;
                [Userfilter{(2*ii)-1},Userfilter{2*ii}]  = butter((IndexSelected), W);
            end
        elseif IndexSelected==7
            %The User wants a Chebyshev filter of 20dB attenuation and order 4
            % The correct frequency limits for this filter are saved in Flims

            ii = [];
            for ii = 1:size(handles.Lims, 1)
                W = [handles.Lims(ii, 1:2)]./500;
                [Userfilter{(2*ii)-1},Userfilter{2*ii}] = cheby2(2, 20, W);
            end
            elseif IndexSelected==8
            %The User wants a Chebyshev filter of 20dB attenuation and order 4
            % The correct frequency limits for this filter are saved in Flims

            ii = [];
            for ii = 1:size(handles.Lims, 1)
                W = [handles.Lims(ii, 1:2)]./500;
                [Userfilter{(2*ii)-1},Userfilter{2*ii}] = cheby2(3, 40, W);
            end
        elseif(IndexSelected == 10)
            %The User wants a FIR filter order 20, 40, 250, 350, 500  ie
            %not a power of ii.
            ii = [];
            for ii = 1:size(handles.Lims, 1)
                W = ([handles.Lims(ii, 1:2)]/500);
                Userfilter{(2*ii -1)} = fir1(2000, W);
                Userfilter{(2*ii)} = 1;
            end
        elseif(IndexSelected>16 && IndexSelected<21)
            %The User wants a FIR filter order 20, 40, 250, 350, 500  ie
            %not a power of ii.
            FIRn = [500 1000 2000 4000];
            FIRn = FIRn(IndexSelected - 16);
            ii = [];
            for ii = 1:size(handles.Lims, 1)
                W = [handles.Lims(ii, 1:2)];
                W = [W(1)-0.01 W W(2)+0.01];
                Userfilter{(2*ii -1)} = fir2(FIRn, [0 W/500 1], [0 0 1 1 0 0] );
                Userfilter{(2*ii)} = 1;
            end
        else
            errordlg('You have not selected a valid filter',...
                'Incorrect Selection','modal')
            Userfilter{1} = [];

        end
    else
        %The user wants to define their own filter function then we must have
        %stored it somewhere...
        errordlg('You cannot choose your own filter yet. Sorry.',...
            'Not ready!!!','modal')
        Userfilter{1} = [];
    end
end %If Lims = [];
%End Of Function    

%This function determines the filter that is selected from the default box
function var1 = GetSelected(handlesItem)


index_selected = get(handlesItem,'Value');
if length(index_selected) ~= 1
    errordlg('You must select only one variable.',...
            'Incorrect Selection','modal')
else
    var1 = index_selected(1);
end 

%This function generates a cell array of axis labels for use when plotting
%It is called by the GoBtn_Callback function
function AxLabels = getaxislabels(handles)
[Bands Bool] = GetFrequencyBandLabels(handles);
Bands = Bands';
LBool = bwlabel(Bool);
ii = [];
if get(handles.JnAdjBands, 'Value')
    for ii = 1:max(LBool)
        %To save on memory, the following two variables have been put
        %directly into the AxLabels assignemnt line
        %Min = min(Bands( find(LBool==ii), 1));
        %Max = max(Bands( find(LBool==ii), 2));
        AxLabels{ii} = strcat(num2str(min(Bands( find(LBool==ii), 1))), '-',...
            num2str(max(Bands( find(LBool==ii), 2))), '_Hz');
    end
else
    %Find the elements that are needed
    F = find(Bool==1);
    %Now go through each elelment and add its label
    for ii = 1:sum(Bool)
        AxLabels{ii} = strcat(num2str(Bands(F(ii),1)), '-',...
            num2str(Bands(F(ii),2)), ' Hz');
    end
end

%Now add the labels of custom bands
if get(handles.ChooseBandsTgl, 'Value')
    F=handles.CustomFilters;
    iii = [];
    for iii = 1:2:length(F)
        Min = F(iii);
        Max = F(iii+1);
        ii = ii+1;
        AxLabels{ii} = strcat(num2str(Min), '-', num2str(Max), ' Hz');
    end
end
%Generates a mask of the Frequency bands selected 1 = selected, 0 = not
%selected. It is called by GetFrequencyBands and getaxislabels.
function Mask = Bandmask(handles)

Mask = [get(handles.DeltaBtn, 'Value'), get(handles.ThetaBtn, 'Value'),...
    get(handles.AlphaBtn, 'Value'), get(handles.BetaBtn, 'Value'),...
    get(handles.GamLBtn, 'Value'), get(handles.GamHBtn, 'Value'),...
    get(handles.GamVHBtn, 'Value')];


% --- Executes on button press in SetNotchTgl.
function SetNotchTgl_Callback(hObject, eventdata, handles)
% hObject    handle to SetNotchTgl (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 SetNotchTgl

if(get(hObject,'Value') == get(hObject,'Max'))
    % We first check whether the toggle button has been turned on, 
    %Next we create an empty vector of Notch limits
    %Now we launch the NotchSet GUI
    [handles.NotchVals, Y] = NotchSet(handles);
    set(handles.SetNotchTgl, 'Value', Y);
end %End if

%Save the handles structure
guidata(hObject, handles);
% End of Function



% --- Executes on button press in PlotSigCQ.
function PlotSigCQ_Callback(hObject, eventdata, handles)
% hObject    handle to PlotSigCQ (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 PlotSigCQ




% --- Executes on button press in PlotOrigSig.
function PlotOrigSig_Callback(hObject, eventdata, handles)
% hObject    handle to PlotOrigSig (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 PlotOrigSig




% --- Executes on button press in ExportToWorkspace.
function ExportToWorkspace_Callback(hObject, eventdata, handles)
% Hint: get(hObject,'Value') returns toggle state of ExportToWorkspace
if get(hObject, 'Value')
    %The user wants to export
    if get(handles.SetNotchTgl, 'Value') 
       %The user wants to use filters
        Coeffs = fir1(500, [handles.NotchVals]/handles.tstep*2, 'stop');
        handles.filterddata = filtfilt(Coeffs, 1,  handles.userdata);
    else
        handles.filterddata = handles.userdata;
    end
    t = find((handles.filterddata == handles.userdata)==1);
    %If filtereddata and userdata are identical , then
    %length(t)==length(userdata)
    handles.Lims = [];
    handles.Lims = GenerateLims(handles);

    %Next generate filters to allow only these frequencies
    handles.Filters = GenerateFilters(handles);
    [Bands Bool] = GetFrequencyBands(handles);
    %Now Filter the data and plot it
    handles.plotme = [];

    if(size(handles.Lims, 1) ~= 0)
        % the user wants to see some separate signals, so lets filter the
        % signal and then store it for plotting
        if get(handles.UseFiltfiltBtn, 'Value')==1
            for ii = 1:size(handles.Lims, 1)
                handles.plotme(ii, :) = ...
                    filtfilt(handles.Filters{2*ii -1}, ...
                    handles.Filters{2*ii}, handles.filterddata);
            end
        else
            for ii = 1:size(handles.Lims, 1)
                handles.plotme(ii, :) = ...
                    filter(handles.Filters{2*ii -1}, ...
                    handles.Filters{2*ii}, handles.filterddata);
            end
        end


        Varlabels = getvarlabels(handles); %Get a cell array of axis labels

        for t = 1:size(handles.Lims, 1)
            assignin('base', Varlabels{t}, handles.plotme(t, :)); %assign data
        end % for
    
    elseif length(find(Bool==1))==0 && ~(length(t)==length(handles.userdata))
        assignin('base', 'Notch_Filtered_Data', handles.filterddata); %assign data
    else
        errordlg('You have not selected a filter or notch filter.',...
            'Incorrect Selection','modal')
    end

    % Update handles structure
    guidata(hObject, handles);
    %Reset the toggle button to out so taht user knows its finished
    set(hObject, 'Value', 0)
end


function VarLabels = getvarlabels(handles)
[Bands Bool] = GetFrequencyBandLabels(handles);
Bands = Bands';
LBool = bwlabel(Bool);
ii = [];
if get(handles.JnAdjBands, 'Value')
    for ii = 1:max(LBool)
        %To save on memory, the following two variables have been put
        %directly into the AxLabels assignemnt line
        %Min = min(Bands( find(LBool==ii), 1));
        %Max = max(Bands( find(LBool==ii), 2));
        %The round term is needed because variable names cannot have
        %decimal points in them
        VarLabels{ii} = strcat('Filtered_', num2str(round(min(Bands( find(LBool==ii), 1)))), '_',...
            num2str(round(max(Bands( find(LBool==ii), 2)))));
    end
else
    %Find the elements that are needed
    F = find(Bool==1);
    %Now go through each elelment and add its label
    for ii = 1:sum(Bool)
        VarLabels{ii} = strcat('Filtered_', num2str(round(Bands(F(ii),1))), '_',...
            num2str(round(Bands(F(ii),2))));
    end
end

%Now add the labels of custom bands
if get(handles.ChooseBandsTgl, 'Value')
    F=handles.CustomFilters;
    iii = [];
    for iii = 1:2:length(F)
        Min = round(F(iii));
        Max = round(F(iii+1));
        ii = ii+1;
        VarLabels{ii} = strcat('Filtered_',num2str(Min), '_', num2str(Max));
    end
end


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

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


