function [ springLength, maxDeflectionAngle, maxDeflectionLocation, springDeflection, avgPitch, maxPitch, maxPitchLocation, pitchStdDeviation, midpointMatrix, edgeMidpointMatrix ] = measureValues( bw, distanceMatrix, connectionMatrix, centers, ratio )
%MEASUREVALUES Summary of this function goes here
%   Output:
%   
%   springLength          - The full length of the spring
%   maxDeflectionAngle    - Angle of the biggest deflection
%   maxDeflectionLocation - Location of the biggest deflection
%   springDeflection      - Difference between the deflection of the first
%                           and last segment
%   avgPitch              - Average pitch between the segments
%   maxPitch              - Biggest pitch
%   maxPitchLocation      - Location of the bigest pitch
%   pitchStdDeviation     - Standard deviation of the pitch
%   midpointMatrix        - Contains the coordinates of segment midpoints
%   edgeMidpointMatrix    - Contains the coordinates of edge midpoints
%
%   Input:
%
%   bw                    - Binary image of the spring
%   distanceMatrix        - Length of the edges
%   centers               - Coordinates of the vertices
%   connectionMatrix      - Edge types:
%                               0: No connecteion 
%                               1: Edge between two points on the same side
%                               2: Edge between two points on different
%                                  side
%   ratio                 - Conversion ratio [px/mm]

% Init output variables
springLength = 0;
maxDeflectionAngle = 0;
maxDeflectionLocation = [];
springDeflection = 0;
avgPitch = 0;
maxPitch = 0;
maxPitchLocation = 0;
pitchStdDeviation = 0;
midpointMatrix = [];
edgeMidpointMatrix = [];

% Number of vertices
vertices = size(distanceMatrix, 1);

% Count the edges between point on the same side
sameEdges = 0;
seen = zeros(vertices, vertices);

for i = 1:vertices
    for j = 1:vertices
        if (connectionMatrix(i, j) == 1 && seen(i, j) == 0)
            sameEdges = sameEdges + 1;
            
            seen(i, j) = 1;
            seen(j, i) = 1;
        end
    end
end

% Compute the segment midpoints
midpointMatrix = zeros(sameEdges, 2);
edgeMidpointMatrix = zeros(vertices, 2);
seen = zeros(vertices, 1);
minY = 1000;
minYVertex = 0;

% Search the "highest" vertex
for i = 1:vertices 
    if (sum(connectionMatrix(i, :) > 0) >= 1 && sum(connectionMatrix(i, :) > 1) >= 1)
         if (centers(i, 2) < minY)
                minY = centers(i, 2);
                minYVertex = i;
         end
    end
end

currentVertex = minYVertex;
for i = 1:sameEdges
    nextVertex = 0;
    oppositeVertex = 0;
    edgeMidpoint = zeros(1, 2);
    
    for j = 1:vertices
        if (connectionMatrix(currentVertex, j) == 1 && seen(j) == 0)
             edgeMidpoint(1, :) = (centers(currentVertex, :) + centers(j, :)) ./ 2; 
         elseif (connectionMatrix(currentVertex, j) == 2 && seen(j) == 0)
             nextVertex = j;
             oppositeVertex = j;
         end
    end
    
    if (oppositeVertex > 0 && sum(edgeMidpoint(1, :) > 0) == 2)
        midpointMatrix(i, :) = (edgeMidpoint(1, :) + centers(oppositeVertex, :)) ./ 2;
        edgeMidpointMatrix(oppositeVertex, :) = edgeMidpoint(1, :);
    end
    
    seen(currentVertex) = 1;
    currentVertex = nextVertex;
end

% Compute deflection angles
maxDeflectionAngle = 0;
maxDeflectionLocation = zeros(1, 2);

for i = 3:sameEdges
    currentAngle = angleBetweenLines(midpointMatrix(i-2, 1), midpointMatrix(i-2, 2), midpointMatrix(i-1, 1), midpointMatrix(i-1, 2), midpointMatrix(i-1, 1), midpointMatrix(i-1, 2), midpointMatrix(i, 1), midpointMatrix(i, 2));
    
    if (abs(currentAngle) > abs(maxDeflectionAngle))
        maxDeflectionAngle = currentAngle;
        maxDeflectionLocation(1, :) = midpointMatrix(i-1, :);
    end
