function varargout = gui(varargin)
% copyright E T Rolls, Oxford Centre for Computational Neuroscience
% We use here a local version of EFR named EFRlayer, which is for one layer. 
% This ensures that we do not overwrite EFR
%
% GUI MATLAB code for gui.fig
%      GUI, by itself, creates a new GUI or raises the existing
%      singleton*.
%
%      H = GUI returns the handle to a new GUI or the handle to
%      the existing singleton*.
%
%      GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GUI.M with the given input arguments.
%
%      GUI('Property','Value',...) creates a new GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before gui_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to gui_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 gui

% Last Modified by GUIDE v2.5 10-Jan-2013 22:27:48

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @gui_OpeningFcn, ...
                   'gui_OutputFcn',  @gui_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
end

% The following handles a mouse click in window 1, the firing rate array
%Click listener, get mouseclick coords and update plot
function click_it(src, evt, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% % handles    structure with handles and user data (see GUIDATA)

global EFR EFRDATA NLAYERS NET_SIZE SQNET_SIZE N_FILES N_GROUPS N_VIEWS N_LOCS BESTCELLS NBESTCELLS ...
       NBESTCELLSINFORM NTRANSFORMS PARAMETER_LIST SYNMAT SYNMAT_CHANGE ...
       SYNMAT_CHANGE_GROUP LOGNUM FIXEDTRACE SPARSENESS BETA ETA LRNRATE NSYN SYNMATL1 SYNMATL2 SYNMATL3 ...
       SYNMATL4 VNLOGINDEX IMLIST IMLIST_TEST N_VIEWS_TEST FILTIM NSYNL1 Images base_dir image_dir ...
       FiltImSize SqFiltImSize Display ...
       filter_layer_1 filter_layer_2  filter_layer_3 filter_layer_4 SIGMOID LATERALINHIB TraceDisp DisplaySYNMATprevious
   
    axes(handles.axes1);
    cp=get(handles.axes1,'CurrentPoint');
    %cp seems to run from 1,1 (Upper Left) to 128, 128, (Lower Right)
    %So, I use C indexing by subtracting 1
    X = floor(cp(1,1)+0.5);
    Y = floor(cp(2,2)+0.5);
    if X <= NET_SIZE && X >= 1 && Y <= NET_SIZE && Y >= 1
        set(handles.editX, 'String', X);
        set(handles.editY, 'String', Y);
        %Cell = ((X - 1) * NET_SIZE) + Y; % For C
        Cell = ((Y - 1) * NET_SIZE) + X; % For Matlab
        set(handles.editCell, 'String', Cell); % Set the cell number too from a click in the firing rate window
        plot_it(handles);
        disp(['Cell=' num2str(Cell)]);
    end
end

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% This is called by the Update button

global EFR EFRDATA NLAYERS NET_SIZE SQNET_SIZE N_FILES N_GROUPS N_VIEWS N_LOCS BESTCELLS NBESTCELLS ...
       NBESTCELLSINFORM NTRANSFORMS PARAMETER_LIST SYNMAT SYNMAT_CHANGE ...
       SYNMAT_CHANGE_GROUP LOGNUM FIXEDTRACE SPARSENESS BETA ETA LRNRATE NSYN SYNMATL1 SYNMATL2 SYNMATL3 ...
       SYNMATL4 VNLOGINDEX IMLIST IMLIST_TEST N_VIEWS_TEST FILTIM NSYNL1 Images base_dir image_dir ...
       FiltImSize SqFiltImSize Display ...
       filter_layer_1 filter_layer_2  filter_layer_3 filter_layer_4 SIGMOID LATERALINHIB TraceDisp DisplaySYNMATprevious

    Cell = str2double(get(handles.editCell, 'String'));
    Y = floor((Cell / NET_SIZE));
    X = mod(Cell, NET_SIZE);
    if X <= NET_SIZE && X >= 1 && Y <= NET_SIZE && Y >= 1
        set(handles.editX, 'String', X);
        set(handles.editY, 'String', Y);
        plot_it(handles);
    end
end

% Plot the EFR and Rates
function plot_it(handles)

global EFR EFRDATA NLAYERS NET_SIZE SQNET_SIZE N_FILES N_GROUPS N_VIEWS N_LOCS BESTCELLS NBESTCELLS ...
       NBESTCELLSINFORM NTRANSFORMS PARAMETER_LIST SYNMAT SYNMAT_CHANGE ...
       SYNMAT_CHANGE_GROUP LOGNUM FIXEDTRACE SPARSENESS BETA ETA LRNRATE NSYN SYNMATL1 SYNMATL2 SYNMATL3 ...
       SYNMATL4 VNLOGINDEX IMLIST IMLIST_TEST N_VIEWS_TEST FILTIM NSYNL1 Images base_dir image_dir ...
       FiltImSize SqFiltImSize Display ...
       filter_layer_1 filter_layer_2  filter_layer_3 filter_layer_4 SIGMOID LATERALINHIB TraceDisp DisplaySYNMATprevious

    % Use 1 indexing for VisNetMat
    X = str2double(get(handles.editX, 'String')); 
    Y = str2double(get(handles.editY, 'String'));
    L = str2double(get(handles.editL, 'String'));
    Group = str2double(get(handles.editGroup, 'String')); 
    View = str2double(get(handles.editView, 'String'));
    Loc = str2double(get(handles.editLoc, 'String')); % Loc is not used in this version of VisNet
    Loc = 1; % This version does not implement Loc, so leave it at 1
    Cell = str2double(get(handles.editCell, 'String'));
    
    % Plot EFR
    axes(handles.axes1);
    cla;
    hold off;
    PointToMat = matfile('../VNanalysis/Sweep.mat'); % caution here. Make sure that this is from the current run
    round(Group);
    round(View);
    if View > N_VIEWS; View = N_VIEWS; end
    if View < 1; View = 1; end
    round(Loc);
    round(L);
    EFRlayer = PointToMat.EFRDATA(Group,View,L,:);
    EFRlayer = reshape(EFRlayer, [NET_SIZE NET_SIZE]);
    imshow(EFRlayer');
    %save Rateslayer EFRlayer % comment this out when it is not needed
    title(['Firing Rates layer ', num2str(L)]);
    drawnow;
    %register a click handler function
    set(gcf,'WindowButtonDownFcn',{@click_it, handles})
      
    % Plot Rates
    %figure()
    axes(handles.axes4);
    cla;
    %hp=gca;
    %set(hp, 'FontSize', 12);
    hold off;
    cell = ((Y - 1) * NET_SIZE) + X;
    rates = PointToMat.EFRDATA(:,:,L,cell);
    rates = reshape(rates, [N_GROUPS N_VIEWS_TEST]);
    %rates = reshape(rates, [N_GROUPS N_VIEWS * N_LOCS]); % 11 Feb 2020
    rates
    
    save('NeuronRates','rates', 'N_GROUPS', 'N_VIEWS_TEST', 'N_LOCS', '-v7.3');

    MeanRates = mean(rates')
    %rates;
    DotProduct = zeros(N_GROUPS);
    for i = 1 : N_GROUPS
        for j = 1 : N_GROUPS
%            distance(j,i) = norm(rates(i,:) - rates(j,:));
            DotProduct(j,i) = dot(rates(i,:)', rates(j,:)');
        end
    end
    % DotProduct
    ntransforms = double(N_VIEWS_TEST * N_LOCS);
    DotProduct = DotProduct / ntransforms    % correlated firing rate vectors have a max of 1   
    % DispNeuronRates(Cell, L)
    plot(handles.axes4, rates','-o','LineWidth',2);
    xlength = N_VIEWS_TEST * N_LOCS;
    xmin = 1.0; ymax = 1.5; ymin = -0.1;
    axis(handles.axes4, [xmin xlength ymin ymax]);
    axis manual;
    %axis(handles.axes4, [0 18 -0.2 1.4]); % this works!
    xlabel('Transforms'); 
    ylabel('Rates');
    title('Firing Rate to each object as a function of the transforms');
    
    % Construct a legend for rates figure
    labels_ = {};
    for i = 1 : N_GROUPS
        labels_(i) = {strcat('Obj', num2str(i))};
    end
    legend(labels_);
    drawnow;
    
    %Handle Gauss, Point, Filter
    if L == 1 
        %calllib('libvisnet', 'calculate_input_connections', X, Y);
        %filt_disp(handles); 
    end

    %Plot Image
    % The image from e.g. /home/erolls/imagedata/jan_calibration/bmw_0.0.filtered/bmw_0.0.image  
    % is a 128*128 image with #define IMAGE_SIZE 128 in VNHeader.h
    % This 128*128 image shows a 64*64 version of the image in a 128*128 background
    % The real filtered files are of a 256*256 image in a 512*512
    % background, with file length 262144 bytes
    axes(handles.axes9);
    cla;
    hold off;
    Xloc = 1; %XY_VIEW(Loc, 1); % the x location in which the image was presented
    Yloc = 1; %XY_VIEW(Loc, 2);
    group=Group;
    view=View;
    %file = (Group) * N_VIEWS_TEST + (View)
    im = view + (group - 1) * N_VIEWS_TEST   % the image numbers start at 1, with N_VIEWS images or files per group
    image_name = char(IMLIST_TEST(im, 1));
    image_dir = strcat(base_dir, image_name, '.filtered/');
    disp(strcat(image_dir, image_name,'.image'));
    f_image = fopen(strcat(image_dir, image_name,'.image'), 'r');
    ima = fread(f_image);
    fclose(f_image);
    ima = reshape(ima, 128, 128); % next show the central 64x64 part
    ima= imcrop(ima, [32 32 64 64]); % [xmin ymin width height]. crop the middle
    ima = imresize(ima, 2);
    imagesc(ima');
    colormap(gray);
    title(['Object ', num2str(group), '   View ', num2str(view)]);
end

% Plot the Gaussian, Point, and Filter Sum Window
function filt_disp(handles)
    return; % not yet implemented for VisNetMat
    
    % Point
    axes(handles.axes5);
    %PointPtr = calllib('libvisnet', 'point_disp');
    %point_disp[N_FILTER_TYPES * (DISPLAY_SIZE + 10) + 10][N_FILTER_FREQS * (DISPLAY_SIZE + 10) + 10];
    N_FILTER_TYPES = 8; % all in VNHeader.h
    DISPLAY_SIZE = 512;
    N_FILTER_FREQS = 4; % edit this depending on the value in VNHeader.h
    npts = (N_FILTER_TYPES * (DISPLAY_SIZE + 10) + 10) * (N_FILTER_FREQS * (DISPLAY_SIZE + 10) + 10);
    %setdatatype(PointPtr, 'singlePtr', 1, npts); % nrow, ncol
    %calllib('libvisnet', 'display_point');
    imagesc(reshape(PointPtr.Value, [(N_FILTER_FREQS * (DISPLAY_SIZE + 10) + 10)   (N_FILTER_TYPES * (DISPLAY_SIZE + 10) + 10)]));

    title('Connections to the Filters'); 
    % ylabel('Spatial frequency');
    
    %Gauss
    axes(handles.axes6);
    cla;
    hold off;
    %GaussPtr = calllib('libvisnet', 'gauss_disp');
    %setdatatype(GaussPtr, 'singlePtr', 1, npts); % nrow, ncol
    %calllib('libvisnet', 'display_gauss');
    %max(GaussPtr.Value);
    % imagesc(reshape(GaussPtr.Value, [4186 4186]));
    %imagesc(reshape(GaussPtr.Value, [(N_FILTER_FREQS * (DISPLAY_SIZE + 10) + 10)   (N_FILTER_TYPES * (DISPLAY_SIZE + 10) + 10)]));
    %colormap([0, 0, 0])
    title('Gabor Filters');

    %Filter Sum
    axes(handles.axes7);
    cla;
    hold off;
    %calllib('libvisnet', 'display_filter_sum');
    %FilterSumPtr = calllib('libvisnet', 'filter_sum_disp');
    %setdatatype(FilterSumPtr, 'singlePtr', 1, 512 * 512); % nrow, ncol
    %imagesc(reshape(FilterSumPtr.Value, [512 512])'); % ETR transpose needed
    %title('Filter Sum');
end

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

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

% Update handles structure
guidata(hObject, handles);

global EFR EFRDATA NLAYERS NET_SIZE SQNET_SIZE N_FILES N_GROUPS N_VIEWS N_LOCS BESTCELLS NBESTCELLS ...
       NBESTCELLSINFORM NTRANSFORMS PARAMETER_LIST SYNMAT SYNMAT_CHANGE ...
       SYNMAT_CHANGE_GROUP LOGNUM FIXEDTRACE SPARSENESS BETA ETA LRNRATE NSYN SYNMATL1 SYNMATL2 SYNMATL3 ...
       SYNMATL4 VNLOGINDEX IMLIST IMLIST_TEST N_VIEWS_TEST FILTIM NSYNL1 Images base_dir image_dir ...
       FiltImSize SqFiltImSize Display ...
       filter_layer_1 filter_layer_2  filter_layer_3 filter_layer_4 SIGMOID LATERALINHIB TraceDisp DisplaySYNMATprevious

%calllib('libvisnet', 'initialise_display_arrays');

% This sets up the initial plot - only do when we are invisible
% so window can get raised using gui.
if strcmp(get(hObject,'Visible'),'off')
   plot_it(handles)
end
end

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

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

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

% --------------------------------------------------------------------
function OpenMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to OpenMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
file = uigetfile('*.fig');
if ~isequal(file, 0)
    open(file);
end
end


% --------------------------------------------------------------------
function PrintMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to PrintMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
printdlg(handles.figure1)
end

% --------------------------------------------------------------------
function CloseMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to CloseMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
selection = questdlg(['Close ' get(handles.figure1,'Name') '?'],...
                     ['Close ' get(handles.figure1,'Name') '...'],...
                     'Yes','No','Yes');
if strcmp(selection,'No')
    return;
end

delete(handles.figure1)
end

function editX_Callback(hObject, eventdata, handles)
% hObject    handle to editX (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 editX as text
%        str2double(get(hObject,'String')) returns contents of editX as a double
end

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


function editY_Callback(hObject, eventdata, handles)
% hObject    handle to editY (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 editY as text
%        str2double(get(hObject,'String')) returns contents of editY as a double
end

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

function editL_Callback(hObject, eventdata, handles)
% hObject    handle to editL (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 editL as text
%        str2double(get(hObject,'String')) returns contents of editL as a double
end

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

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

% Hint: place code in OpeningFcn to populate axes4
end

function editGroup_Callback(hObject, eventdata, handles)
% hObject    handle to editGroup (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 editGroup as text
%        str2double(get(hObject,'String')) returns contents of editGroup as a double
end

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


function editView_Callback(hObject, eventdata, handles)
% hObject    handle to editView (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 editView as text
%        str2double(get(hObject,'String')) returns contents of editView as a double
end

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

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

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

% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% This is the Clear button
%calllib('libvisnet', 'clear_filter_disp');
filt_disp(handles); % redisplay the cleared arrays
end


% --- Executes on mouse press over axes background.
function axes1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
end

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


function editCell_Callback(hObject, eventdata, handles)
% hObject    handle to editCell (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 editCell as text
%        str2double(get(hObject,'String')) returns contents of editCell as a double
end

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


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

% Hint: place code in OpeningFcn to populate axes9
end
