function makeThresholdTester(mfn)
%get the user to experiment with a threshold
%setting before applying it to the whole window 

%"{NAME}" indicates code that has been commented out or changed 
%based on the assumption that there is only one set of element 
%labels (ie element names).

%Note: the "thresholdTester" was more accurately renamed as the
%"Parameter Explorer" in my thesis and the user study instructions.

global theVars;

selectedVerb = getVerbID(mfn);
if(isempty(selectedVerb))
  %the user clicked cancel
  return;
end;

index=find(strcmp(theVars(mfn).allFullNames,selectedVerb{1}));  

%make the data structure to hold the variables assoc with this ttester
myttIndex = getNextAvailableTTindex(mfn);
theVars(mfn).thresholdTesters(myttIndex).verbIndex = index;
theVars(mfn).thresholdTesters(myttIndex).currentThreshold = theVars(mfn).visThreshold;
theVars(mfn).thresholdTesters(myttIndex).fromValue =1;
theVars(mfn).thresholdTesters(myttIndex).toValue = -1;
theVars(mfn).thresholdTesters(myttIndex).simTypeID = theVars(mfn).simMode;
theVars(mfn).thresholdTesters(myttIndex).stopflag=0;
%{NAME}
%theVars(mfn).thresholdTesters(myttIndex).nameTypeID = theVars(mfn).fni;

theVars(mfn).thresholdTesters(myttIndex).theaxishandle = 0;
theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle = 0;
theVars(mfn).thresholdTesters(myttIndex).clickQueryTextHandle = 0;
theVars(mfn).thresholdTesters(myttIndex).rangeDisplayHandle = 0;
theVars(mfn).thresholdTesters(myttIndex).patchhandles = [];
theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOn = [];
theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOff = [];
theVars(mfn).thresholdTesters(myttIndex).buttonHandleList = [];

theVars(mfn).thresholdTesters(myttIndex).tables = {};
theVars(mfn).thresholdTesters(myttIndex).animIndex=0;
makeSimilarityRankings(mfn,myttIndex); %initializes 'tables' and 'animIndex'

theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum = 0;%flag as unused
theVars(mfn).thresholdTesters(myttIndex).statsWindow.histAxis=0;
theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewConnectionsText = 0;
theVars(mfn).thresholdTesters(myttIndex).statsWindow.fewConPromptHandle = 0;
theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewBound = 3;%default
theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyConnectionsText = 0;
theVars(mfn).thresholdTesters(myttIndex).statsWindow.manyConPromptHandle = 0;
theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyBound = 10;%default
theVars(mfn).thresholdTesters(myttIndex).statsWindow.totalNumPatchesText = 0;

theVars(mfn).thresholdTesters(myttIndex).numTopVals = 10;
numTopVals = theVars(mfn).thresholdTesters(myttIndex).numTopVals;
theVars(mfn).thresholdTesters(myttIndex).tophandles = zeros(numTopVals,1);
stringValTop = cell(numTopVals,1);
for(i=1:numTopVals)
  stringValTop(i)={''};
end;

theVars(mfn).thresholdTesters(myttIndex).numRecVals = 10;
numRecVals = theVars(mfn).thresholdTesters(myttIndex).numRecVals;
theVars(mfn).thresholdTesters(myttIndex).rechandles = zeros(numRecVals,1);
%recOrigIndexes holds the originalIndexes of the elements currently
%listed in the recent matches list (to be used for name conversion)
theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes = zeros(numRecVals,1);

stringValRec = cell(numRecVals,1); %start empty
for(i=1:numRecVals)
  stringValRec(i)={''};
end;
thisFigNum=getNextFigNum;
theVars(mfn).thresholdTesters(myttIndex).figNum = thisFigNum;
%end of datastructure initialization and setting default values

figure(thisFigNum);
figtitle = sprintf('Parameter Explorer for Figure %d', mfn);
set(thisFigNum,{'Toolbar','MenuBar','Units','Name','NumberTitle'},...
		{'none','none','pixels', figtitle, 'off'});
currfigdims = get(thisFigNum,'Position'); %get the defaults

figdims = [660, 520]; 
currfigdims(1:2) = currfigdims(1:2)-100;
currfigdims(3:4) = figdims;
set(thisFigNum, 'Position', currfigdims);

set(thisFigNum,'Units','normalized');
thebigaxishandle= axes('Visible','off','Units','pixels',...
 'Position',[0 0 1 1]);

set(thisFigNum,'Units','pixels');

GUIheight=60; %the stuff at the bottom
textsize=12;
sptextsize = textsize+3;
axistitleheight=30;
spacer=15;
smallspace=3;

desiredaxisheight=min(10+3*figdims(1)/4,...
	figdims(2)-(GUIheight+textsize+axistitleheight))-2;%-2 for padding

changeVerbButtonDims=[90,25];
changeVerbButtonHandle = uicontrol('Style','pushbutton','String','change verb',...
	'Position',[0,figdims(2)-(changeVerbButtonDims(2)),...
		    changeVerbButtonDims],'Callback',...
				   {@changeVerbButtonCallback, mfn,myttIndex});
popupDims = [175,25];
%insert names popup here if {NAME} changing is added
text(desiredaxisheight+spacer,figdims(2),...
     'Use similarity measure:','HorizontalAlignment',...
     'left','VerticalAlignment','top','FontSize',textsize);

popuphandle = uicontrol('Style', 'popup', 'String', ...
	'absolute sim|relative sim (pearson)|rel sim 2|absolute simsim|relative simsim|rel2 simsim',...
	'Position', [figdims(1)-popupDims(1),figdims(2)-(popupDims(2)+sptextsize+smallspace),...
		    popupDims],'Callback', {@setSimTypeCB, mfn, myttIndex});
set(popuphandle,'Value',theVars(mfn).simMode);
spacer=15;

stringValTitleTop = {'\bfTop 10 Best Matches\rm'};
titleTop = text(10+desiredaxisheight+spacer,figdims(2)-...
		(popupDims(2)+sptextsize+2*smallspace), stringValTitleTop,...
		'HorizontalAlignment','left','VerticalAlignment','top','FontSize',textsize);

for(i=1:theVars(mfn).thresholdTesters(myttIndex).numTopVals)
  theVars(mfn).thresholdTesters(myttIndex).tophandles(i) =...
      text(10+desiredaxisheight+spacer,figdims(2)-(popupDims(2)+i*(sptextsize)+sptextsize+2*smallspace),...
		       stringValTop{i},'HorizontalAlignment','left',...
		       'VerticalAlignment','top','FontSize',textsize,'FontName','FixedWidth');
end;
fillTopText(mfn,myttIndex);%insert the actual verb names

