% Clear the workspace
close all;
clear;

% Here we call some default settings for setting up Psychtoolbox
PsychDefaultSetup(2);

Screen('Preference', 'SkipSyncTests', 2);

% Get the screen numbers
screens = Screen('Screens');

% Draw to the external screen if avaliable
screenNumber = max(screens);

% Define colors
white = WhiteIndex(screenNumber);
black = BlackIndex(screenNumber);
blue = [0 0 white];
red = [white 0 0];

% Open an on screen window
[window, windowRect] = PsychImaging('OpenWindow', screenNumber, black,...
    [], [], [], [], [], kPsychNeedRetinaResolution);

% Get the size of the on screen window
[screenXpixels, screenYpixels] = Screen('WindowSize', window);

% Get the centre coordinate of the window
[xCenter, yCenter] = RectCenter(windowRect);

% Change the blend function for anti-aliasing
Screen('BlendFunction', window, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');

% Set the size of the text
textSize = 260;
Screen('TextSize', window, textSize);

% Hide the mouse cursor
HideCursor;

% Maximum priority level
topPriorityLevel = MaxPriority(window);
Priority(topPriorityLevel);

% Query the frame duration
ifi = Screen('GetFlipInterval', window);

% Number of frames to wait before redrawing
waitframes = 1;

% The alphabet
theAlphaBet = 'a':'z';
numLetters = length(theAlphaBet);

% Positions of the letters: we put them on a square grid. The grids size is
% larger, in terms of slots, then the length of the alphabet. It is just an
% easy was to position them.
dim = 2;
pixScale = 300;
[x, y] = meshgrid(-dim:dim + 1, -dim:dim + 1);
x = reshape((x .* pixScale + yCenter), 1, numel(x));
y = reshape((y .* pixScale + yCenter), 1, numel(y));

% Line width for the bounding boxes
lineWidth = 4;

% Letters with possible issues: these are defined as those where the xy
% requested position of the text and reported end of the text do not match
% bounding box corners
oddLetters = {'a', 'c', 'e', 'm', 'n', 'o',...
    'r', 's', 'u', 'v', 'w', 'x', 'z'};

% Loop the animation until a key is pressed. Note the reverse of x and y to
% get the order of the letters left-right rather then up-down
for i = 1:numLetters

    % Get this letter and compare it to the "odd" list
    thisLetter = theAlphaBet(i);
    isOdd = sum(strcmp(thisLetter, oddLetters));

    % Draw the letter and get the text bounds and the reported end position
    % of the text
    [nx, ny, textBounds] = DrawFormattedText(window, thisLetter, y(i), x(i), white);

    % Draw the text bounding box
    Screen('FrameRect', window, blue, textBounds, lineWidth);

    % Draw the text "corrected" bounding box
    if isOdd == 1
        corrValue = ny - textBounds(4);
        Screen('FrameRect', window, red, textBounds + [0 corrValue 0 corrValue], lineWidth);
    end

    % Draw the requested screen position of the text as a dot
    Screen('DrawDots', window, [y(i) x(i)], 25, blue, [], 2);

    % Draw the reported end of the text as a square (we use the DrawDots
    % command with no antialising to give a square)
    Screen('DrawDots', window, [nx ny], 25, blue, [], 0);

end

% Flip to the screen
Screen('Flip', window);

% Clear the screen
KbStrokeWait(-1)
sca;