function wangNetwork(action)

% WANG OSCILLATOR NETWORK
%
% Guy J Brown
% MAD - Matlab Auditory Demostrations
% (C) University of Sheffield 1998

if nargin<1
	action='init';
end

switch action

	
		
	case 'init'
	  f=findobj('Tag','wangNetwork_fig');
  if ~isempty(f)
    figure(f);
  else  	
		wangNetwork_gui;

		% parameters
		
		ud.eta=0.1;
		ud.beta=0.1;
		ud.gamma=6.0;
		ud.inp=0.2;
 		ud.wz=0.5;
		ud.weight=0.8;
				
		% inhibition limits
		ud.maxwz=1.0;
		ud.minwz=0.0;
		
 		% constants for the integration
		ud.h=0.2;
		ud.maxSteps=1000;
		
		% weights
		ud.w = zeros(4,4);
		updateMatrix(ud.w);
		
		% 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;
		cla;
		% plot([-5 5],[0 0],[0 0],[-5 5]);	doesn't work
		hold on;
		
		% inhibition slider 
		set(findobj('Tag','zslider'),'Max',ud.maxwz);
		set(findobj('Tag','zslider'),'Min',ud.minwz);
		
		% set up the time axis
		axes(findobj('Tag','TimeAxes'));
		axis([1 ud.maxSteps 0 27]);
		axis manual;
		cla;
		hold on;
		
		% set up the tick boxes
		set(findobj('Tag','xnulltick'),'Value',1);
		set(findobj('Tag','ynulltick'),'Value',1);

		set(findobj('Tag','zslider'),'Value',ud.wz);
		
		set(gcf,'UserData',ud);
		
		set(findobj('Tag','icmenu'),'Value',1);
		wangNetwork('zsliderChanged');
        end
		
	case 'noInhib'
		ud=get(gcf,'UserData');
		set(findobj('Tag','icmenu'),'Value',2);
		set(findobj('Tag','zslider'),'Value',0.0);
		wangNetwork('zsliderChanged');
		ud.w = zeros(4,4);
		updateMatrix(ud.w);
		set(gcf,'UserData',ud);
		wangNetwork('doPlot');
		
	case 'segregated'
		ud=get(gcf,'UserData');
		set(findobj('Tag','icmenu'),'Value',1);
		set(findobj('Tag','zslider'),'Value',0.5);
		wangNetwork('zsliderChanged');
		ud.w = zeros(4,4);
		updateMatrix(ud.w);
		set(gcf,'UserData',ud);
		wangNetwork('doPlot');

	case 'grouped'
		ud=get(gcf,'UserData');
		set(findobj('Tag','icmenu'),'Value',1);
		set(findobj('Tag','zslider'),'Value',0.5);
		wangNetwork('zsliderChanged');
		ud.w = not(eye(4,4));
		updateMatrix(ud.w);
		set(gcf,'UserData',ud);
		wangNetwork('doPlot');
				
	case 'rbgroup'
		ud=get(gcf,'UserData');
		set(findobj('Tag','icmenu'),'Value',1);
		set(findobj('Tag','zslider'),'Value',0.5);
		wangNetwork('zsliderChanged');
		ud.w = [0 1 0 0; 1 0 0 0; 0 0 0 0; 0 0 0 0];
		updateMatrix(ud.w);
		set(gcf,'UserData',ud);
		wangNetwork('doPlot');
		
	case 'twogroup'
		ud=get(gcf,'UserData');
		set(findobj('Tag','icmenu'),'Value',1);
		set(findobj('Tag','zslider'),'Value',0.5);
		wangNetwork('zsliderChanged');
		ud.w = [0 1 0 0; 1 0 0 0; 0 0 0 1; 0 0 1 0];
		updateMatrix(ud.w);
		set(gcf,'UserData',ud);
		wangNetwork('doPlot');
			
case 'close'
  if strcmp(questdlg('Are you sure you want to quit?'),'Yes')
    wangNetwork 'reallyquit';
  end
  
case 'reallyquit'
  delete(get(0,'CurrentFigure'));
  
case 'aboutBox'
  helpwin(mfilename);
  
case 'help'
  web(['file:' which([mfilename '.htm'])]);

case 'localmadHomePage'
  web(['file:' which('mad.htm')]);    
  