toendoftopvals = figdims(2)-(popupDims(2)+ ...
		(theVars(mfn).thresholdTesters(myttIndex).numTopVals+1)*...
			     (sptextsize)+sptextsize+2*smallspace);

stringValTitleRec = {'\bfTop 10 Most Recent\rm'};
titleRec = text(10+desiredaxisheight+spacer, toendoftopvals-(spacer),...
		stringValTitleRec,'HorizontalAlignment','left',...
		'VerticalAlignment','top','FontSize',textsize);

for(i=1:numRecVals)
  theVars(mfn).thresholdTesters(myttIndex).rechandles(i) = ...
      text(10+desiredaxisheight+spacer,toendoftopvals-(spacer+i*(sptextsize)),...
		       stringValRec{i},'HorizontalAlignment','left',...
		       'VerticalAlignment','top','FontSize',textsize,'FontName','FixedWidth');
end;

t2=text(10+desiredaxisheight+spacer,GUIheight,'Threshold range is','FontSize',...
	textsize,'Color', [0 0 0],...
	'HorizontalAlignment','left','VerticalAlignment','bottom','Units','pixels');

rangeString = ['from ', num2str(theVars(mfn).thresholdTesters(myttIndex).fromValue),...
	       ' to ', num2str(theVars(mfn).thresholdTesters(myttIndex).toValue)];
theVars(mfn).thresholdTesters(myttIndex).rangeDisplayHandle = ...
    text(10+desiredaxisheight+spacer,GUIheight-(textsize+1),...
	rangeString,'FontSize', textsize,'Color', [0 0 0],...
	'HorizontalAlignment','left','VerticalAlignment','bottom','Units','pixels');

restartButtonDims=[50,25];
t3=text(10+desiredaxisheight+spacer,restartButtonDims(2)+5,...
	'currently','FontSize', textsize,'Color', [0 0 0],...
	'HorizontalAlignment','left','VerticalAlignment','baseline','Units','pixels');
textpos = get(t3 , 'Extent');
theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle = ...
    text(textpos(1)+textpos(3)+2,restartButtonDims(2)+5, ...
	 sprintf('%1.5f',theVars(mfn).thresholdTesters(myttIndex).currentThreshold),...
	'FontWeight','bold', 'FontSize',textsize+4,'Color', [1 0 0],...
	'HorizontalAlignment','left','VerticalAlignment','baseline','Units','pixels');

restartButton = uicontrol('Style','pushbutton','String','restart','Position',...
	[10+desiredaxisheight+spacer,0,restartButtonDims]);
resumeButton = uicontrol('Style','pushbutton','String','resume','Position',...
	[10+desiredaxisheight+spacer+restartButtonDims(1),0,restartButtonDims]);

editRangeButtonDims = [70,25];
editRangeButtonHandle = uicontrol('Style','pushbutton','String','edit range',...
		'Position', [figdims(1)-editRangeButtonDims(1),...
		 0, editRangeButtonDims],...
		'Callback',{@editRangeButtonCallback,mfn, myttIndex});

setValueButtonDims = [70,25];
setValueButtonHandle =  uicontrol('Style','pushbutton','String','set value',...
		'Position', [figdims(1)-setValueButtonDims(1),...
		 editRangeButtonDims(2), setValueButtonDims],...
		'Callback',{@setValueButtonCallback,mfn, myttIndex});

closeWindowButtonDims=[140,25];
closeWindowButton = uicontrol('Style','pushbutton','String','close',...
			      'Position',[0,0,closeWindowButtonDims],'Callback',...
			      {@closeButtonCallback,mfn,myttIndex});
useThisButtonDims = [140,25];
useThisButtonHandle = uicontrol('Style','pushbutton','String','use this threshold',...
	'Position',[0,closeWindowButtonDims(2)+5,useThisButtonDims],...
	'Callback',{@useThisButtonCallback,mfn,myttIndex});

getStatsButtonDims = [100,25];
getStatsButtonHandle = uicontrol('Style','pushbutton', 'String', 'get stats',...
	'Position', [(figdims(1)/2)-getStatsButtonDims(1),0,...
		    getStatsButtonDims], 'Callback',{@getStatsButtonCallback,mfn,myttIndex});

theVars(mfn).thresholdTesters(myttIndex).clickQueryTextHandle = ...
    text((figdims(1)/2)-getStatsButtonDims(1),getStatsButtonDims(2)+5,'',...
	 'FontSize', textsize, 'HorizontalAlignment','left',...
	 'VerticalAlignment','bottom','Units','pixels');

%do this after all the ui objects are created so we can pass their handles
set(restartButton,'Callback',{@restartButtonCallback, mfn, myttIndex,...
	resumeButton,editRangeButtonHandle, changeVerbButtonHandle,popuphandle,...
		    useThisButtonHandle,closeWindowButton,getStatsButtonHandle,setValueButtonHandle});

set(resumeButton,'Callback',{@resumeButtonCallback, mfn, myttIndex});

theVars(mfn).thresholdTesters(myttIndex).buttonHandleList = [restartButton; ...
		    resumeButton; editRangeButtonHandle; changeVerbButtonHandle;popuphandle;...
		    useThisButtonHandle;closeWindowButton;getStatsButtonHandle;setValueButtonHandle];

%theaxishandle is global so animators can see it
theVars(mfn).thresholdTesters(myttIndex).theaxishandle=...
    axes('Units','pixels','Position',[10,...
		    GUIheight+textsize+2,desiredaxisheight,desiredaxisheight]);
%fill in the patches & set their visibility based on the currentThreshold
fillaxis(mfn, myttIndex, index, selectedVerb);
adjustVisForCurrThreshold(mfn, myttIndex);
set(theVars(mfn).thresholdTesters(myttIndex).patchhandles,'ButtonDownFcn',...
		  {@patchClickCallback, mfn, myttIndex});


function makeSimilarityRankings(mfn,myttIndex)
global theVars
%construct tables of affinities using all similarity measures
%relative to the focus (proteinIndex)
%NOTE: these tables include similarities to ALL inputs, not just the subset
%appearing in this thresholdTester's main window

index = theVars(mfn).thresholdTesters(myttIndex).verbIndex;
tables={};
tables{1}=zeros(theVars(mfn).origNuminputs,2); %abs
tables{2}=zeros(theVars(mfn).origNuminputs,2); %rel (pearson)
tables{3}=zeros(theVars(mfn).origNuminputs,2); %rel2
tables{4}=zeros(theVars(mfn).origNuminputs,2); %abssimsim
tables{5}=zeros(theVars(mfn).origNuminputs,2); %relsimsim
tables{6}=zeros(theVars(mfn).origNuminputs,2); %rel2simsim

