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

% Last Modified by GUIDE v2.5 28-Nov-2012 13:36:36

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

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

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

set(handles.phase_axes,'View',[get(handles.camx,'Value'),get(handles.camy,'Value')]);
% set(handles.alpha_slider,'Value',get(handles.alpha_slider,'Min'))
% set(handles.beta_slider,'Value',get(handles.beta_slider,'Min'))
% set(handles.g1_slider,'Value',get(handles.g1_slider,'Min'))
% set(handles.g2_slider,'Value',get(handles.g2_slider,'Min'))
% set(handles.gcs_slider,'Value',get(handles.gcs_slider,'Min'))
% set(handles.alpha_slider,'Value',8); 
% set(handles.beta_slider,'Value',15); 
% set(handles.g1_slider,'Value',8/7); 
% set(handles.g2_slider,'Value',3/64);
set(handles.alpha_slider,'Value',10.8); 
set(handles.beta_slider,'Value',13.54); 
set(handles.g1_slider,'Value',1.03); 
set(handles.g2_slider,'Value',0.044);
set(handles.gcs_slider,'Value',0.8);

set(handles.alpha_disp_text,'String',num2str(get(handles.alpha_slider,'Value')));
set(handles.beta_disp_text,'String',num2str(get(handles.beta_slider,'Value')));
set(handles.g1_disp_text,'String',num2str(get(handles.g1_slider,'Value')));
set(handles.g2_disp_text,'String',num2str(get(handles.g2_slider,'Value')));
set(handles.gcs_disp_text,'String',num2str(0))

set(handles.gui_timer_edit,'String','0.1');

sysdims=length(mysys);

dimchosetext={}; for i=1:sysdims; dimchosetext{end+1}=num2str(i); end
set(handles.dim1_popupmenu,'String',dimchosetext,'Value',1);
set(handles.dim2_popupmenu,'String',dimchosetext,'Value',2);
set(handles.dim3_popupmenu,'String',dimchosetext,'Value',sysdims-1);
set(handles.sound_left_popup,'String',dimchosetext,'Value',1);
set(handles.sound_right_popup,'String',dimchosetext,'Value',sysdims);
global Y;
global T;
Y=zeros(2,sysdims);
T=[0 0.1]';
handles.aplayer = audioplayer(Y,get(handles.sound_freq_slider,'Value'));

global chualabels;
chualabels={'Ch1 V1','Ch1 V2','Ch1 Ri','Ch2 V1','Ch2 V2','Ch2 Ri'};
xlabel(handles.dim1_axes, 't');
ylabel(handles.dim1_axes,  chualabels(get(handles.dim1_popupmenu,'Value')));
xlabel(handles.dim2_axes, 't');
ylabel(handles.dim2_axes,  chualabels(get(handles.dim2_popupmenu,'Value')));
xlabel(handles.dim3_axes, 't');
ylabel(handles.dim3_axes,  chualabels(get(handles.dim3_popupmenu,'Value')));
xlabel(handles.phase_axes, chualabels(get(handles.dim1_popupmenu,'Value')));
ylabel(handles.phase_axes, chualabels(get(handles.dim2_popupmenu,'Value')));
zlabel(handles.phase_axes, chualabels(get(handles.dim3_popupmenu,'Value')));

handles.timem = timer('BusyMode','queue','ExecutionMode','fixedRate', 'Period', str2double(get(handles.gui_timer_edit,'String')), 'Tag', 'gui_timer','TimerFcn', {@gui_timer_callback,handles},'StartFcn', {@gui_timer_startcallback,handles});
% Update handles structure
guidata(hObject, handles);

function gui_timer_startcallback(obj, event, handles)
global Y;
global T;
global Y2;
global T2;

cla(handles.phase_axes);
cla(handles.dim1_axes);
cla(handles.dim2_axes);
cla(handles.dim3_axes);

params=[get(handles.alpha_slider,'Value') get(handles.beta_slider,'Value') get(handles.g1_slider,'Value') get(handles.g2_slider,'Value') get(handles.gcs_slider,'Value')];
tt=[0,str2double(get(handles.update_edit,'String'))];
y0 = str2num(get(handles.initial_edit,'String'));
[T,Y]=ode45(@(t,y) mysys(t,y,params),tt,y0);

