function wangNeuron(action)

% TERMAN-WANG OSCILLATOR DEMO
%
% Guy J Brown
% MAD - Matlab Auditory Demostrations
% (C) University of Sheffield 1998
% updated July 1999 for v2.1 by Martin

if nargin<1
	action='init';
end

switch action
   
case 'init'
    f=findobj('Tag','wangNeuron_fig');
    if ~isempty(f)
        figure(f);
    else  	

		wangNeuron_gui;
		
		% initialise the input slider
		ud.inp=0.0;
		ud.maxInput=1.5;
		ud.minInput=-0.5;
		set(findobj('Tag','InputSlider'),'Max',ud.maxInput);
		set(findobj('Tag','InputSlider'),'Min',ud.minInput);
        
		% initialise the eta slider
		ud.eta=0.05;
		ud.maxEta=0.5;
		ud.minEta=0.01;
		set(findobj('Tag','EtaSlider'),'Max',ud.maxEta);
		set(findobj('Tag','EtaSlider'),'Min',ud.minEta);
		
		% initialise the gamma slider		
		ud.gamma=6.0;
		ud.maxGamma=20.0;
		ud.minGamma=1.0;
		set(findobj('Tag','GammaSlider'),'Max',ud.maxGamma);
		set(findobj('Tag','GammaSlider'),'Min',ud.minGamma);
        
		% initialise the beta slider
		ud.beta=0.1;
		ud.maxBeta=1.0;
		ud.minBeta=0.01;
		set(findobj('Tag','BetaSlider'),'Max',ud.maxBeta);
		set(findobj('Tag','BetaSlider'),'Min',ud.minBeta);
        
		% constants for the integration
		ud.h=0.2;
		ud.maxSteps=800;
		
		% limits of the axes
		ud.maxX=3;
		ud.minX=-3;
		ud.maxY=7;
		ud.minY=-1;
		
		% initialise the figure
		set(gcf,'backingstore','off');
		set(gcf,'NextPlot','replacechildren');
        
		% set up the phase axis
		axes(findobj('Tag','PhaseAxes'));
		axis([ud.minX ud.maxX ud.minY ud.maxY]);
		axis manual;
		hold on;
		
		% set up the time axis
		axes(findobj('Tag','TimeAxes'));
		axis([1 ud.maxSteps ud.minX ud.maxX]);
		axis manual;
		hold on;
		
		% set up the tick boxes
		set(findobj('Tag','xnulltick'),'Value',1);
		set(findobj('Tag','ynulltick'),'Value',1);
		
		set(gcf,'UserData',ud);
        
		% initialise the interface sliders etc
		update_interface(ud.inp,ud.eta,ud.gamma,ud.beta);
    end
  
case 'InputSliderChanged'
    ud=get(gcf,'UserData');
    ud.inp=get(findobj('Tag','InputSlider'),'Value');
    set(findobj('Tag','InputBox'),'String',num2str(ud.inp));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'InputBoxChanged'
    ud=get(gcf,'UserData');
    ud.inp=str2num(get(findobj('Tag','InputBox'),'String'));
    ud.inp=max(min(ud.inp,ud.maxInput),ud.minInput);
    set(findobj('Tag','InputSlider'),'Value',ud.inp);
    set(findobj('Tag','InputBox'),'String',num2str(ud.inp));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'EtaSliderChanged'
    ud=get(gcf,'UserData');
    ud.eta=get(findobj('Tag','EtaSlider'),'Value');
    set(findobj('Tag','EtaBox'),'String',num2str(ud.eta));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'EtaBoxChanged'
    ud=get(gcf,'UserData');
    ud.eta=str2num(get(findobj('Tag','EtaBox'),'String'));
    ud.eta=max(min(ud.eta,ud.maxEta),ud.minEta);
    set(findobj('Tag','EtaSlider'),'Value',ud.eta);
    set(findobj('Tag','EtaBox'),'String',num2str(ud.eta));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'noOscPreset'
    update_interface(0.0,0.05,6.0,0.1);
    wangNeuron('doPlot');
    
case 'fastOscPreset'
    update_interface(0.5,0.5,6.0,0.1);
    wangNeuron('doPlot');
	
case 'slowOscPreset'
    update_interface(0.5,0.05,6.0,0.1);
    wangNeuron('doPlot');
    
    
case 'BetaSliderChanged'
    ud=get(gcf,'UserData');
    ud.beta=get(findobj('Tag','BetaSlider'),'Value');
    set(findobj('Tag','BetaBox'),'String',num2str(ud.beta));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'BetaBoxChanged'
    ud=get(gcf,'UserData');
    ud.beta=str2num(get(findobj('Tag','BetaBox'),'String'));
    ud.beta=max(min(ud.beta,ud.maxBeta),ud.minBeta);
    set(findobj('Tag','BetaSlider'),'Value',ud.beta);
    set(findobj('Tag','BetaBox'),'String',num2str(ud.beta));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'GammaSliderChanged'
    ud=get(gcf,'UserData');
    ud.gamma=get(findobj('Tag','GammaSlider'),'Value');
    set(findobj('Tag','GammaBox'),'String',num2str(ud.gamma));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'GammaBoxChanged'
    ud=get(gcf,'UserData');
    ud.gamma=str2num(get(findobj('Tag','GammaBox'),'String'));
    ud.gamma=max(min(ud.gamma,ud.maxGamma),ud.minGamma);
    set(findobj('Tag','GammaSlider'),'Value',ud.gamma);
    set(findobj('Tag','GammaBox'),'String',num2str(ud.gamma));
    set(gcf,'UserData',ud);
    wangNeuron('drawNullclines');
    