%column 1 is the ID (index) assoc with this affinity val
for(i=1:6) %HARD CODED
  tables{i}(:,1) = [1:theVars(mfn).origNuminputs]';
end;

%column 2 is the affinity val
tables{1}(:,2)=theVars(mfn).theFullAbsSimilarityMatrix(index,:)';
tables{2}(:,2)=theVars(mfn).theFullRelSimilarityMatrix(index,:)';
tables{3}(:,2)=theVars(mfn).theFullRel2SimilarityMatrix(index,:)';
tables{4}(:,2)=theVars(mfn).theFullAbsSimSimMatrix(index,:)';
tables{5}(:,2)=theVars(mfn).theFullRelSimSimMatrix(index,:)';
tables{6}(:,2)=theVars(mfn).theFullRel2SimSimMatrix(index,:)';


%NOTE: sorts to ASCENDING order
for(i=1:6) %HARD CODED
  tables{i} = sortrows(tables{i},2);
end;

theVars(mfn).thresholdTesters(myttIndex).tables = tables;
simTypeID = theVars(mfn).thresholdTesters(myttIndex).simTypeID;
theVars(mfn).thresholdTesters(myttIndex).animIndex =...
    min(find(tables{simTypeID}(:,2)> ...
	     theVars(mfn).thresholdTesters(myttIndex).currentThreshold));
if(isempty(theVars(mfn).thresholdTesters(myttIndex).animIndex))
  %set to one past the end
  theVars(mfn).thresholdTesters(myttIndex).animIndex = theVars(mfn).origNuminputs+1;
end;


function setSimTypeCB(obj, eventinfo, mfn, myttIndex)
global theVars;
%do stuff based on the obj's 'Value' (1 thru 6)
oldID = theVars(mfn).thresholdTesters(myttIndex).simTypeID;
newID = get(obj,'Value');
if(oldID ~= newID)
  theVars(mfn).thresholdTesters(myttIndex).stopflag=1;
  theVars(mfn).thresholdTesters(myttIndex).simTypeID = get(obj,'Value');
  adjustVisForCurrThreshold(mfn,myttIndex);
  fillTopText(mfn,myttIndex);
  clearRecText(mfn, myttIndex);
end;

%function setNameTypeCB(obj, eventInfo, mfn, myttIndex)
%function renameText(mfn, myttIndex,oldNameType)
%fill in these functions if {NAME} changing is added

function fillTopText(mfn, myttIndex)
global theVars;

toptexthandles = theVars(mfn).thresholdTesters(myttIndex).tophandles;
simTypeID = theVars(mfn).thresholdTesters(myttIndex).simTypeID;
tables = theVars(mfn).thresholdTesters(myttIndex).tables;
numTopVals = theVars(mfn).thresholdTesters(myttIndex).numTopVals;
%set the top text values
 
desiredverbIDs = tables{simTypeID}(end-numTopVals+1:end,1);
%change next line if {NAME} changing is added
namesaschars = char(theVars(mfn).allFullNames{desiredverbIDs});

for(i=1:numTopVals)
  verbNum = desiredverbIDs(end-i+1);
  verbRowNum = ceil(verbNum/theVars(mfn).origNumcols);
  if(verbNum <= theVars(mfn).origNumcols)
    verbColNum = verbNum;
  else %verbRowNum > 1
    verbColNum = verbNum-(verbRowNum-1)*theVars(mfn).origNumcols;
  end;
  c=theVars(mfn).patchColors(verbRowNum,verbColNum,:);
  %darken the text to account for the effect of the grey bg
  c = c*0.9; %NEW!(Mar 9)
  
  thestring = sprintf('%2d. %s (%1.5f)', i, namesaschars(end-i+1,:),...
		      tables{simTypeID}(end-i+1,2));
  set(toptexthandles(i), {'String','Color'},{thestring,c});
end;

function clearRecText(mfn, myttIndex)
global theVars;

rectexthandles = theVars(mfn).thresholdTesters(myttIndex).rechandles;
for(i=1:length(rectexthandles))
    set(rectexthandles(i), {'String','Color'},{'','k'});
end;
theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes = ...
    zeros(size(theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes));


function restartButtonCallback(obj, eventdata, mfn, myttIndex, theresumebutton, ...
	editrangebutton,changeVerbButtonHandle,popuphandle,...
        useThisButtonHandle,closeWindowButton,getStatsButtonHandle,setValueButtonHandle)
global theVars;

set(obj,'Enable','off'); %user can't click restart twice in a row
set(editrangebutton,'Enable','off');
set([changeVerbButtonHandle,popuphandle,setValueButtonHandle...
	useThisButtonHandle,closeWindowButton,getStatsButtonHandle],'Enable','off');

simTypeID = theVars(mfn).thresholdTesters(myttIndex).simTypeID;
tables = theVars(mfn).thresholdTesters(myttIndex).tables;

%reset
theVars(mfn).thresholdTesters(myttIndex).currentThreshold = ...
    theVars(mfn).thresholdTesters(myttIndex).fromValue;
set(theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle,'String',...
		  sprintf('%1.5f',theVars(mfn).thresholdTesters(myttIndex).currentThreshold));
adjustVisForCurrThreshold(mfn,myttIndex);

%show top matches
fillTopText(mfn,myttIndex);
%clear most recent matches
clearRecText(mfn, myttIndex);

theVars(mfn).thresholdTesters(myttIndex).stopflag=0;
if(strcmp(get(theresumebutton,'String'),'resume'))
  set(theresumebutton,'String','pause');
end;

if(theVars(mfn).thresholdTesters(myttIndex).fromValue < ...
   theVars(mfn).thresholdTesters(myttIndex).toValue)

  animateForwards(mfn, myttIndex);
else
  animateBackwards(mfn, myttIndex);
end;


function resumeButtonCBHelper(weWantToPause, mfn, myttIndex)
%weWantToPause is a boolean
global theVars;

therestartbutton = theVars(mfn).thresholdTesters(myttIndex).buttonHandleList(1);
theresumebutton = ...
    theVars(mfn).thresholdTesters(myttIndex).buttonHandleList(2);
buttonsToToggle = theVars(mfn).thresholdTesters(myttIndex).buttonHandleList(3:end);

if(weWantToPause)
  theVars(mfn).thresholdTesters(myttIndex).stopflag=1;
  set(theresumebutton,'String','resume');
  set(therestartbutton,'Enable','on');
  set(buttonsToToggle, 'Enable','on');
else
  set(therestartbutton,'Enable','off');
  set(buttonsToToggle, 'Enable','off');
  set(theresumebutton,'String','pause');
  theVars(mfn).thresholdTesters(myttIndex).stopflag=0;
  if(theVars(mfn).thresholdTesters(myttIndex).fromValue < ...
     theVars(mfn).thresholdTesters(myttIndex).toValue)
    animateForwards(mfn, myttIndex);
  else
    animateBackwards(mfn, myttIndex);
  end;
