%Linear Associator demo BioNB330
%Bruce Land
%Aug2004

clear all

%build the GUI
%define the figure

colordef white

fig=figure(1);
clf
figTop = 650;
figRight = 800;
set(fig,'resize','off',...
    'doublebuffer','on',...
    'color',[1 1 1]*0.8,...
    'position',[100 100 figRight figTop],...
    'name', 'BioNB 330 Linear Associator Simulator',...
    'numbertitle','off')

%===Main state controls=================
%define the Run button
x=10; y=figTop-25;

%Mode Toggle Learn/Recall
learntoggle=uicontrol('style','radiobutton',...
    'string','Learn', ...
    'fontsize',14, ...
    'position',[x,y,100,20], ...
    'tag','mode',...
    'value',1, ...
    'callback', ...
    ['learn=1;'...
     'set(learntoggle,''value'',1);'...
     'set(recalltoggle,''value'',0);']);
recalltoggle=uicontrol('style','radiobutton',...
    'string','Recall', ...
    'fontsize',14, ...
    'position',[x,y-25,100,20], ...
    'tag','mode',...
    'callback', ...
    ['recall=1;'...
     'set(recalltoggle,''value'',1);'...
     'set(learntoggle,''value'',0);']);

%define the Quit button
quitbutton=uicontrol('style','pushbutton',...
    'string','Quit', ...
    'fontsize',12, ...
    'position',[figRight-65,y,50,20], ...
    'callback','quitit=1;close all;');

x=500;
y=350;
%reset the weights
resetbutton=uicontrol('style','pushbutton',...
    'string','Reset Weights', ...
    'fontsize',14, ...
    'position',[x,y,200,25], ...
    'callback', 'resetW=1;');

%define the set weight button
setbutton=uicontrol('style','pushbutton',...
    'string','Set Weights', ...
    'fontsize',14, ...
    'position',[x,y+70,200,25], ...
    'callback','setW=1;');

%define the threshold edit field
thresholdUI=uicontrol('style','edit',...
    'string','1', ...
    'fontsize',14, ...
    'position',[x,y-70,80,30] ...
    );
uicontrol('style','text',...
    'string','Threshold', ...
    'fontsize',14, ...
    'position',[x+80,y-70,100,25] ...
    );
%===input regions===============================
x=20; y=400;
in1UI = uicontrol('style','pushbutton',...
    'string','1', ...
    'fontsize',14, ...
    'userdata', 0, ...
    'backgroundcolor', 'w', ...
    'position',[x,y,50,50], ...
    'callback',...
    ['if 0==get(in1UI,''userdata'');' ...
        'set(in1UI,''userdata'',1);in(1)=1;'...
        'set(in1UI,''backgroundcolor'',''k'');' ...
        'set(in1UI,''foregroundcolor'',''w'');' ...
     'else;' ...
        'set(in1UI,''userdata'',0);in(1)=0;'...
        'set(in1UI,''backgroundcolor'',''w'');' ...
        'set(in1UI,''foregroundcolor'',''k'');' ...
     'end;' ...
    ]);

y=y-100;
in2UI = uicontrol('style','pushbutton',...
    'string','2', ...
    'fontsize',14, ...
    'userdata', 0, ...
    'backgroundcolor', 'w', ...
    'position',[x,y,50,50], ...
    'callback',...
    ['if 0==get(in2UI,''userdata'');' ...
        'set(in2UI,''userdata'',1);in(2)=1;'...
        'set(in2UI,''backgroundcolor'',''k'');' ...
        'set(in2UI,''foregroundcolor'',''w'');' ...
     'else;' ...
        'set(in2UI,''userdata'',0);in(2)=0;'...
        'set(in2UI,''backgroundcolor'',''w'');' ...
        'set(in2UI,''foregroundcolor'',''k'');' ...
     'end;' ...
    ]);

y=y-100;
in3UI = uicontrol('style','pushbutton',...
    'string','3', ...
    'fontsize',14, ...
    'userdata', 0, ...
    'backgroundcolor', 'w', ...
    'position',[x,y,50,50], ...
    'callback',...
    ['if 0==get(in3UI,''userdata'');' ...
        'set(in3UI,''userdata'',1);in(3)=1;'...
        'set(in3UI,''backgroundcolor'',''k'');' ...
        'set(in3UI,''foregroundcolor'',''w'');' ...
     'else;' ...
        'set(in3UI,''userdata'',0);in(3)=0;'...
        'set(in3UI,''backgroundcolor'',''w'');' ...
        'set(in3UI,''foregroundcolor'',''k'');' ...
     'end;' ...
    ]);

%===output regions===============================
x=300; y=400;
out1UI = uicontrol('style','pushbutton',...
    'string','1', ...
    'fontsize',14, ...
    'userdata', 0, ...
    'backgroundcolor', 'w', ...
    'position',[x,y,50,50], ...
    'callback',...
    ['if 0==get(out1UI,''userdata'');' ...
        'set(out1UI,''userdata'',1);out(1)=1;'...
        'set(out1UI,''backgroundcolor'',''k'');' ...
        'set(out1UI,''foregroundcolor'',''w'');' ...
     'else;' ...
        'set(out1UI,''userdata'',0);out(1)=0;'...
        'set(out1UI,''backgroundcolor'',''w'');' ...
        'set(out1UI,''foregroundcolor'',''k'');' ...
     'end;' ...
    ]);