case 'madHomePage'
  web ('http://www.dcs.shef.ac.uk/~martin/mad');
    
case 'bugReport'
  web ('mailto:g.brown@dcs.shef.ac.uk');
  
  
		
	case 'zsliderChanged'
		ud=get(gcf,'UserData');
		ud.wz=get(findobj('Tag','zslider'),'Value');
		set(findobj('Tag','zbox'),'String',num2str(ud.wz));
		set(gcf,'UserData',ud);	
		
	case 'zboxChanged'
		ud=get(gcf,'UserData');
		ud.wz=str2num(get(findobj('Tag','zbox'),'String'));
		ud.wz=max(min(ud.wz,ud.maxwz),ud.minwz);
		set(findobj('Tag','zslider'),'Value',ud.wz);
		set(findobj('Tag','zbox'),'String',num2str(ud.wz));
		set(gcf,'UserData',ud);
					
	% this is not used at the moment
	
	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 'box12'
		toggle(1,2);	
	case 'box13'
		toggle(1,3);
	case 'box14'
		toggle(1,4);
		
	case 'box21'
		toggle(2,1);
	case 'box23'
		toggle(2,3);
	case 'box24'
		toggle(2,4);
		
	case 'box31'
		toggle(3,1);	
	case 'box32'
		toggle(3,2);
	case 'box34'
		toggle(3,4);
		
	case 'box41'
		toggle(4,1);	
	case 'box42'
		toggle(4,2);
	case 'box43'
		toggle(4,3);

	case 'doPlot'
		inactivate_controls;
		ud=get(gcf,'UserData');
		switch get(findobj('Tag','icmenu'),'Value')
			case 1 			
				x1=randn(4,1);
			case 2
				x1=[-1;-1;-1;-1];
			case 3
				x1=[1.7572;-1.3921;-1.5309;-1.8140];
		end 
		y1=3.*x1-x1.^3+2+ud.inp; 
		z1=0;
		xd=zeros(4,ud.maxSteps); 
		zd=zeros(1,ud.maxSteps);
		offset=[6;12;18;24];
		xd(:,1)=offset;
		% set up the time axes
		axes(findobj('Tag','TimeAxes'));
		cla;
		timePlot1=plot(1,x1(1),'b-');
		timePlot2=plot(1,x1(2),'r-');
		timePlot3=plot(1,x1(3),'g-');
		timePlot4=plot(1,x1(4),'c-');
		timePlot5=plot(1,0,'k-');
		set(timePlot1,'EraseMode','none');
		set(timePlot2,'EraseMode','none');
		set(timePlot3,'EraseMode','none');
		set(timePlot4,'EraseMode','none');
		set(timePlot5,'EraseMode','none');
		% set up the phase axes
		axes(findobj('Tag','PhaseAxes'));
		cla;
		phasePlot1=plot(x1(1),y1(1),'b.');
		phasePlot2=plot(x1(2),y1(2),'r.');
		phasePlot3=plot(x1(3),y1(3),'g.');
		phasePlot4=plot(x1(4),y1(4),'c.');
		set(phasePlot1,'EraseMode','background','MarkerSize',24);
		set(phasePlot2,'EraseMode','background','MarkerSize',24);
		set(phasePlot3,'EraseMode','background','MarkerSize',24);
		set(phasePlot4,'EraseMode','background','MarkerSize',24);
		xs=[1:ud.maxSteps];
		% set up the weight matrix
		w=ud.w*ud.weight;
		for i=1:ud.maxSteps,
			
			% update the network (2nd order RK)
			
			s=squash1(x1);
			
			xinp=ud.inp-ud.wz*squash2(z1)+0.02*randn(4,1)+w*s;
			
			kx1=ud.h.*(3.*x1-x1.^3+2-y1+xinp);
			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+xinp);
			ky2=ud.h.*(ud.eta.*(ud.gamma.*(1+tanh(xx./ud.beta))-yy));
			x2=x1+(kx1+kx2)/2;
			y2=y1+(ky1+ky2)/2;			

			zinp=heaviside(sum(squash1(x2)));
			kz1=ud.h*(3*(zinp-z1));
			kz2=ud.h*(3*(zinp-(z1+kz1/2)));
			z2=z1+(kz1+kz2)/2;
			
			% global inhibitor
			
			xd(:,i)=offset+x2;
			zd(i)=1+z2;
			
			set(timePlot1,'XData',xs(1:i),'YData',xd(1,1:i));
			set(timePlot2,'XData',xs(1:i),'YData',xd(2,1:i));
			set(timePlot3,'XData',xs(1:i),'YData',xd(3,1:i));
			set(timePlot4,'XData',xs(1:i),'YData',xd(4,1:i));
			set(timePlot5,'XData',xs(1:i),'YData',zd(1:i));
			
			set(phasePlot1,'XData',x2(1),'YData',y2(1));
			set(phasePlot2,'XData',x2(2),'YData',y2(2));
			set(phasePlot3,'XData',x2(3),'YData',y2(3));
			set(phasePlot4,'XData',x2(4),'YData',y2(4));
			
			drawnow;
			x1=x2; y1=y2; z1=z2;
			
		end
		activate_controls;