end;


function resumeButtonCallback(obj,eventdata, mfn, myttIndex)
global theVars;

if(strcmp(get(obj,'String'),'pause')) %user clicked pause
  resumeButtonCBHelper(1,mfn,myttIndex);
else
  resumeButtonCBHelper(0,mfn,myttIndex);
end;


function changeVerbButtonCallback(obj, eventdata, mfn, myttIndex)
global theVars;

oldVerbIndex = theVars(mfn).thresholdTesters(myttIndex).verbIndex;
selectedVerb = getVerbID(mfn);

if(~isempty(selectedVerb))
  index=find(strcmp(theVars(mfn).allFullNames,selectedVerb{1}));
  if(oldVerbIndex ~= index)
    theVars(mfn).thresholdTesters(myttIndex).verbIndex = index;
    makeSimilarityRankings(mfn,myttIndex); %sets tables
    set(get(theVars(mfn).thresholdTesters(myttIndex).theaxishandle,'Title'),...
	{'String','FontSize'}, {selectedVerb,14});

    adjustVisForCurrThreshold(mfn, myttIndex);
    fillTopText(mfn, myttIndex);
    clearRecText(mfn, myttIndex);
  end;
end;


function getStatsButtonCallback(obj, eventdata, mfn, myttIndex)
showStats(mfn,myttIndex); %so we can call this independant of
                          %clicking on the stats button

function showStats(mfn, myttIndex);
global theVars;

textsize=12;

%calculate what we want to display

switch(theVars(mfn).thresholdTesters(myttIndex).simTypeID)
 case 1
  fullAffinityVals = theVars(mfn).theFullAbsSimilarityMatrix(theVars(mfn).inboundsIndexes,:);
 case 2
  fullAffinityVals = theVars(mfn).theFullRelSimilarityMatrix(theVars(mfn).inboundsIndexes,:);
 case 3
  fullAffinityVals = theVars(mfn).theFullRel2SimilarityMatrix(theVars(mfn).inboundsIndexes,:);
 case 4
  fullAffinityVals = theVars(mfn).theFullAbsSimSimMatrix(theVars(mfn).inboundsIndexes,:);
 case 5
  fullAffinityVals = theVars(mfn).theFullRelSimSimMatrix(theVars(mfn).inboundsIndexes,:);
 case 6
  fullAffinityVals = theVars(mfn).theFullRel2SimSimMatrix(theVars(mfn).inboundsIndexes,:);
end;

fullAffinities = fullAffinityVals > ...
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold;

histData = sum(fullAffinities,2); %connectivity counts

numberFewCon = length(find(histData <= ...
			   theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewBound));
percentFewCon = numberFewCon *100 / theVars(mfn).lastValidDataIndex;
fewConString = [num2str(numberFewCon), ' ( ', num2str(percentFewCon),'% )'];

numberManyCon = length(find(histData > ...
			    theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyBound));
percentManyCon = numberManyCon *100 / theVars(mfn).lastValidDataIndex;
manyConString = [num2str(numberManyCon), ' ( ', num2str(percentManyCon),'% )'];

numberPatches = sum(histData);

fewConPrompt = sprintf('Number of verbs with %2g connections or less:',...
		       theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewBound);

manyConPrompt = sprintf('Number of verbs with more than %2g connections:',...
		       theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyBound);

if(theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum == 0)
  ttFigPos = get(theVars(mfn).thresholdTesters(myttIndex).figNum,'Position');
  pixelsSS=get(0,'screensize');
  screenwidth = pixelsSS(3);
  screenheight = pixelsSS(4);
  
  hOffsetDefault = 20;
  vOffsetDefault = 35;
  ttRightmostCorner = ttFigPos(1)+ttFigPos(3);
  hOffset = min(hOffsetDefault,screenwidth-ttRightmostCorner);
  vOffset = min(vOffsetDefault, ttFigPos(2));
  newPos = ttFigPos + [hOffset,-vOffset,0,0];
  
  %we need to layout the window
  statsFigNum=getNextFigNum;
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum = statsFigNum;
  figure(statsFigNum);
  figtitle = sprintf('Connectivity Statistics for Figure %d',mfn);
  set(statsFigNum,{'Toolbar','MenuBar','Position','Name','NumberTitle'},...
		  {'none','none',newPos, figtitle,'off'});
  thebigaxishandle= axes('Visible','off','Units','pixels',...
      'Position',[0,0,1,1]);

  set(statsFigNum,'Units','Pixels');
  currfigdims=get(statsFigNum,'Position');%get the defaults
  figdims = [560,420]; 
  currfigdims(3:4) = figdims;
  set(statsFigNum, 'Position', currfigdims);
  
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.histAxis = ...
      axes('Units','pixels','Position',[25,figdims(2)/3,figdims(1)-50,(figdims(2)*2/3)-20]);
  hist(histData,max(histData));
  mytitle = sprintf('Connectivity of data in figure %d using threshold %1.5f', mfn, theVars(mfn).thresholdTesters(myttIndex).currentThreshold);
  title(mytitle);
  xlabel('number of connections');
  ylabel('number of verbs');

  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum,'CurrentAxes',thebigaxishandle);

  closeWindowButtonDims=[140,25];
  closeWindowButton = uicontrol('Style','pushbutton','String','close',...
				'Position',[0,0,closeWindowButtonDims],'Callback',...
				{@statsCloseButtonCallback,mfn,myttIndex});

  customizeButtonDims=[140,25];
  customizeButton = uicontrol('Style', 'pushbutton', 'String', 'customize...',...
			      'Position',[figdims(1)-customizeButtonDims(1),...
		    0,customizeButtonDims],'Callback', {@customizeStatsButtonCallback,...
		    mfn, myttIndex});
  
  tt2 = text(10, closeWindowButtonDims(2)+5,...
	     'Total number of squares to display in the whole data set:',...
	     'FontSize',textsize,'HorizontalAlignment','left',...
	     'VerticalAlignment','baseline','Units','pixels');
  tt2Extent=get(tt2,'Extent');
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.totalNumPatchesText = ...
      text(tt2Extent(1)+tt2Extent(3)+5, closeWindowButtonDims(2)+5, num2str(numberPatches),...
      'FontSize',textsize,'HorizontalAlignment','left',...
       'VerticalAlignment','baseline','Units','pixels');
  
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.manyConPromptHandle = ...
      text(10, closeWindowButtonDims(2)+textsize+2*5,...
	     manyConPrompt, 'FontSize',textsize,'HorizontalAlignment','left',...
	     'VerticalAlignment','baseline','Units','pixels');
  manyConPromptExtent=get(theVars(mfn).thresholdTesters(myttIndex).statsWindow.manyConPromptHandle,'Extent');
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyConnectionsText = ...
      text(manyConPromptExtent(1)+manyConPromptExtent(3)+5, closeWindowButtonDims(2)+textsize+2*5,...
	   manyConString, 'FontSize',textsize,'HorizontalAlignment','left',...
       'VerticalAlignment','baseline','Units','pixels','FontWeight','bold');
  
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.fewConPromptHandle = ...
      text(10,closeWindowButtonDims(2)+2*textsize+3*5 ,...
	    fewConPrompt,'FontSize',textsize,'HorizontalAlignment','left',...
	    'VerticalAlignment','baseline','Units','pixels');
  fewConPromptExtent=get(theVars(mfn).thresholdTesters(myttIndex).statsWindow.fewConPromptHandle,'Extent');
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewConnectionsText = ...
      text(fewConPromptExtent(1)+fewConPromptExtent(3)+5, closeWindowButtonDims(2)+2*textsize+3*5, ...
	fewConString, 'FontSize',textsize,'HorizontalAlignment','left',...
       'VerticalAlignment','baseline','Units','pixels','FontWeight','bold');
