%-------------------------------------------------------------------------%
% Part of array visualizer for CoF applications as part of my thesis 
% project titled 'High-density interconnect technology optimised for 
% flexible implants'.
% Full documentation can be found in my thesis report.
%
% Author:   T.B. Hosman
% E-mail:   timhosman@posteo.net
% Version:  1.2
% Created:  01/08/2019
% Modified: 22/08/2019
%-------------------------------------------------------------------------%

function [numberOfPads,visualizerArray,rFull] = ...
    generate_visual(OUTER_PADS,TOTAL_R,showUnscaled)
%GENERATEVISUAL This function is used in combination with the optimizer 
% script, it generates a matrix of pad locations and sums a number of pads
% of the array. 
%   OUTER_PADS  = int number of pads on one side of chip periphery
%   TOTAL_R     = int number of routable rows
%   showUnscaled = boolean for showing unscaled visualization (true) 
%                   or not (false)
%   numberOfPads = number of pads of the generated array
%   visualizerArray = representation of generated visual. '1' represents
%                       array connections. '0' represents no connections.
%   rFull       = returns if the array is completely filled or not

% Check if values are realistic
rFull = false;
if (ceil(OUTER_PADS/2)>=TOTAL_R) fprintf('Valid visualizer input\n')
else
    warning ('Cannot utilize all rows, incorrect calculations likely');
    rFull = true;
    % This will likely cause stray values, calculating higher than desired
    % number of pads on a large area. These will be sub-optimal values.
end

%% Generate initial visualizer array
arraySize = (OUTER_PADS * 2) - 1;
visualizerArray = int8(zeros(arraySize));
for n=1:((arraySize-1)/2+1)
    visualizerArray(2*n-1,1:end) = mod(1:arraySize,2);
end

%% Empty unreachable array area
unreachableRows = OUTER_PADS - 2 * TOTAL_R;
if (unreachableRows > 0)
    %fillerArray = zeros(unreachableRows * 2 - 1);
    fillerStartLoc = 2 * TOTAL_R + 1;
    fillerEndLoc = 2 * (OUTER_PADS - TOTAL_R) - 1;
    visualizerArray(fillerStartLoc:fillerEndLoc, ...
        fillerStartLoc:fillerEndLoc) = 0;%fillerArray;
end

%% Plot visuals
% credit to https://stackoverflow.com/questions/3280705/
% how-can-i-display-a-2d-binary-matrix-as-a-black-white-plot
if (showUnscaled)
    TICK_SIZE = 10; % Set axis tick, larger value -> fewer pad markers
    %visualizerArray = ~visualizerArray;       % To inverse b/w color
    [r, c] = size(visualizerArray);            % Get the matrix size
    imagesc((1:c)+0.5, (1:r)+0.5, visualizerArray); % Plot the image
    colormap(gray);                            % Use a gray colormap
    axis equal                                 % Make axes grid sizes equal
    set(gca, 'XTick', 0:2*TICK_SIZE:(c+1),... % Change some axis properties
             'YTick', 0:2*TICK_SIZE:(r+1), ...
             'XTickLabel', 0:TICK_SIZE:(c+1)/2, ...
             'YTickLabel', 0:TICK_SIZE:(r+1)/2, ...
             'XLim', [1 c+1], ...
             'YLim', [1 r+1], ...
             'GridLineStyle', '-', ...
             'XGrid', 'on', ...
             'YGrid', 'on');

end

%% Return total number of pads
numberOfPads = sum(sum(visualizerArray == 1));

end