end

function y=heaviside(x)
y=(x>=0.1);

function y=squash1(x)
y=1./(1+exp(-50.*(x+0.5)));

function y=squash2(x)
y=1./(1+exp(-50.*(x-0.1)));

function updateMatrix(w)
for i=1:4,
	for j=1:4,
		c=not(w(i,j));
		b=['box' num2str(i) num2str(j)];
		set(findobj('Tag',b),'BackgroundColor',[ c c c ]);
	end
end
	
function toggle(row,col)
ud=get(gcf,'UserData');
ud.w(row,col)=not(ud.w(row,col));
ud.w(col,row)=not(ud.w(col,row));
c=not(ud.w(row,col));
b=['box' num2str(row) num2str(col)];
set(findobj('Tag',b),'BackgroundColor',[ c c c ]);
b=['box' num2str(col) num2str(row)];
set(findobj('Tag',b),'BackgroundColor',[ c c c ]);
set(gcf,'UserData',ud);

function inactivate_controls()
set(findobj('Tag','zslider'),'Enable','off');
set(findobj('Tag','zbox'),'Enable','off');
set(findobj('Tag','icmenu'),'Enable','off');
set(findobj('Tag','beginButton'),'Enable','off');
set(findobj('Tag','presetMenu'),'Enable','off');
set(findobj('Tag','helpMenu'),'Enable','off');
set(findobj('Tag','box11'),'Enable','off');
set(findobj('Tag','box12'),'Enable','off');
set(findobj('Tag','box13'),'Enable','off');
set(findobj('Tag','box14'),'Enable','off');
set(findobj('Tag','box21'),'Enable','off');
set(findobj('Tag','box22'),'Enable','off');
set(findobj('Tag','box23'),'Enable','off');
set(findobj('Tag','box24'),'Enable','off');
set(findobj('Tag','box31'),'Enable','off');
set(findobj('Tag','box32'),'Enable','off');
set(findobj('Tag','box33'),'Enable','off');
set(findobj('Tag','box34'),'Enable','off');
set(findobj('Tag','box41'),'Enable','off');
set(findobj('Tag','box42'),'Enable','off');
set(findobj('Tag','box43'),'Enable','off');
set(findobj('Tag','box44'),'Enable','off');

function activate_controls()
set(findobj('Tag','zslider'),'Enable','on');
set(findobj('Tag','zbox'),'Enable','on');
set(findobj('Tag','icmenu'),'Enable','on');
set(findobj('Tag','beginButton'),'Enable','on');
set(findobj('Tag','presetMenu'),'Enable','on');
set(findobj('Tag','helpMenu'),'Enable','on');
set(findobj('Tag','box11'),'Enable','on');
set(findobj('Tag','box12'),'Enable','on');
set(findobj('Tag','box13'),'Enable','on');
set(findobj('Tag','box14'),'Enable','on');
set(findobj('Tag','box21'),'Enable','on');
set(findobj('Tag','box22'),'Enable','on');
set(findobj('Tag','box23'),'Enable','on');
set(findobj('Tag','box24'),'Enable','on');
set(findobj('Tag','box31'),'Enable','on');
set(findobj('Tag','box32'),'Enable','on');
set(findobj('Tag','box33'),'Enable','on');
set(findobj('Tag','box34'),'Enable','on');
set(findobj('Tag','box41'),'Enable','on');
set(findobj('Tag','box42'),'Enable','on');
set(findobj('Tag','box43'),'Enable','on');
set(findobj('Tag','box44'),'Enable','on');
