%function hyperscan1player(atNIRS,subjectName,istest)
function subjectData = hyperscan1player(atNIRS,subjectName,istest)

switch nargin
    case 0 
        atNIRS = 0;
        subjectName = 'noname';
        istest=5;
    case 1
        subjectName= 'noname';
        istest=5;
    case 2
        istest=5;
end
    
timedistribution = 1;

% In each trial, a gray circle appears and stays on the screen for
% designated amount of time via the variable 'interval' which can be
% between (.5-12s). Then it changes to green until the correct key press or
% after 'duration' (4 seconds). Participants are supposed to press button
% 'z' as fast as possible. the player starts with 100 points and wins a
% point for every press and loses a point for every early press (before
% green circle) or if they do not press in 4 seconds. at the beginning
% there is a 30sec rest period as well as in the middle (after 20 trials)
% and the end.
%
% Usage: subjectData = readygo(subjectName, istest, timedistribution)
%
%
% If istest = 1 or 4, then only 5 trials, otherwise 40 trials
%
% If timedistribution = 1, it means flat distribution over 4, 6, 8, 10, 12s
% If timedistribution = 0, it means non flat distribution w/  10     8
% 4     8    10 for 4, 6, 8, 10, 12s
% If timedistribution = -1, it means iso-response distribution w/  12
% 10 8 6 4 for 4, 6, 8, 10, 12s
% if istest = 5, there are 40 trials where the timedistribution ins
% shuffled randomly between .5 and 1.5 seconds.
%
% Example:
%   readygo('chris', 5, 1)
%
% interval, intertrialinterval, and keyname calculations by Xu Cui
% Author: Chris Gauthier. August, 2010

% makes room for 15 decimal points
format long;
%atNIRS = 1; %this is for testing

marksignal = 0;

if atNIRS ==1
    com1 = serial('COM1','BaudRate',9600,'DataBits',8,'Parity','none','StopBits',1);
    fopen(com1);
    st   = sprintf('ST\r\n');% Start
    mark1 = sprintf('F1\r\n');% Mark 1 Tapping Onset/Offset
    mark2 = sprintf('F2\r\n');% Mark 1 Tapping Onset/Offset
    ed   = sprintf('ED\r\n');% End


    %/////////// Send to Commands for OT /////////////
    fwrite(com1,st);disp('Send ST');    %Start
    pause(10);                          %10s Prescan
end


nummarkOnes = 0;
%addpath(genpath('C:\Documents and Settings\nirs\My Documents\MATLAB\cgauthie'));

if istest
    numRepeat = [1];
else
    numRepeat = [10];
end



reaction1 = []; %when user1 presses the button after they see green
eventready = []; %when it is gray
eventgo = []; %when it becomes green
eventwarning = [];
eventWrong = []; %reaction time of a wrong key press
difference = [];
rt1 = 0;
points1 = 100;
exitProgram = 0;
w =0;
x= 0;
zarray =[];
zearly = [];
small1=0;
block = 0;
restbreak = 20;


% This is a set of 40 trials with a progressbar(via line 36) and a flat
% distribution. 'interval' is a 1x40 matrix of numbers 4,6,8,10,12.
% intertrialinterval is a 1x40 matrix of numbers such as 3.220 up to 12.992
% in random order. The matrix is saved as a .mat file
if istest == 0 && knowwhentopress == 0 && timedistribution == 1
    interval = 2*(Shuffle(repmat([1:4],1,numRepeat))+1); % unit is seconds and numRepeat is = 10
    intertrialinterval = 2*(Shuffle(repmat([1:4],1,numRepeat))+1); % unit is seconds
    intertrialinterval = intertrialinterval + 2*rand(size(intertrialinterval))-1;
    save([subjectName 'sequence.mat'], 'interval', 'intertrialinterval'); % ex chrissequence.mat
    % this contains the matricies 'interval' and 'intertrialinterval'
    
end


