function STIM = addDotMotionOnTop(win,img,coherence,direction,numFrames,varargin)
% STIM = addDotMotionOnTop(win,img,coherence,direction,[numFrames,options])
%
% addDotMotionOnTop: adds a dot-motion stimulus (single trial) on top of a pre-existing image in 
% a series of off-screen  windows, returning an array of pointers to the windows (STIM). 
% Each entry in STIM is a pointer to one frame of the trial.
% inputs:
%
%	win: pointer to onscreen window being used to display stimuli
%
%	img: image to place underneath the stimulus
%
%	coherence: level of coherence for motion in the trial, as a percent. Ranges from 0 
%		(totally random motion) to 100 (all dots moving together).
%
%	direction: if 0, coherent motion will be to the left. Otherwise, motion will be to the right.
%
%	numFrames: number of frames in the trial. Default = 10.
%
%	Options include: 
%	'stimSize',[value],...: size of the stimulus, in pixels (as a side of a square).
%		Default = size of the image.
%	'noFixation':  don't add a fixation cross. Default is to add a fixation cross
%	'dotSize': set the dot size. Default = 2.
%	'velocity': set the velocity of motion in pixels/frame. Default = 5.
%
%
% created 1/03 by ras (for fMR-A Expt 3)
% 1/14/03 ras: addDotMotionOnTop2: tries to better approximate the Newsome stimulus, incl. differing
% dot intensities, more dots
% 2/28/03 ras: changed algorithm to be faster (fewer for loopage), but not multiple
% colors anymore (will be soon)
% 
if ~exist('numFrames','var') 	numFrames = 10;	end
rect = screen(win,'Rect');
X = rect(3); Y = rect(4);

%%%%% parameters / defaults %%%%%%%%%%%%%%%%%%
stimSize = min(size(img));
dotSz = 1;
numDots = 150;
velocity = 5; 		% pixels per frame, rate of motion for coherent dots
jitterVelocity = 1;	% amount which to randomly  vary velocity among coherent dots
dotColor = 254;	% pointer in screen's lookup table for dot color
gray = 127;
addFixation = 1;
fixcol = 254;   		% fixation color: leave off a few values for reserved cols
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%% parse the option flags %%%%%%%%%%%%%%%%%%%
for i = 1:length(varargin)
	switch varargin{i}
	case 'addFixation'
		addFixation = 1;
	case 'noFixation'
		addFixation = 0;
	case 'left'
		direction = 0;
	case 'right'
		direction = +1;
	case {'dotSize','dotSz'}
		dotSz = varargin{i+1};
	case 'stimSize'
		stimSize = varargin{i+1};
	case 'velocity'
		velocity = varargin{i+1};
	case 'numDots'
		numDots = varargin{i+1};
	case 'dotColor'
		dotColor = varargin{i+1};
	case 'gray'
		gray = varargin{i+1};
	case 'fixcol',
		fixcol = varargin{i+1};
	otherwise,
		if ischar(varargin{i})
			fprintf('\nWARNING: addDotMotionOnTop unrecognized option flag "%s".\n', varargin{i});
		end
	end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

numCohDots = round(numDots * (coherence/100));
numNoiseDots = numDots - numCohDots;
if direction==0
	direction = -1;
else
	direction = 1;
end
minX = round(X/2 - stimSize/2);
maxX = round(X/2 + stimSize/2);
minY = round(Y/2 - stimSize/2);
maxY = round(Y/2 + stimSize/2);
imgRect = [minX minY maxX maxY];
r = round(stimSize/2);

%%%%% constrain img to a circle of radius r
[xx,yy] = meshgrid(1:stimSize);
dX = xx-r; dY = yy-r;
R = sqrt(dX.*dX + dY.*dY);
img(R > r) = gray;

% fprintf('Creating dot stimuli.');
for frame  = 1:numFrames
	STIM(frame) = screen(win,'OpenOffScreenWindow',gray);
	currimg = img;

	%%%%% draw coherent dots on current image, taking into account
	%%%%% their location on the previous frame, direction and velocity
	if frame==1
		loc = round((stimSize^2)*rand(numCohDots,1));
	else
		jitter = RandSample([-1*jitterVelocity:jitterVelocity],size(loc))';
		loc = loc + direction*(jitter + velocity)*stimSize;
	end
	
	% constrain to a circle of radius r
	ind = find( (mod(loc,stimSize)-r).^2 + (floor(loc/stimSize)-r).^2 > r^2);
	while ~isempty(ind)
		loc(ind) = round((stimSize^2) * rand(size(ind)));
		ind = find( (mod(loc,stimSize)-r).^2 + (floor(loc/stimSize)-r).^2 > r^2);
	end

	% expand to dotSz 
	coh = [];
	for row = 1:dotSz
		for col = 1:dotSz
			coh = [coh; loc + row - stimSize*col];
		end
	end	
	coh = coh(find(coh > 0 & coh < stimSize^2));

	currimg(coh) = dotColor;
	
	%%%%% draw noise dots on current image
	locN = round((stimSize^2)*rand(numNoiseDots,1));
	
	% constrain to a circle of radius r
	ind = find( (mod(locN,stimSize)-r).^2 + (floor(locN/stimSize)-r).^2 > r^2);
	while ~isempty(ind)
		locN(ind) = round((stimSize^2) * rand(size(ind)));
		ind = find( (mod(locN,stimSize)-r).^2 + (floor(locN/stimSize)-r).^2 > r^2);
	end

	% expand to dotSz
	noise = [];
	for row = 1:dotSz
		for col = 1:dotSz
			noise = [noise; locN + row - stimSize*col];
		end
	end	
	noise = noise(find(noise > 0 & noise < stimSize^2));
	
	currimg(noise) = dotColor;
		
	%%%%% put up next frame of movie
	screen(STIM(frame),'PutImage',currimg,imgRect,'srcCopyQuickly');
	
	if addFixation
		PutFixation(STIM(frame),X,Y,fixcol);
	end
	
% 	fprintf('.');
end		
% fprintf('\n');

return