case 'drawNullclines'
    ud=get(gcf,'UserData');
    axes(findobj('Tag','PhaseAxes'));
    cla;
    if (get(findobj('Tag','xnulltick'),'Value'))==1
        x=[ud.minX:0.1:ud.maxX];
        y=3.*x-x.^3+2+ud.inp;
        plot(x,y,'m');
    end
    if (get(findobj('Tag','ynulltick'),'Value'))==1
        x=[ud.minX:0.05:ud.maxX];
        y=ud.eta.*(ud.gamma.*(1+tanh(x./ud.beta)));
        plot(x,y,'c');
        
    end	

case 'doPlot'
    inactivate_controls;
    ud=get(gcf,'UserData');
    x1=-2; y1=3.*x1-x1.^3+2+ud.inp; ; 
    % set up the time axes
    axes(findobj('Tag','TimeAxes'));
    cla;
    timePlotHdl=plot(x1,y1);
    set(timePlotHdl,'EraseMode','none');
    % set up the phase axes
    wangNeuron('drawNullclines');
    axes(findobj('Tag','PhaseAxes'));
    phasePlotHdl=plot(x1,y1,'r.');
    set(phasePlotHdl,'EraseMode','xor','MarkerSize',24);
    xt=[1:ud.maxSteps];
    xd=zeros(1,ud.maxSteps);
    for i=1:ud.maxSteps,
        
        kx1=ud.h.*(3.*x1-x1.^3+2-y1+ud.inp);
        ky1=ud.h.*(ud.eta.*(ud.gamma.*(1+tanh(x1./ud.beta))-y1));
        xx=x1+kx1./2;
        yy=y1+ky1./2;
        kx2=ud.h.*(3.*xx-xx.^3+2-yy+ud.inp);
        ky2=ud.h.*(ud.eta.*(ud.gamma.*(1+tanh(xx./ud.beta))-yy));
        x2=x1+(kx1+kx2)/2;
        y2=y1+(ky1+ky2)/2;		
        
        xd(i)=x2;
        set(timePlotHdl,'XData',xt(1:i),'YData',xd(1:i));
        set(phasePlotHdl,'XData',x2,'YData',y2);
        drawnow;
        x1=x2; y1=y2;
    end
    activate_controls;

    otherwise
maduievent('wangNeuron',action);
 
    
    end

function update_interface(inp,eta,gamma,beta)
% ---------------------------------------------
% update the interface after a change of preset
% ---------------------------------------------
set(findobj('Tag','InputSlider'),'Value',inp);
set(findobj('Tag','EtaSlider'),'Value',eta);
set(findobj('Tag','GammaSlider'),'Value',gamma);
set(findobj('Tag','BetaSlider'),'Value',beta);
wangNeuron('InputSliderChanged');
wangNeuron('BetaSliderChanged');
wangNeuron('EtaSliderChanged');
wangNeuron('GammaSliderChanged');
wangNeuron('drawNullclines');

function inactivate_controls()
set(findobj('Tag','InputSlider'),'Enable','off');
set(findobj('Tag','EtaSlider'),'Enable','off');
set(findobj('Tag','GammaSlider'),'Enable','off');
set(findobj('Tag','BetaSlider'),'Enable','off');
set(findobj('Tag','InputBox'),'Enable','off');
set(findobj('Tag','EtaBox'),'Enable','off');
set(findobj('Tag','GammaBox'),'Enable','off');
set(findobj('Tag','BetaBox'),'Enable','off');
set(findobj('Tag','xnulltick'),'Enable','off');
set(findobj('Tag','ynulltick'),'Enable','off');
set(findobj('Tag','helpMenu'),'Enable','off');
set(findobj('Tag','presetMenu'),'Enable','off');
set(findobj('Tag','beginButton'),'Enable','off');

function activate_controls()
set(findobj('Tag','InputSlider'),'Enable','on');
set(findobj('Tag','EtaSlider'),'Enable','on');
set(findobj('Tag','GammaSlider'),'Enable','on');
set(findobj('Tag','BetaSlider'),'Enable','on');
set(findobj('Tag','InputBox'),'Enable','on');
set(findobj('Tag','EtaBox'),'Enable','on');
set(findobj('Tag','GammaBox'),'Enable','on');
set(findobj('Tag','BetaBox'),'Enable','on');
set(findobj('Tag','xnulltick'),'Enable','on');
set(findobj('Tag','ynulltick'),'Enable','on');
set(findobj('Tag','helpMenu'),'Enable','on');
set(findobj('Tag','presetMenu'),'Enable','on');
set(findobj('Tag','beginButton'),'Enable','on');