line(Y(:,get(handles.dim1_popupmenu,'Value')),Y(:,get(handles.dim2_popupmenu,'Value')),Y(:,get(handles.dim3_popupmenu,'Value')),'Color',[0 0 1],'Parent',handles.phase_axes);
line(T-T(end),Y(:,get(handles.dim1_popupmenu,'Value')),'Color',[0 0 1],'Parent',handles.dim1_axes);
line(T-T(end),Y(:,get(handles.dim2_popupmenu,'Value')),'Color',[0 0 1],'Parent',handles.dim2_axes);
line(T-T(end),Y(:,get(handles.dim3_popupmenu,'Value')),'Color',[0 0 1],'Parent',handles.dim3_axes);

if str2num(get(handles.disturb_edit,'String'))~=0
    y02 = y0+str2num(get(handles.disturb_edit,'String'));
    [T2,Y2]=ode45(@(t,y) mysys(t,y,params),tt,y02);
    line(Y2(:,get(handles.dim1_popupmenu,'Value')),Y2(:,get(handles.dim2_popupmenu,'Value')),Y2(:,get(handles.dim3_popupmenu,'Value')),'Color',[1 0 0],'Parent',handles.phase_axes);
    line(T2-T2(end),Y2(:,get(handles.dim1_popupmenu,'Value')),'Color',[1 0 0],'Parent',handles.dim1_axes);
    line(T2-T2(end),Y2(:,get(handles.dim2_popupmenu,'Value')),'Color',[1 0 0],'Parent',handles.dim2_axes);
    line(T2-T2(end),Y2(:,get(handles.dim3_popupmenu,'Value')),'Color',[1 0 0],'Parent',handles.dim3_axes);
end
set(handles.sim_time_text,'String',num2str(T(end)));

function gui_timer_callback(obj, event, handles)
global Y;
global T;
global Y2;
global T2;

params=[get(handles.alpha_slider,'Value') get(handles.beta_slider,'Value') get(handles.g1_slider,'Value') get(handles.g2_slider,'Value') get(handles.gcs_slider,'Value')];
tt=[T(end),T(end)+str2double(get(handles.update_edit,'String'))];
[TT,YY]=ode45(@(t,y) mysys(t,y,params),tt,Y(end,:));

lastneed=find(T>(TT(end)-str2double(get(handles.history_edit,'String'))),1);
T=[T(lastneed:end); TT(2:end)];
Y=[Y(lastneed:end,:); YY(2:end,:)];

hphase_ch=get(handles.phase_axes,'Child');
hdim1_ch=get(handles.dim1_axes,'Child');
hdim2_ch=get(handles.dim2_axes,'Child');
hdim3_ch=get(handles.dim3_axes,'Child');

set(hphase_ch(1),'XData',Y(:,get(handles.dim1_popupmenu,'Value')),'YData',Y(:,get(handles.dim2_popupmenu,'Value')),'ZData',Y(:,get(handles.dim3_popupmenu,'Value')));
set(hdim1_ch(1),'XData',T-T(end),'YData',Y(:,get(handles.dim1_popupmenu,'Value')));
set(hdim2_ch(1),'XData',T-T(end),'YData',Y(:,get(handles.dim2_popupmenu,'Value')));
set(hdim3_ch(1),'XData',T-T(end),'YData',Y(:,get(handles.dim3_popupmenu,'Value')));
if length(hphase_ch)>1
    [TT2,YY2]=ode45(@(t,y) mysys(t,y,params),tt,Y2(end,:));
    lastneed=find(T2>(TT2(end)-str2double(get(handles.history_edit,'String'))),1);
    T2=[T2(lastneed:end); TT2(2:end)];
    Y2=[Y2(lastneed:end,:); YY2(2:end,:)];
    set(hphase_ch(2),'XData',Y2(:,get(handles.dim1_popupmenu,'Value')),'YData',Y2(:,get(handles.dim2_popupmenu,'Value')),'ZData',Y2(:,get(handles.dim3_popupmenu,'Value')));
    set(hdim1_ch(2),'XData',T2-T2(end),'YData',Y2(:,get(handles.dim1_popupmenu,'Value')));
    set(hdim2_ch(2),'XData',T2-T2(end),'YData',Y2(:,get(handles.dim2_popupmenu,'Value')));
    set(hdim3_ch(2),'XData',T2-T2(end),'YData',Y2(:,get(handles.dim3_popupmenu,'Value')));
end

set(handles.sim_time_text,'String',num2str(T(end)));