y=y-100;
out2UI = uicontrol('style','pushbutton',...
    'string','2', ...
    'fontsize',14, ...
    'userdata', 0, ...
    'backgroundcolor', 'w', ...
    'position',[x,y,50,50], ...
    'callback',...
    ['if 0==get(out2UI,''userdata'');' ...
        'set(out2UI,''userdata'',1);out(2)=1;'...
        'set(out2UI,''backgroundcolor'',''k'');' ...
        'set(out2UI,''foregroundcolor'',''w'');' ...
     'else;' ...
        'set(out2UI,''userdata'',0);out(2)=0;'...
        'set(out2UI,''backgroundcolor'',''w'');' ...
        'set(out2UI,''foregroundcolor'',''k'');' ...
     'end;' ...
    ]);

y=y-100;
out3UI = uicontrol('style','pushbutton',...
    'string','3', ...
    'fontsize',14, ...
    'userdata', 0, ...
    'backgroundcolor', 'w', ...
    'position',[x,y,50,50], ...
    'callback',...
    ['if 0==get(out3UI,''userdata'');' ...
        'set(out3UI,''userdata'',1);out(3)=1;'...
        'set(out3UI,''backgroundcolor'',''k'');' ...
        'set(out3UI,''foregroundcolor'',''w'');' ...
     'else;' ...
        'set(out3UI,''userdata'',0);out(3)=0;'...
        'set(out3UI,''backgroundcolor'',''w'');' ...
        'set(out3UI,''foregroundcolor'',''k'');' ...
     'end;' ...
    ]);

%===Connections===============================
lineax = axes('position',[0 0 1 1]);
axis off
set(lineax,'xlim',[0 figRight],'ylim',[0 figTop],'color','none')
offset=525 ; delta=100;
%line from input i to output j
for i = 1:3
    for j=1:3
        lh(i,j) = line([70 300],[offset-i*delta offset-j*delta],'color','k');
    end
end
%===set button states===========================
quitit = 0;
resetW=1;
setW=0;
recall=0;
in = [0 0 0];
out = in;
weight = zeros(3);
%draw weights
t1=text(500,200,num2str(weight(1,:),'%8d'),'fontsize',14)
t2=text(500,150,num2str(weight(2,:),'%8d'),'fontsize',14)
t3=text(500,100,num2str(weight(3,:),'%8d'),'fontsize',14)
text(520,230,'Outputs','fontsize',14)
text(480,120,'Inputs','fontsize',14,'rotation',90)

%===main event loop===============================
while (quitit==0)
    %obj = get(gcf,'currentobject')
    learnmode = get(learntoggle,'value');
    recallmode = get(recalltoggle,'value');
    threshold = str2num(get(thresholdUI,'string'));
    
    %enable output state clicking
    if learnmode
        set(out1UI,'enable','on')
        set(out2UI,'enable','on')
        set(out3UI,'enable','on')
    end
    
    %set weights if button push and in learn mode
    if setW & learnmode
        setW=0;
        weight = weight + in' * out ;    
    end
    
    %reset weights if button push and in learn mode
    if resetW & learnmode
        resetW=0;
        weight = zeros(3);
    end
    
    %produce output
    if recallmode
        recall=0;
        %disable output state clicking
        set(out1UI,'enable','off')
        set(out2UI,'enable','off')
        set(out3UI,'enable','off')
        %compute and display outputs 
        %based on weights, inputs and threshold
        out = (in * weight) >= threshold ;
        if out(1)
            set(out1UI,'backgroundcolor','k');
            set(out1UI,'foregroundcolor','w');
        else
            set(out1UI,'backgroundcolor','w');
            set(out1UI,'foregroundcolor','k');
        end;
        if out(2)
            set(out2UI,'backgroundcolor','k');
            set(out2UI,'foregroundcolor','w');
        else
            set(out2UI,'backgroundcolor','w');
            set(out2UI,'foregroundcolor','k');
        end;
        if out(3)
            set(out3UI,'backgroundcolor','k');
            set(out3UI,'foregroundcolor','w');
        else
            set(out3UI,'backgroundcolor','w');
            set(out3UI,'foregroundcolor','k');
        end;
    end
    
    %animate connections
    %line from input i to output j
    for i = 1:3
        for j=1:3
            lcol =  [weight(i,j)>0, 0, 0];
            lwidth = max(1,2*weight(i,j));
            set(lh(i,j),'color',lcol,'linewidth',lwidth);
        end
    end
    set(t1,'string',num2str(weight(1,:),'%8d'))
    set(t2,'string',num2str(weight(2,:),'%8d'))
    set(t3,'string',num2str(weight(3,:),'%8d'))
    drawnow    
end %main while loop