else
  %the desired figure already exists, update its display
  figure(theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum);
  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum,'CurrentAxes',...
		    theVars(mfn).thresholdTesters(myttIndex).statsWindow.histAxis);
  hist(histData,max(histData));
  mytitle = sprintf('Connectivity of data in figure %d using threshold %f', ...
		    mfn,theVars(mfn).thresholdTesters(myttIndex).currentThreshold);
  title(mytitle);
  xlabel('number of connections');
  ylabel('number of verbs');

  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.fewConPromptHandle,...
      'String', fewConPrompt);
  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewConnectionsText,...
      'String', fewConString);
  
  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.manyConPromptHandle,...
      'String', manyConPrompt);
  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyConnectionsText,...
      'String', manyConString);
  
  set(theVars(mfn).thresholdTesters(myttIndex).statsWindow.totalNumPatchesText,...
      'String',num2str(numberPatches));
  
end;

function statsCloseButtonCallback(obj, eventdata, mfn, myttIndex)
global theVars;

if(myFigureCloseRequest)
  %0 --> flag stats window as non-existant
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum = 0;
end;


function useThisButtonCallback(obj, eventdata, mfn, myttIndex)
global theVars;
%check if any of the simMode, threshold or {NAME}naming choices have
%changed, and make appropriate updates to info window and main
%figure (do nothing if nothing has changed)

%close this TT window (and DON'T ask the user if they're sure)
thisWindow = theVars(mfn).thresholdTesters(myttIndex).figNum;
theVars(mfn).thresholdTesters(myttIndex).figNum = 0; %flag as unused
subs = []; %other windows to close if this does
if(theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum > 0)
  % prepare to close the corresponding stats window
  subs = theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum;
end;

closeTTnoOption(thisWindow,subs);
theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum = 0;

%clear memory
theVars(mfn).thresholdTesters(myttIndex).patchhandles = [];
theVars(mfn).thresholdTesters(myttIndex).tables = {};
theVars(mfn).thresholdTesters(myttIndex).buttonHandleList = [];
theVars(mfn).thresholdTesters(myttIndex).tophandles = [];
theVars(mfn).thresholdTesters(myttIndex).rechandles = [];
theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes = [];

msg = sprintf('Currently redrawing figure %d. Please be patient...',mfn);
writeUserMessage(mfn,{msg});

%now update the main figure
newThreshold = ...
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold;
newSimMode = theVars(mfn).thresholdTesters(myttIndex).simTypeID;
oldSimMode = theVars(mfn).simMode;
if(theVars(mfn).visThreshold ~= newThreshold | ...
   oldSimMode ~= newSimMode)
  theVars(mfn).simMode = newSimMode; %set the new sim measure
  theVars(mfn).visThreshold = newThreshold; %set the new threshold
  updateSimInfo(mfn);

  set(0,'CurrentFigure',mfn); %set the focus figure, but DON'T BRING TO FRONT
  makeNewPatches(mfn);
  figure(mfn); %bring to foreground

  %next test is special for verbs data
  if(oldSimMode <=3 & newSimMode >3)
    theVars(mfn).fni=2;
    updateFeatureListHandles(mfn); %numFeatures has changed
  elseif(oldSimMode > 3 & newSimMode <=3)
    theVars(mfn).fni=1;
    updateFeatureListHandles(mfn); %numFeatures has changed
  end;
  %erase the 'please wait' message
  writeUserMessage(mfn,{''});
%else, nothing has changed, so do nothing
end;
%test is need to change {NAMES}


function animateForwards(mfn, myttIndex)
%threshold will INCREASE from currentThreshold to toValue
%so we'll be turning patches OFF

global theVars;

patchesToHide=[];
tables = theVars(mfn).thresholdTesters(myttIndex).tables;
patchhandles = theVars(mfn).thresholdTesters(myttIndex).patchhandles;
simTypeID = theVars(mfn).thresholdTesters(myttIndex).simTypeID;
i=theVars(mfn).thresholdTesters(myttIndex).animIndex;
tdh = theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle;
stop = theVars(mfn).thresholdTesters(myttIndex).stopflag;
%exit this loop when we exceed the desired maxthreshold
while(~stop & i<=size(tables{simTypeID},1))
  nextThreshold = min(tables{simTypeID}(i,2),...
		      theVars(mfn).thresholdTesters(myttIndex).toValue);
  if(nextThreshold > theVars(mfn).thresholdTesters(myttIndex).toValue)
    break; %<-- EXIT the loop
  end;
  previouslyOff = theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOff;
  if(length(previouslyOff)>0)
    prevOffColors = get(previouslyOff,'EdgeColor');
    set(previouslyOff,'Visible','off');
    if(length(previouslyOff)==1)
      set(previouslyOff,'FaceColor',prevOffColors);
    else
      set(previouslyOff,{'FaceColor'},prevOffColors);
    end;
  end;
  patchesToHide = find(tables{simTypeID}(:,2)<= nextThreshold &...
		       tables{simTypeID}(:,2)>...
		       theVars(mfn).thresholdTesters(myttIndex).currentThreshold);
  if(length(patchesToHide) > 0)
    currColors=get(patchhandles(tables{simTypeID}(patchesToHide,1)),'FaceColor');
    set(patchhandles(tables{simTypeID}(patchesToHide,1)),'FaceColor','none');
    theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOff = ...
      patchhandles(tables{simTypeID}(patchesToHide,1));
  
    set(tdh,'String',sprintf('%1.5f',nextThreshold));
    i=max(patchesToHide); 
    theVars(mfn).thresholdTesters(myttIndex).animIndex=i;
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold=nextThreshold;
    %update 'recently added' list
    updateRec(tables{simTypeID}(patchesToHide,1), tables{simTypeID}(patchesToHide,2), ...
	    currColors, mfn, myttIndex);
    pause(0.5);
  else
    i=i+1;
    theVars(mfn).thresholdTesters(myttIndex).animIndex=i;
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold= ...
	nextThreshold;
    set(tdh,'String',sprintf('%1.5f',nextThreshold));
  end;
  stop = theVars(mfn).thresholdTesters(myttIndex).stopflag;