end

% Total deflection angle
temp = sameEdges;

for i = 1:sameEdges
    if (sum(midpointMatrix(i, :) == 0) == 2)
        temp = i-1; 
    end
end

springDeflection = angleBetweenLines(midpointMatrix(1, 1), midpointMatrix(1, 2), midpointMatrix(2, 1), midpointMatrix(2, 2), midpointMatrix(temp-2, 1), midpointMatrix(temp-2, 2), midpointMatrix(temp-1, 1), midpointMatrix(temp-1, 2));

% Compute spring length
for i = 2:sameEdges
    springLength = springLength + sqrt((abs(midpointMatrix(i-1, 1) - midpointMatrix(i, 1)))^2 + (abs(midpointMatrix(i-1, 2) - midpointMatrix(i, 2)))^2);
end

% Compute the length of the last 2 segment of the spring (top and bottom)
topOfTheSpring = [];
bottomOfTheSpring = [];
temp = sameEdges;
[m_top, b_top] = lineEquation(midpointMatrix(2, 1), midpointMatrix(2, 2), midpointMatrix(1, 1), midpointMatrix(1, 2));

for i = 1:sameEdges
    if (sum(midpointMatrix(i, :) == 0) == 2)
        temp = i-1; 
    end
end

[m_bottom, b_bottom] = lineEquation(midpointMatrix(temp-1, 1), midpointMatrix(temp-1, 2), midpointMatrix(temp, 1), midpointMatrix(temp, 2));

counter = 1;
while (size(topOfTheSpring, 2) == 0)   
    x_top = (counter - b_top) / m_top;
    
    x_top = floor(x_top);
    
    if (bw(counter, x_top) == 0)
        topOfTheSpring = [topOfTheSpring; [x_top counter]];
    end
    
    counter = counter + 1;
end

counter = size(bw, 1);
while (size(bottomOfTheSpring, 2) == 0)   
    x_bottom = (counter - b_bottom) / m_bottom;
   
    x_bottom = floor(x_bottom);
    
    if (bw(counter, x_bottom) == 0)
        bottomOfTheSpring = [bottomOfTheSpring; [x_bottom counter]];
    end
    
    counter = counter - 1;
end

topSegmentLength = sqrt((abs(midpointMatrix(1, 1) - topOfTheSpring(1, 1)))^2 + (abs(midpointMatrix(1, 2) - topOfTheSpring(1, 2)))^2);
bottomSegmentLength = sqrt((abs(midpointMatrix(temp, 1) - bottomOfTheSpring(1, 1)))^2 + (abs(midpointMatrix(temp, 2) - bottomOfTheSpring(1, 2)))^2);
springLength = springLength + topSegmentLength + bottomSegmentLength;

midpointMatrix = [topOfTheSpring; midpointMatrix];

temp = 0;
for i = 1:size(midpointMatrix, 1)
    if (sum(midpointMatrix(i, :) == 0) == 2)
        temp = i; 
    end
end

if (temp == 0)
    midpointMatrix = [midpointMatrix; bottomOfTheSpring];
else
    midpointMatrix(temp, :) = bottomOfTheSpring(1, :);
end

% Compute pitch
seen = zeros(vertices, vertices);
lengthVector = [];

for i = 1:vertices
    for j = 1:vertices
        if (connectionMatrix(i, j) == 1 && seen(i, j) == 0)
            lengthVector = [lengthVector; distanceMatrix(i, j)];
            
            if (distanceMatrix(i, j) > maxPitch)
                maxPitch = distanceMatrix(i, j);
                maxPitchLocation = [centers(i, 1) centers(i, 2); centers(j, 1) centers(j, 2)];
            end
            
            seen(i, j) = 1;
            seen(j, i) = 1;
        end
    end
end

avgPitch = mean(lengthVector);
pitchStdDeviation = std(lengthVector);

% Convert px to mm
springLength = springLength / ratio;
avgPitch = avgPitch / ratio;
maxPitch = maxPitch / ratio;
pitchStdDeviation = pitchStdDeviation / ratio;

end