% The set is 40 trials and the distribution is a 10, 8, 4, 8, 10 for the 4,
% 6, 8, 10, 12 second delays
if timedistribution == 0 && istest == 0
    interval = [4*ones(1, 10), 6*ones(1, 8), 8*ones(1, 4), 10*ones(1, 8), 12*ones(1, 10)];
    interval = Shuffle(interval); % after this line there is a 1x50 matrix with
    % a shuffled set of 10 fours, 8 sixes, 4 eights, 8 tens and 10 twelves.
    intertrialinterval = 2*(Shuffle(repmat([1:4],1,numRepeat))+1); % unit is seconds
    intertrialinterval = intertrialinterval + 2*rand(size(intertrialinterval))-1;
end

% iso-response distribution so it completes a 1x40 matrix with 14 fours
% 10 sixes, 8 eights, 6 tens and 2 twelves.
if timedistribution == -1 && istest == 0
    interval = [4*ones(1, 14), 6*ones(1, 10), 8*ones(1, 8), 10*ones(1, 6), 12*ones(1, 2)];
    interval = Shuffle(interval);
    intertrialinterval = 2*(Shuffle(repmat([1:4],1,numRepeat))+1); % unit is seconds and numRepeat = 10
    intertrialinterval = intertrialinterval + 2*rand(size(intertrialinterval))-1;
    % this is a second matrix of 1x40 which has values from 2.xxxx to
    % 12.xxxx in a random order
end

% this is a 5 trial test.
if istest == 1
    interval = 2*(Shuffle(repmat([1:5],1,numRepeat))+1); % unit is seconds and numRepeat = 1
    intertrialinterval = 2*(Shuffle(repmat([1:5],1,numRepeat))+1); % unit is seconds
    disp ('Time between gray circles:');
    disp (intertrialinterval);
    disp('Time between green circles:');
    disp(interval);
end

%programmer error check - its really short intervals.
if istest == 4
    interval = 2*ones(1,5);
    intertrialinterval = ones(1,5);
elseif istest == 5
    interval = 2*ones(1,40);
    %intertrialinterval = ones(1,40);
    intertrialinterval = Shuffle(repmat([6:15],1,4)/10);
end

%matrix of trials to access for trials with 'index'
trials = [interval', intertrialinterval'];
whichTrial = [1:length(trials)];


%window colors
frontcolor = 255; % white
readycolor = 100; % gray for the circle
window=Screen('OpenWindow', 0, 0);
duration = 4; %gray circle is on screen for this time before turning green
rect = Screen('Rect',window);
xcenter = .5*rect(3);
ycenter = .5*rect(4);
reactionline = ycenter + 50; %display of '+' or '-'
firstline = 250; %display win/loss and points line


radius = 90;
outline = [xcenter-radius ycenter-radius xcenter+radius ycenter+radius];
greencircle = [xcenter-(radius-20) ycenter-(radius-20) xcenter+(radius-20) ycenter+(radius-20)];
gocolor = [0 255 0]; %green color
losecolor = [255 0 0];

%escape codes
[keyIsDown, seconds, keyCode] = KbCheck;
%escapeKey = KbName('ESCAPE'); %use for mac
%escapeKey = KbName('esc'); % use for windows
%escapeKey = KbName('escape'); % use for windows
escapeKey =27;
%while KbCheck; end
%escapeMac = keyCode(41);
%escapeWin = keyCode(54);

%Hide the cursor
HideCursor;
bgcolor =0;
Screen('FillRect', window, bgcolor);
if keyIsDown
    b = KbName(keyCode);
    disp(b)
    if keyCode(escapeKey)
        exitProgram = 1;
        Screen ('CloseAll');
        ShowCursor;
    end
end

%Key Press
targetKey1 = KbName('z');
targetScan1 = KbName('z');
%for the error message if they press the wrong key when there is a green
%circle:
target1 = 'z';

%%% INSTRUCTIONS %%%
sz = Screen('Rect', window); %gets a measurement of monitor
%how to escape program
%Screen(window,'TextSize',50);
%Screen (window, 'DrawText', 'To exit, press the escape key. We will begin in 3 seconds.', 0, ycenter, frontcolor);
%Screen(window, 'Flip');
%tic
%while toc <3
%    ;
%end
%show the instructions for three seconds
showinstruction(window, frontcolor, sz);
clearscreen(window);