end;
%finish up if we didn't abort due to a stop call
if(~stop)
  previouslyOff = theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOff;
  if(length(previouslyOff)>0)
    prevOffColors = get(previouslyOff,'EdgeColor');
    set(previouslyOff,'Visible','off');
    if(length(previouslyOff)==1)
      set(previouslyOff,'FaceColor',prevOffColors);
    else
      set(previouslyOff,{'FaceColor'},prevOffColors);
    end;
  end;
  resumeButtonCBHelper(1,mfn,myttIndex); %toggle pause button
end;


function updateRec(verbnumList, verbscoresList, colorsList, mfn, myttIndex)
global theVars;
numnew = length(verbnumList);
rechandles = theVars(mfn).thresholdTesters(myttIndex).rechandles;
if(numnew==1)
  colorsList = num2cell(colorsList,2);
end;

%darken the text to account for the effect of the grey bg
colorsList = num2cell(mycell2mat(colorsList)*0.9,2); 


lastIndextoShow = min(theVars(mfn).thresholdTesters(myttIndex).numRecVals,numnew);
%use FullNames, not feature names for newnames
newnames = cellstr([char(theVars(mfn).allFullNames{verbnumList(1:lastIndextoShow)}), ...
		repmat(' (',lastIndextoShow,1),num2str(verbscoresList(1:lastIndextoShow)), ...
		repmat(')',lastIndextoShow,1)]);
strs = get(rechandles, 'String');
allstrs = cat(1,newnames,strs(1:end-lastIndextoShow));
set(rechandles,{'String'},allstrs);

strcolors = get(rechandles,'Color');
allcolors = cat(1,colorsList(1:lastIndextoShow),strcolors(1:end-lastIndextoShow));
set(rechandles,{'Color'}, allcolors);

%finally, keep a ref to the originalIndexes
oldrecorigI = theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes;
theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes=...
    [verbnumList(1:lastIndextoShow);oldrecorigI(1:end-lastIndextoShow)];


function animateBackwards(mfn, myttIndex)
%threshold will DECREASE from currentThreshold to toValue
%so we'll be turning patches on
global theVars;

patchesToShow=[];
tables = theVars(mfn).thresholdTesters(myttIndex).tables;
patchhandles = theVars(mfn).thresholdTesters(myttIndex).patchhandles;
simTypeID = theVars(mfn).thresholdTesters(myttIndex).simTypeID;

i=theVars(mfn).thresholdTesters(myttIndex).animIndex;
tdh = theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle;
stop = theVars(mfn).thresholdTesters(myttIndex).stopflag;

%exit this loop when we exceed the desired minthreshold
while(~stop & i>0)
  if(i>1)
    nextThreshold = max(theVars(mfn).thresholdTesters(myttIndex).toValue,...
			tables{simTypeID}(i-1,2));
  else %this is the last one to show
    nextThreshold = theVars(mfn).thresholdTesters(myttIndex).toValue;
  end;
  
  if(theVars(mfn).thresholdTesters(myttIndex).currentThreshold <= ...
     theVars(mfn).thresholdTesters(myttIndex).toValue)
    break; %<--EXIT the loop
  end;
      
  previouslyOn = theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOn;
  if(length(previouslyOn)>0)
    prevOnColors = get(previouslyOn,'FaceColor');
    if(length(previouslyOn)==1)
      set(previouslyOn,'EdgeColor',prevOnColors);
    else
      set(previouslyOn,{'EdgeColor'},prevOnColors);
    end;
    
  end;
  %we need these complicated 'find' conditions because when we
  %first start, the current threshold value may not be based on the
  %affinities of this verb
  patchesToShow = find(tables{simTypeID}(:,2)>nextThreshold &...
		       tables{simTypeID}(:,2)<=...
		       theVars(mfn).thresholdTesters(myttIndex).currentThreshold);
  
  if(length(patchesToShow)>0)
    %BLACK highlights are now used
    currColors = get(patchhandles(tables{simTypeID}(patchesToShow,1)),'FaceColor');
    set(patchhandles(tables{simTypeID}(patchesToShow,1)),'EdgeColor','k');
    set(patchhandles(tables{simTypeID}(patchesToShow,1)),'Visible','on');
    theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOn = ...
      patchhandles(tables{simTypeID}(patchesToShow,1));
  
    set(tdh,'String',sprintf('%1.5f',nextThreshold));
    i=min(patchesToShow)-1;
    theVars(mfn).thresholdTesters(myttIndex).animIndex=i;
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold=nextThreshold;
    %update 'recently removed' list
    updateRec(tables{simTypeID}(patchesToShow,1), tables{simTypeID}(patchesToShow,2),...
	    currColors, mfn, myttIndex);
    pause(0.5);
  else
    i=i-1;
    theVars(mfn).thresholdTesters(myttIndex).animIndex=i;
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold= ...
	nextThreshold;
    set(tdh,'String',sprintf('1.5f',nextThreshold)); %need this here?
  end;
  
  stop = theVars(mfn).thresholdTesters(myttIndex).stopflag;
end;
%finish up if we didn't abort due to a stop call
if(~stop)
  previouslyOn = theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOn;
  if(length(previouslyOn)>0)
    prevOnColors = get(previouslyOn,'FaceColor');
    if(length(previouslyOn)==1)
      set(previouslyOn,'EdgeColor',prevOnColors);
    else
      set(previouslyOn,{'EdgeColor'},prevOnColors);
    end;
  end;
  resumeButtonCBHelper(1,mfn,myttIndex); %toggle pause button
end;


function closeButtonCallback(obj, eventdata, mfn, myttIndex)
global theVars;

thisWindow = theVars(mfn).thresholdTesters(myttIndex).figNum;
subs = []; %other windows to close if this does

if(theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum > 0)
  % prepare to close the corresponding stats window
  subs = theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum;
end;