global chualabels;
xlabel(handles.dim1_axes, 't');
ylabel(handles.dim1_axes,  chualabels(get(handles.dim1_popupmenu,'Value')));
xlabel(handles.dim2_axes, 't');
ylabel(handles.dim2_axes,  chualabels(get(handles.dim2_popupmenu,'Value')));
xlabel(handles.dim3_axes, 't');
ylabel(handles.dim3_axes,  chualabels(get(handles.dim3_popupmenu,'Value')));
xlabel(handles.phase_axes, chualabels(get(handles.dim1_popupmenu,'Value')));
ylabel(handles.phase_axes, chualabels(get(handles.dim2_popupmenu,'Value')));
zlabel(handles.phase_axes, chualabels(get(handles.dim3_popupmenu,'Value')));

% --- Executes on button press in start_button.
function start_button_Callback(hObject, eventdata, handles)
% hObject    handle to start_button (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,'UserData') % 0 if stopped 1 if running
    set(hObject,'UserData',0);
    stop(handles.timem);
    set(handles.disturb_edit,'Enable','on'); 
    set(handles.gui_timer_edit,'Enable','on');
    set(hObject,'String','Continue');
    set(handles.timem,'TimerFcn', {@gui_timer_callback,handles},'StartFcn','');
else
    set(hObject,'UserData',1);
    set(handles.disturb_edit,'Enable','inactive'); 
    set(handles.gui_timer_edit,'Enable','inactive');
    set(handles.timem,'Period',str2double(get(handles.gui_timer_edit,'String')));
    set(hObject,'String','Pause');
    start(handles.timem);
end