if istest ~= 4
rest(window, xcenter, ycenter, frontcolor);
end

%%% TRIALS %%%
% This code will show a blank screen for a designated amount of time, then
% move to a gray hollowed circle for a designated amount of time (4, 6, 8,
% 10, 12 seconds via variable 'interval' and then that will fill in with
% green for up to 4 seconds or until the participant presses the correct
% key.
%if atNIRS ==1
%    fwrite(com1, mark1);
%end
for i=1:length(trials)
    
    selectedrow = whichTrial(i);
    index = trials(selectedrow,:);
    x = 1;
    
    %clears the screen for the specified time (in seconds)
    %via the intertrialinterval
    timerSecs = GetSecs;
    
    while GetSecs < timerSecs + index(1)
        [keyIsDown, seconds, keyCode] = KbCheck;
        while KbCheck; end
        %warning if they hit a key too early
        if keyIsDown
            if keyCode(escapeKey)
                exitProgram = 1;
                break;
            end
            keyname = KbName(keyCode);
            if keyCode(escapeKey)
                break;
            end
            if iscell(keyname)
                keyname = [keyname{1} keyname{2}];
            end
            
            %if a person presses early we record the number of presses and
            %will subtract that from the total points later. 
            earlyTime = GetSecs - timerSecs;
             if strfind(keyname, 'z') 
                zearly = [zearly earlyTime];
                eventwarning = [eventwarning GetSecs];
             end
             if strfind(keyname, '/') 
                zearly = [zearly earlyTime];
                eventwarning = [eventwarning GetSecs];
             end
            
            %flashes warning
            timerSecs = GetSecs;
            warning(window, frontcolor, xcenter, ycenter);
            %FlushEvents(['keyDown']);
            timerSecs = GetSecs;
        end
        
        %show a blank screen
        clearscreen(window);
    end
    
    if      exitProgram == 1
        break;
    end
    % Put Gray Circle on
    timerSecs = GetSecs; % start timer
    eventready = [eventready timerSecs];
    while GetSecs < timerSecs + index(2)
        [keyIsDown, seconds, keyCode] = KbCheck;
        while KbCheck; end
        %warning if they hit a key too early
        if keyIsDown
            if keyCode(escapeKey)
                exitProgram = 1;
                break;
            end
            
            keyname = KbName(keyCode);
            %key = find(keyCode);
            
            if keyCode(escapeKey)
                break;
            end
            
            if iscell(keyname)
                keyname = [keyname{1} keyname{2}];
            end
             earlyTime = GetSecs - timerSecs;
            if strfind(keyname, 'z')
                zearly = [zearly earlyTime];
                eventwarning = [eventwarning GetSecs];
            end
            if strfind(keyname, '/')
                zearly = [zearly earlyTime];
                eventwarning = [eventwarning GetSecs];
            end
            
            
            timerSecs = GetSecs;
            warning(window, frontcolor, xcenter, ycenter);
            timerSecs = GetSecs;
        end
        %show the gray circle
        Screen(window,'FrameOval', readycolor, outline, 12);
        Screen(window, 'Flip');
        marksignal = marksignal + 1;
        if marksignal == 1
            if atNIRS == 1
            nummarkOnes = nummarkOnes+1;
            fwrite(com1, mark1);
            end
        end
        
    end
    if      exitProgram == 1
        break;
    end
    
    % Green Circle block of code
    rt1 = 0;
    startTime = GetSecs;
    eventgo = [eventgo startTime];
    a = 0;
    marksignal = 0;
    while GetSecs < startTime + duration
        % Check the state of the keyboard.
        [ keyIsDown, seconds, keyCode ] = KbCheck;
        
        % If the user is pressing a key, then display its code number and name.
        if keyIsDown
            format long
            % Note that we use find(keyCode) because keyCode is an array.
            % See 'help KbCheck'
            nowTime = GetSecs - startTime;
            keyname = KbName(keyCode);
            if keyCode(escapeKey)
                break;
            end
            if iscell(keyname)
                keyname = [keyname{1} keyname{2}];
            end
            
              % If the user holds down a key, KbCheck will report multiple
            % events. This is why we put them in an array and then choose
            % the smallest one.
                if strfind(keyname, 'z')
                    zarray = [zarray nowTime];
                    a=1;
                end
                if strfind(keyname, '/')
                    zarray = [zarray nowTime];
                    a=1;
                end
             
% this check of the wrong button press is not necessary for the program to run 

            %if test ~= targetKey1 && test ~= targetKey2
            %    wrong(eventWrong, seconds, window, target1, target2, frontcolor, readycolor, outline, gocolor, greencircle);
            %end
            %begin error check:
            %if(iscell(keyname))
                %fprintf('%f %i  %s%s\n', nowTime, find(keyCode), keyname{1}, keyname{2});
            %    disp([num2str(nowTime) ' ' keyname{1} ' ' keyname{2}]);
            %else
           %     disp([num2str(nowTime) ' ' keyname]);
                %fprintf('%f %i  %s\n', nowTime, find(keyCode), keyname);
            %end
            %end error check. 
        end
        
        %after one of two correct button presses, the program moves on. %
        %Xu Cui
        if a ==1 
            break;
        end
        %calls green circle function to display
        marksignal = marksignal +1;
        if atNIRS==0
            com1=0;
            mark2=0;
        end
        greenCircle(window, readycolor, outline, gocolor, greencircle, atNIRS,marksignal, com1, mark2);
        
    end

    marksignal = 0;
    if  exitProgram == 1
        break;
    end
    
    %search for first reaction time
    if isempty(zarray) ~=1
    small1 = zarray(1);
   % disp(length(zarray));
    for i = 1:length(zarray)
        if small1 > zarray(i)
            small1 = zarray(i);
        end
    end
    rt1 = small1;
    end
    
    %if they pressed early, loses points:
        if isempty(zearly) ~=1
            points1 = points1 - length(zearly);
        end
 
        %point distribution and player win/lose functions called
    if rt1 ~=0 
        if rt1<4 
        points1 = points1 + 1;
        playerwin(window, xcenter, reactionline, firstline, gocolor, points1);
        end
    elseif rt1 ==0 
        points1 = points1 - 1;
        lose(window, xcenter, reactionline, firstline, losecolor, points1);
    end
    
    %puts (in long 16 deci place format the reaction times into an array to
    %later put into the subjectData.reaction1 struct
    format long
    reaction1 = [reaction1 rt1];
    
    %displays points, win or loss, and '+' or '-' for 1.5 secs
    Screen(window, 'Flip');
    tic
    while toc < 1.5
        ;
    end
    
    %reset arrays
    zarray = [];
    slasharray = [];
    zearly = [];
    slashearly = [];
    
    %add one to the block and once block reaches 20 (aka restbreak) calls
    %rest function
    block = block + 1;
    if block == restbreak
    rest(window, xcenter, ycenter, frontcolor);
    end
end


%ending screen
if exitProgram ==1
    Screen(window,'TextSize',35);
    Screen(window,'DrawText',sprintf('Ok, goodbye!'), 100, 100, frontcolor);
else
    if istest~= 4
    rest(window, xcenter, ycenter, frontcolor);
    end
    % Thank you Screen
    Screen(window,'TextSize',20);
    Screen(window,'DrawText',sprintf('Experiment Complete! Thank You.'), 100, 100, frontcolor);
    Screen (window, 'DrawText', sprintf('Player 1 Total: %d', points1), xcenter-400,ycenter + 90, frontcolor);
end
tic
Screen(window, 'Flip');
while toc < 1
    ;
end

% If they pressed the escape key, the program exits
if exitProgram ==1
    Screen('CloseAll');
    ShowCursor;
end

%%% Saving Data in a Struct %%%
subjectData.reaction1 = reaction1;
subjectData.eventgo = eventgo;
subjectData.eventready = eventready;
subjectData.eventwarning = eventwarning;
%subjectData.eventWrong = eventWrong;
c = clock;
date = datestr(now, 'mm_dd_yy');
hour = num2str(c(4));
minute = num2str(c(5));
seconds = num2str(round(c(6)));

save(['readygo_1player_' '_' subjectName '_' date '_' hour '_' minute '_' seconds], 'subjectData', 'intertrialinterval', 'interval');

Screen('CloseAll'); %close all windows
ShowCursor;

if atNIRS == 1
    fwrite(com1,ed);disp('Send ED');    %End
    %//////////// Close Serial Port ///////////////// 
    fclose(com1);%END NIRS
    clear com1;%delete(com1);
    clear st;clear mark;clear ed;
end
return



%%%%%%%%%%%%   FUNCTIONS   %%%%%%%%%%%%%


function showinstruction(window, color, screensize)
% This function puts the instructions on the screen
%   sz = screensize;
%   Screen(window,'DrawText',sprintf('Press the button as quickly as possible when you see'), 100, sz(4)/2, color);
% 	rect = [sz(3)/2-100 sz(4)/2-100 sz(3)/2+100 sz(4)/2+100] - [200 0 200 0];
% 	Screen(window,'FrameOval', 100, rect, 20);
% 	rect = [sz(3)/2-100+20 sz(4)/2-100+20 sz(3)/2+100-20 sz(4)/2+100-20] - [200 0 200 0];
% 	Screen(window,'FillOval', [0 255 0], rect);
%   Screen(window, 'DrawLine', color, 0, 0, 100, 100);
qq = imread('instruction1.jpg');
Screen(window, 'putimage', qq);
Screen(window, 'Flip');
tic
while toc < 1.5
    ;
end
return

% Screen goes blank
function clearscreen(window)
Screen(window,'FillRect', 0);
Screen(window, 'Flip');
return

%if they hit a wrong key ----- function works, but the check to get to the
%function doesn't. this is not necessary for the code to run.
function [eventWrong] = wrong(eventWrong, seconds, window, target1, target2, frontcolor, readycolor, outline, gocolor, greencircle)
eventWrong = [eventWrong seconds];
Screen(window,'TextSize',50);
Screen (window, 'DrawText', sprintf('You are supposed to press "%s" and "%s"! Hurry, try again', target1, target2), 0,0, frontcolor);
Screen(window,'FrameOval', readycolor, outline, 12);
Screen(window,'FillOval', gocolor, greencircle);
Screen(window, 'Flip');
tic
while toc < .5
    ;
end
return

%flashes warning
function warning(window, frontcolor, xcenter, ycenter)
Screen(window,'TextSize',40);
clearscreen(window);
Screen (window, 'DrawText', 'Too Early', xcenter - 150, ycenter-50, frontcolor);
Screen(window, 'Flip');
tic
while toc <.5
    ;
end
return 

%flashes green circle
function greenCircle(window, readycolor, outline, gocolor, greencircle, atNIRS, marksignal, com1, mark2)
Screen(window,'FrameOval', readycolor, outline, 12);
Screen(window,'FillOval', gocolor, greencircle);
Screen(window, 'Flip');
if marksignal ==1
if atNIRS == 1
fwrite(com1, mark2);
end
end
return

%player wins round
function playerwin(window, xcenter, reactionline, firstline, gocolor, points1)

    Screen(window,'TextSize',50);
    Screen (window, 'DrawText', '+', xcenter-20,reactionline, gocolor);
    Screen (window, 'DrawText', sprintf('Win!'), xcenter-170,firstline, gocolor);
    Screen (window, 'DrawText', sprintf('%d', points1), xcenter+50,firstline, gocolor);
return
        
        
%Player loses the round if they don't press the 'z' in 4 seconds
function lose(window, xcenter, reactionline, firstline, losecolor, points1)
    Screen(window,'TextSize',50);
    Screen (window, 'DrawText', '-', xcenter-20,reactionline, losecolor);
    Screen (window, 'DrawText', sprintf('Lose'), xcenter-170,firstline, losecolor);
    Screen (window, 'DrawText', sprintf('%d', points1), xcenter+50,firstline, losecolor);
return

function rest(window, xcenter, ycenter, frontcolor)
Screen(window,'TextSize',40);
Screen(window,'DrawText',sprintf('Rest'), xcenter - 50, ycenter - 50, frontcolor);
Screen(window, 'Flip');
tic
while toc < 30
    ;
end
return