%close the threshold tester window & subs (if any)
if(myFigureCloseRequest(thisWindow,subs))
  %if we get in here the user didn't cancel
  theVars(mfn).thresholdTesters(myttIndex).statsWindow.figNum =0;
  theVars(mfn).thresholdTesters(myttIndex).figNum = 0;
  theVars(mfn).thresholdTesters(myttIndex).patchhandles = [];
  theVars(mfn).thresholdTesters(myttIndex).tables = {};
  theVars(mfn).thresholdTesters(myttIndex).buttonHandleList = [];
  theVars(mfn).thresholdTesters(myttIndex).tophandles = [];
  theVars(mfn).thresholdTesters(myttIndex).rechandles = [];
  theVars(mfn).thresholdTesters(myttIndex).recOrigIndexes = [];
end;


function selectedVerb = getVerbID(mfn)
global theVars;

myprompt  = 'Which verb''s connections do you want to monitor?';
mytitle   = 'Threshold Test Selection';
lines= 1;
def     = theVars(mfn).names(1); %default to the first element
selectedVerb  = inputdlg(myprompt,mytitle,lines,def);

done = 0;
while (~done & ~isempty(selectedVerb))
  %selectedVerb is empty when the user clicked 'cancel'
  if(ismember(selectedVerb,theVars(mfn).names))
    done=1;
  else
    errorprompt = sprintf('%s is not in figure %d.\n%s',selectedVerb{1},mfn,myprompt);
    selectedVerb  = inputdlg(errorprompt,mytitle,lines,def);
  end;
end;

function customizeStatsButtonCallback(obj, eventData, mfn, myttIndex)
global theVars;

promptMain = 'Show me total number of verbs with connectivity...';
promptSub = '<= this value:';
prompt1 = sprintf('%s\n%s', promptMain, promptSub);
prompt2 = '> this value:';
mytitle = 'Change what summary statistics are displayed';
lines=1;
def = {num2str(theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewBound),...
       num2str(theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyBound)};
theAnswer = inputdlg({prompt1,prompt2}, mytitle, lines, def);

theVars(mfn).thresholdTesters(myttIndex).statsWindow.numFewBound = str2num(theAnswer{1});
theVars(mfn).thresholdTesters(myttIndex).statsWindow.numManyBound = str2num(theAnswer{2});
%now redisplay based on these new settings
showStats(mfn, myttIndex);


function setAnimBounds(mfn, myttIndex)
global theVars;

basicprompt = 'Select threshold animation bounds in [-1,1].';
myFromprompt = 'FROM:';
prompt1 = sprintf('%s\n%s',basicprompt,myFromprompt);
myToprompt = 'TO:';
mytitle = 'Change the Upper and Lower Thresholds';
lines=1;
def = {num2str(theVars(mfn).thresholdTesters(myttIndex).fromValue),...
       num2str(theVars(mfn).thresholdTesters(myttIndex).toValue)};
theAnswer = inputdlg({prompt1, myToprompt}, mytitle, lines, def);

if(isempty(theAnswer))
  %user clicked 'cancel'
  return; %leave everything as it was
end;

done=0;
while(~done)
  def = theAnswer;
  %to do: implement this check so str2num is always valid
  theAnswerNums(1) = str2num(theAnswer{1});
  theAnswerNums(2) = str2num(theAnswer{2});
  maxval = max(theAnswerNums);
  minval = min(theAnswerNums);
  errorprompt = '';
  done = 1;
  
  if(maxval == minval)
    errorprompt = sprintf('TO and FROM values cannot be the same.\n%s',errorprompt);
    done=0;
  end;
  if(maxval > 1)
    errorprompt = sprintf('Selected values cannot be more than 1.\n%s',errorprompt);
    def{find(theAnswerNums > 1)}='1';
    done=0;
  end;
  if(minval < -1)
    errorprompt = sprintf('Selected values cannot be less than -1.\n%s',errorprompt);
    def{find(theAnswerNums < -1)} = '-1';
    done=0;
  end;
  if(length(errorprompt > 0))
    prompt1 = sprintf('%s\n%s', errorprompt, myFromprompt);
    theAnswer = inputdlg({prompt1, myToprompt}, mytitle, lines, def);
  end;
end;
theVars(mfn).thresholdTesters(myttIndex).fromValue = theAnswerNums(1);
theVars(mfn).thresholdTesters(myttIndex).toValue = theAnswerNums(2);


function editRangeButtonCallback(obj, eventdata, mfn, myttIndex)
global theVars;

currentThreshold = theVars(mfn).thresholdTesters(myttIndex).currentThreshold;
oldFrom = theVars(mfn).thresholdTesters(myttIndex).fromValue;
oldTo = theVars(mfn).thresholdTesters(myttIndex).toValue;

setAnimBounds(mfn, myttIndex); %sets fromValue and toValue in theVars
newFrom = theVars(mfn).thresholdTesters(myttIndex).fromValue;
newTo = theVars(mfn).thresholdTesters(myttIndex).toValue;

if(oldFrom ~= newFrom | oldTo ~= newTo)
  smaller = min(newFrom, newTo);
  bigger = max(newFrom, newTo);
  
  if(currentThreshold < smaller)
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold = smaller;
    set(theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle,'String',...
		      sprintf('%1.5f',smaller));
    adjustVisForCurrThreshold(mfn, myttIndex);
    clearRecText(mfn, myttIndex);
  elseif(currentThreshold > bigger)
    theVars(mfn).thresholdTesters(myttIndex).currentThreshold = bigger;
    set(theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle,'String',...
		      sprintf('%1.5f',bigger));
    adjustVisForCurrThreshold(mfn, myttIndex);
    clearRecText(mfn, myttIndex);
  end;
  rangeString = ['from ', num2str(newFrom),' to ', num2str(newTo)];
  set(theVars(mfn).thresholdTesters(myttIndex).rangeDisplayHandle,...
      'String',rangeString);
end;
adjustVisForCurrThreshold(mfn,myttIndex); %sort-out any cells just
                                          %turned on/off

function fillaxis(mfn, myttIndex, verbindex, selectedVerb)
global theVars;

%all the patches are drawn, so just make an array of
%origNuminputs-many 1's and the appropriate number of trailing 0's
adjacentPatchesToDraw = zeros(1,theVars(mfn).origNumrows*theVars(mfn).origNumcols);
n=theVars(mfn).origNuminputs;
adjacentPatchesToDraw(1:n) = 1;

[bghandle,patchhandles]=hintonColorOneBoxSize(reshape(adjacentPatchesToDraw,...
	theVars(mfn).origNumcols, theVars(mfn).origNumrows)', ...
	[0 0 0], 10, mfn); %always use a black border with big patches
title(selectedVerb,'FontSize',14);
theVars(mfn).thresholdTesters(myttIndex).patchhandles = patchhandles;


