%TRACKING.M - Simple Cogent 2000 mouse tracking demo
%             Duration = 20 sec
%             Left click ---> reports mouse status to console
%             Right click --> immediately terminates tracking demo

config_mouse(10);  %polling mode with 10ms sampling interval
config_display(1); %full screen; exclusive mode; 640x480
                   %Note: Mouse commands are 'finicky' in Windowed mode
start_cogent;      %initialize realtime MATLAB subsystem

map = getmousemap; %mouse access map
x = 0;             %cursor x-position
y = 0;             %cursor y-position
xt = 0;            %target x-position
yt = 0;            %target y-position
xtmin = -300;      %display left border
xtmax = 300;       %display right border
xbias = 1;         %target direction (plus or minus 1)
delta = 2;         %target step size
errors=zeros(4000,1); %tracking error data array (approx 60 secs worth)
n = 1;             %loop counter
loop = 1;          %loop active flag
starttime = time;  %session start time
%
%begin main animation and tracking loop
%
while (loop > 0)
   
   %Draw text at position defined by mouse (0,0 at first).
   clearpict(1);
   %draw red target
   setforecolour(1,0,0); %red
   preparestring( 'O', 1, xt, yt );
   %draw blue chase cursor
   setforecolour(0,0,1); %blue
   preparestring( '+', 1, x, y );
   %show stimulus
   drawpict( 1 );
   
   %update chase target position
   xt = xt + (xbias * delta);
   if( xt >= xtmax )
       xbias = -1;
   end
   if( xt <= xtmin )
       xbias = 1;
   end
       
   %Fetch mouse status information
   %immediately if in non-polling mode
   %or, at next sampling interval if in polling mode
   readmouse;     
   
   % Read delta-X and -Y, update coordinates and plot cursor position
   x = x + sum( getmouse(map.X) );
   y = y - sum( getmouse(map.Y) );
      
   %caclulate Euclidean distance between target and chase cursor
   %(still need to calibrate constant x,y offsets)
   eDistance = sqrt( ((x-xt)*(x-xt)) + ((y-yt)*(y-yt)) );
   errors(n) = eDistance;
   
   %process Left Button Clicks
   [mevent,mapid,times]=getmouse(map.Button1);
   if ~isempty(mevent)
       disp('Mouse event detected...');
       disp(['m-event: ',num2str(mevent)]);
       disp([' map-id: ',num2str(mapid)]);
       disp(['   time: ',num2str(times)]);
       disp(['  error: ',num2str(eDistance)]);
       disp(' ');
   end
   
   % Exit if right mouse button is pressed
   if ~isempty(getmouse(map.Button2)) & any(getmouse(map.Button2) == 128 ) 
       loop = 0;
   end

   %exit after 20 secs
   nowtime = time;
   if( (nowtime-starttime) >20000 )
       loop = 0;
   end
   
   %bump loop counter
   n = n + 1;
   
end

%
%calculate performance statistics 
%
%trim error array
errors = [errors(1:n)];
mean_error = mean(errors);
std_error = std(errors);
max_error = max(errors);
%display results summary
fprintf('\nMean error:  %f\n', mean_error);
fprintf('Std. error:  %f\n', std_error);
fprintf('Max error:   %f\n', max_error);

stop_cogent;   
