% 
% chapter Demos: GaborDetection.m
% 
% opens a Full Screen Exclusive Mode Window and displays a Gabor patch on 
% either side of the screen, waits for observer response, and gives an 
% auditory feedback. It employs a 3 down 1 up adaptive procedure.
%

import psychWithJava.*;
import java.awt.event.KeyEvent;

MEAN = 0.5;
CPP = 0.05;
PHASE = 0;
ORIENTATION = 45;
SIGMA = 32;

INITIAL_CONTRAST = 0.5;
DELTA_CONTRAST = 0.05;

NOISE_AMPLITUDE = 0.2;

LEFT = 0;
RIGHT = 1;
  
try
    fs = FullScreen();
    fs.setNBuffers(2);
    fs.displayText(10,50, 'Indicate the location of Gabor patch');
    fs.displayText(10,100,'left arrow for LEFT, right arrow for RIGHT');
    fs.displayText(10,150,'press q to quit');
    fs.displayText(10,300,'now press any key to continue');
    fs.updateScreen();
    
    width = fs.getWidth();
    height = fs.getHeight();
    bg =  ones(height,width) * MEAN ;
       
    % getKeyPressed(-n) (n > 0, integer) waits until observer presses a key
    % getKeyPressed(0) or getKeyPressed() returns immediately with the
    % last key the observer pressed, if nothing is pressed returns null
    % getKeyPressed(ms) (ms > 0) returns the last key pressed immediately,
    % if there is nothing in the que, it waits for ms milliseconds then 
    % returns observer's response or null if still nothing in the que.
    fs.getKeyPressed(-1);
    fs.setBackground(java.awt.Color(MEAN,MEAN,MEAN));
    fs.blankScreen();
    fs.updateScreen();
       
    contrast = INITIAL_CONTRAST;
    
    correctCount = 0;
    
    while true
        
        stimulus = bg;
        
        order = round(unifrnd(0,1));
        
        sprintf('contrast = %f ', contrast)
        
        % I'm not sure this is the best way to generate a Gabor patch 
        % in Matlab. Though it is not a factor to slow down the program.
        gbr = gabor(MEAN,CPP,contrast,PHASE,SIGMA,ORIENTATION);
        if order == LEFT
            x = round(fs.getWidth()/4 - size(gbr,2)/2);
        else
            x = round(fs.getWidth()*3/4 - size(gbr,2)/2);
        end
        y = round( fs.getHeight()/2 - size(gbr,1)/2);
        
        stimulus(y+1:y+size(gbr,1),x+1:x+size(gbr,2))=gbr(:,:);
        stimulus=stimulus+normrnd(0,1,height,width)*NOISE_AMPLITUDE/2;
         
        %!!!!!im2java2d is the bottleneck!!!!! it takes the longest time
        fs.displayImage(im2java2d(stimulus));   
        fs.updateScreen();
        
        % clear the keyPressed que
        fs.flushKeyPressed();
        
        response = fs.getKeyPressed(-1);
        if(response==KeyEvent.VK_Q)
            break;
        elseif( (response==KeyEvent.VK_LEFT && order==LEFT) || ...
            (response==KeyEvent.VK_RIGHT && order==RIGHT) )
            correctCount = correctCount + 1;
            if correctCount == 3
                contrast = max(contrast - DELTA_CONTRAST,0);
                correctCount = 0;
            end
            sound(beepSound(1000,100));
            sprintf('succes')
        else
            contrast = min(contrast + DELTA_CONTRAST,1);
            correctCount = 0;
            sound(beepSound(10000,100));
            sprintf('fail')
        end
        fs.blankScreen();
        fs.updateScreen();
        pause(0.1);
    end
    fs.closeScreen();
catch
    fs.closeScreen();
    rethrow(lasterror);
end