function adjustVisForCurrThreshold(mfn,myttIndex)
%ALSO SETS ANIM INDEX, and fixes any patchesjust turned on/off
global theVars

previouslyOff = theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOff;
if(length(previouslyOff)>0)
  prevOffColors = get(previouslyOff,'EdgeColor');
  if(iscell(prevOffColors))
    set(previouslyOff,{'FaceColor'},prevOffColors);
  else
    set(previouslyOff,'FaceColor',prevOffColors);
  end;
end;
theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOff=[];

previouslyOn = theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOn;
if(length(previouslyOn)>0)
  prevOnColors = get(previouslyOn,'FaceColor');
  if(length(previouslyOn)==1)
    set(previouslyOn,'EdgeColor',prevOnColors); 
  else
    set(previouslyOn,{'EdgeColor'},prevOnColors); 
  end;
  %assumes we set the edge to another color to indicate it's newly-on-ness
end;
theVars(mfn).thresholdTesters(myttIndex).patchHjustTurnedOn=[];

aff = theVars(mfn).thresholdTesters(myttIndex).tables{...
    theVars(mfn).thresholdTesters(myttIndex).simTypeID};

rowsToTurnOff = find(aff(:,2) <= theVars(mfn).thresholdTesters(myttIndex).currentThreshold);
indexesToTurnOff = aff(rowsToTurnOff,1);
indexesToTurnOn = setdiff([1:theVars(mfn).origNuminputs], indexesToTurnOff);

handlesToTurnOff = theVars(mfn).thresholdTesters(myttIndex).patchhandles(indexesToTurnOff);
handlesToTurnOn = theVars(mfn).thresholdTesters(myttIndex).patchhandles(indexesToTurnOn);
set(handlesToTurnOff,'Visible','off');
set(handlesToTurnOn,'Visible','on');

%re-establish the anim index
theVars(mfn).thresholdTesters(myttIndex).animIndex = ...
    min(find(theVars(mfn).thresholdTesters(myttIndex).tables{...
	theVars(mfn).thresholdTesters(myttIndex).simTypeID}(:,2)>...
	     theVars(mfn).thresholdTesters(myttIndex).currentThreshold));
if(isempty(theVars(mfn).thresholdTesters(myttIndex).animIndex))
  %set to one past the end
  theVars(mfn).thresholdTesters(myttIndex).animIndex = theVars(mfn).origNuminputs+1;
end;


function patchClickCallback(obj, eventdata, mfn, myttIndex)
global theVars;

patchIndex = find(theVars(mfn).thresholdTesters(myttIndex).patchhandles == obj);
patchcolor = get(obj, 'FaceColor');
if(strcmp(patchcolor,'none'))
  patchcolor = get(obj, 'EdgeColor');
end;
%darken the text to account for the effect of the grey bg
patchcolor = patchcolor*0.9;

%{NAME}
patchname = theVars(mfn).allFullNames{patchIndex};
set(theVars(mfn).thresholdTesters(myttIndex).clickQueryTextHandle, {'String','Color'},...
		  {patchname,patchcolor});


function setValueButtonCallback(obj, eventdata, mfn, myttIndex)
global theVars;

enterThresholdPrompt = 'Enter the desired threshold in [-1,1]';
mytitle = 'Change the Current Threshold Value';
lines=1;
def = {num2str(theVars(mfn).thresholdTesters(myttIndex).currentThreshold)};
theAnswer = inputdlg({enterThresholdPrompt}, mytitle, lines, def);

done = 0;
while (~done & ~isempty(theAnswer))
  %theAnswer is empty when the user clicked 'cancel'
  if(str2num(theAnswer{1})>=-1 & str2num(theAnswer{1})<=1)
    done=1;
  else
    errorprompt = sprintf('%g is not in [-1,1].\n%s',str2num(theAnswer{1}),enterThresholdPrompt);
    theAnswer  = inputdlg({errorprompt},mytitle,lines,def);
  end;
end;

if(done)
  theVars(mfn).thresholdTesters(myttIndex).currentThreshold = ...
      str2num(theAnswer{1});
  set(theVars(mfn).thresholdTesters(myttIndex).thresholdDisplayHandle,'String',...
		    sprintf('%1.5f',str2num(theAnswer{1})));
  
  changed = 0;
  if(theVars(mfn).thresholdTesters(myttIndex).fromValue < ...
     theVars(mfn).thresholdTesters(myttIndex).toValue)
    if(theVars(mfn).thresholdTesters(myttIndex).currentThreshold < ...
       theVars(mfn).thresholdTesters(myttIndex).fromValue)
      theVars(mfn).thresholdTesters(myttIndex).fromValue = ...
	  theVars(mfn).thresholdTesters(myttIndex).currentThreshold;
      changed = 1;
    elseif(theVars(mfn).thresholdTesters(myttIndex).currentThreshold > ...
	   theVars(mfn).thresholdTesters(myttIndex).toValue)
      theVars(mfn).thresholdTesters(myttIndex).toValue = ...
	  theVars(mfn).thresholdTesters(myttIndex).currentThreshold;
      changed = 1;
    end;
  else %from > to
    if(theVars(mfn).thresholdTesters(myttIndex).currentThreshold > ...
       theVars(mfn).thresholdTesters(myttIndex).fromValue)
      theVars(mfn).thresholdTesters(myttIndex).fromValue = ...
	  theVars(mfn).thresholdTesters(myttIndex).currentThreshold;
      changed = 1;
    elseif(theVars(mfn).thresholdTesters(myttIndex).currentThreshold < ...
	   theVars(mfn).thresholdTesters(myttIndex).toValue)
      theVars(mfn).thresholdTesters(myttIndex).toValue = ...
	  theVars(mfn).thresholdTesters(myttIndex).currentThreshold;
      changed = 1;
    end;
  end;
  
  if(changed)
    rangeString = ['from ', num2str(theVars(mfn).thresholdTesters(myttIndex).fromValue),...
		   ' to ', num2str(theVars(mfn).thresholdTesters(myttIndex).toValue)];
    set(theVars(mfn).thresholdTesters(myttIndex).rangeDisplayHandle,'String',rangeString);
  end;
  adjustVisForCurrThreshold(mfn,myttIndex);
end;


function indextouse = getNextAvailableTTindex(mfn)
global theVars;

if(length(theVars(mfn).thresholdTesters)==0)
  %it's the first one
  indextouse = 1;
else
  freedOnes = find([theVars(mfn).thresholdTesters.figNum]==0);

  if(isempty(freedOnes))
    indextouse = length(theVars(mfn).thresholdTesters)+1;
  else
    indextouse = freedOnes(1);    
  end;
end;