% --- Executes on button press in reset_button.
function reset_button_Callback(hObject, eventdata, handles)
% hObject    handle to reset_button (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if get(handles.start_button,'UserData') % 0 if stopped 1 if running
    stop(handles.timem);
    set(handles.timem,'Period',str2double(get(handles.gui_timer_edit,'String')),'StartFcn', {@gui_timer_startcallback,handles});
    start(handles.timem);
else
    set(handles.disturb_edit,'Enable','on'); 
    set(handles.gui_timer_edit,'Enable','on'); 
    set(handles.timem,'Period',str2double(get(handles.gui_timer_edit,'String')),'StartFcn', {@gui_timer_startcallback,handles});
    set(handles.start_button,'String','Start');
end

% --- Executes on button press in sound_toggle.
function sound_toggle_Callback(hObject, eventdata, handles)
global Y;
global T;
% Hint: get(hObject,'Value') returns toggle state of sound_toggle
if get(hObject,'Value')
    localT=T;
    localY=Y(:,[get(handles.sound_left_popup,'Value'),get(handles.sound_right_popup,'Value')]);
    handles.aplayer=audioplayer(interp1(localT, localY, linspace(localT(1),localT(end),(localT(end)-localT(1))*get(handles.sound_freq_slider,'Value')/str2double(get(handles.sound_tempo_edit,'String')))),get(handles.sound_freq_slider,'Value'));
    set(handles.aplayer,'StopFcn',{@repeat_sound_callback,handles});
    play(handles.aplayer);
    guidata(handles.output, handles);
else
    set(handles.aplayer,'StopFcn','');
    stop(handles.aplayer);
end

function repeat_sound_callback(obj, event, handles)
global T;
global Y;
localT=T;
localY=Y(:,[get(handles.sound_left_popup,'Value'),get(handles.sound_right_popup,'Value')]);
    handles.aplayer=audioplayer(interp1(localT, localY, linspace(localT(1),localT(end),(localT(end)-localT(1))*get(handles.sound_freq_slider,'Value')/str2double(get(handles.sound_tempo_edit,'String')))),get(handles.sound_freq_slider,'Value'));
    set(handles.aplayer,'StopFcn',{@repeat_sound_callback,handles});
    play(handles.aplayer);
    guidata(handles.output, handles);

% --- Executes on button press in checkbox_grid.
function checkbox_grid_Callback(hObject, eventdata, handles)
% Hint: get(hObject,'Value') returns toggle state of checkbox_grid
if get(hObject,'Value')
    set(handles.phase_axes,'XGrid','on','YGrid','on','ZGrid','on');
    set(handles.dim1_axes,'XGrid','on','YGrid','on');
    set(handles.dim2_axes,'XGrid','on','YGrid','on');
    set(handles.dim3_axes,'XGrid','on','YGrid','on');
else
    set(handles.phase_axes,'XGrid','off','YGrid','off','ZGrid','off');
    set(handles.dim1_axes,'XGrid','off','YGrid','off');
    set(handles.dim2_axes,'XGrid','off','YGrid','off');
    set(handles.dim3_axes,'XGrid','off','YGrid','off');    
end    
 
% --- Executes on slider movement.
function sound_freq_slider_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
set(handles.sound_freq_disp_text,'String',num2str(get(hObject,'Value')));

function camy_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
view(handles.phase_axes,get(handles.camx,'Value'),get(hObject,'Value'));
set(handles.camy_text,'String',get(hObject,'Value'));

function camx_Callback(hObject, eventdata, handles)  
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
view(handles.phase_axes,get(hObject,'Value'),get(handles.camy,'Value'));
set(handles.camx_text,'String',get(hObject,'Value'));

function alpha_slider_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of
%        slider
set(handles.alpha_disp_text,'String',num2str(get(hObject,'Value')));

function beta_slider_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
set(handles.beta_disp_text,'String',num2str(get(hObject,'Value')));

function g1_slider_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
set(handles.g1_disp_text,'String',num2str(get(hObject,'Value')));

function g2_slider_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
set(handles.g2_disp_text,'String',num2str(get(hObject,'Value')));

%--- Executes when new edit String is given by the user
function alpha_min_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of alpha_min_edit as text
%        str2double(get(hObject,'String')) returns contents of alpha_min_edit as a double
set(handles.alpha_slider,'Min',str2double(get(hObject,'String')));

function alpha_max_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of alpha_max_edit as text
%        str2double(get(hObject,'String')) returns contents of alpha_max_edit as a double
set(handles.alpha_slider,'Max',str2double(get(hObject,'String')));

function beta_min_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of beta_min_edit as text
%        str2double(get(hObject,'String')) returns contents of beta_min_edit as a double
set(handles.beta_slider,'Min',str2double(get(hObject,'String')));

function beta_max_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of beta_max_edit as text
%        str2double(get(hObject,'String')) returns contents of beta_max_edit as a double
set(handles.beta_slider,'Max',str2double(get(hObject,'String')));

function g1_min_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of g1_min_edit as text
%        str2double(get(hObject,'String')) returns contents of g1_min_edit as a double
set(handles.g1_slider,'Min',str2double(get(hObject,'String')));

function g1_max_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of g1_max_edit as text
%        str2double(get(hObject,'String')) returns contents of g1_max_edit as a double
set(handles.g1_slider,'Max',str2double(get(hObject,'String')));

function g2_min_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of g2_min_edit as text
%        str2double(get(hObject,'String')) returns contents of g2_min_edit as a double
set(handles.g2_slider,'Min',str2double(get(hObject,'String')));

function g2_max_edit_Callback(hObject, eventdata, handles)
% Hints: get(hObject,'String') returns contents of g2_max_edit as text
%        str2double(get(hObject,'String')) returns contents of g2_max_edit as a double
set(handles.g2_slider,'Max',str2double(get(hObject,'String')));

% --- Outputs from this function are returned to the command line.
function varargout = hf_sample_chua_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 during object deletion, before destroying properties.
function figure1_DeleteFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if exist('handles.timem')
    stop(handles.timem);
    delete(handles.timem);
end
set(handles.aplayer,'StopFcn','');
stop(handles.aplayer);


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


% --- Executes on slider movement.
function gcs_slider_Callback(hObject, eventdata, handles)
% hObject    handle to gcs_slider (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
set(handles.gcs_disp_text,'String',num2str(get(hObject,'Value')));


% --- Executes during object creation, after setting all properties.
function gcs_slider_CreateFcn(hObject, eventdata, handles)
% hObject    handle to gcs_slider (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 gcs_min_edit_Callback(hObject, eventdata, handles)
% hObject    handle to gcs_min_edit (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 gcs_min_edit as text
%        str2double(get(hObject,'String')) returns contents of gcs_min_edit as a double
set(handles.gcs_slider,'Min',str2double(get(hObject,'String')));

% --- Executes during object creation, after setting all properties.
function gcs_min_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to gcs_min_edit (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 gcs_max_edit_Callback(hObject, eventdata, handles)
% hObject    handle to gcs_max_edit (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 gcs_max_edit as text
%        str2double(get(hObject,'String')) returns contents of gcs_max_edit as a double
set(handles.gcs_slider,'Max',str2double(get(hObject,'String')));

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