function mesh = mfmAdjustSpacing(mesh, unfoldMesh, params, unfolded2D, insideNodes);
%
%  mesh = mfmAdjustSpacing(mesh, unfoldMesh, params, unfolded2D,
%  insideNodes);
%
% Author: Winawer
% Purpose:
%   Adjust the spacing of the points in a flattened mesh so they don't
%   bunch up too much.  The method is to find a cartesian grid within the
%   data, find a Delaunay triangulation of this grid, and then use a series
%   of affine transformations to transform each of the triangles to an
%   equal area representation with the proper grid topology.  This is
%   explained in more detail in flatAdjustSpacing
%  
%   Sub-routine derived from Alex's unfoldMeshFromGUI code.
%
% See Also:  unfoldMeshFromGUI

% Get all the variables we may need
meshFileName     = params.meshFileName;
grayFileName     = params.grayFileName;
flatFileName     = params.flatFileName;
startCoords      = params.startCoords;
scaleFactor      = params.scaleFactor;
perimDist        = params.perimDist;
statusHandle     = params.statusHandle;
busyHandle       = params.busyHandle;
spacingMethod    = params.spacingMethod;
adjustSpacing    = params.adjustSpacing;
gridSpacing      = params.gridSpacing;
showFigures      = params.showFigures;
saveExtra        = params.saveExtra;
truePerimDist    = params.truePerimDist;
hemi             = params.hemi;
nperims          = params.NPERIMS;
saveIntermeidate = params.SAVE_INTERMEDIATE;
numberOfSteps    = params.NUMBEROFSTEPS;

if (adjustSpacing)
    str = sprintf('Spacing points (method = %s)',spacingMethod);
    statusStringAdd(statusHandle,str);
    
    unfoldMesh.maxFractionDist = 0.8;
    unfoldMesh.gridSpacing = gridSpacing;
    unfoldMesh.locs2d = unfolded2D(:,1:2);
    unfoldMesh.startCoords = startCoords;
    unfoldMesh.scaleFactor = scaleFactor;
    
    % The user can select Cartesian or Polar spacing methods.  Only
    % Cartesian is working now, though, I think -- BW
    [newLocs2d,goodIdx] = flatAdjustSpacing(unfoldMesh,spacingMethod);
end

if (showFigures)
    statusStringAdd(statusHandle,['Displaying unfolded mesh']);
    h = unfoldMeshFigure(unfoldMesh); 

	[p f] = fileparts(flatFileName);
    ensureDirExists(p);
	savePath = fullfile(p, [f,'_Unfolded Mesh.png']);
	saveas(gcf, savePath);
	fprintf('[%s]: Saved %s.\n', mfilename, savePath);
end

% Finally - the mapping of grey to mesh points takes place using the entire mesh. 
% Therefore, we need to generate X for the mesh as well as the unfold mesh

% insideNodes is an array of indices into the original (non-bounded) mesh.
% Each entry in insideNodes relates a point in the unfoldMesh to a point in
% the original mesh 

% Recover the perimeter and internal points
mesh.X=zeros(length(mesh.uniqueVertices),2);

% In order to deal with a cropped mesh (as generated by flatAdjustSpacing)
% we need to compute the ... Alex?
if (adjustSpacing)
    
    mesh.X(insideNodes(goodIdx),:)=newLocs2d;
    hasCoords=[insideNodes(goodIdx)];
    
else
    
    unfoldToOrigPerimeter=insideNodes(unfoldMesh.orderedUniquePerimeterPoints);
    unfoldToOrigInside=insideNodes(unfoldMesh.internalNodes);
    
    mesh.X(unfoldToOrigPerimeter,:)=unfoldMesh.X_zero;
    mesh.X(unfoldToOrigInside,:)=unfoldMesh.X;
    hasCoords=[unfoldToOrigPerimeter(:);unfoldToOrigInside(:)];
    
end

coords=mesh.X(hasCoords,:);
dists=mesh.dist(hasCoords);

% use griddata to image the distance map
warning off MATLAB:griddata:DuplicateDataPoints;
mesh.distMap=makeMeshImage(coords,dists,128);
warning on MATLAB:griddata:DuplicateDataPoints;

ZI=mesh.distMap;

if (showFigures), 
	h = unfoldDistFigure(mesh); 
	
	[p f ext] = fileparts(flatFileName);
	savePath = fullfile(p, [f ' Unfold Distance.png']);
	saveas(h, savePath);
	fprintf('[%s]: Saved %s.\n', mfilename, savePath);
end

% Record which nodes in the big mesh are in the unfold
mesh.insideNodes=insideNodes;

if (saveIntermeidate)
    statusStringAdd(statusHandle,'Saving intermediate data.');
    save ('meshOutTemp.mat','mesh');
end

return


%----------------------------------
% ---- SUBROUTINES
%----------------------------------
%----------------------------------
function h = unfoldMeshFigure(unfoldMesh);
h = figure;
hold off;
gplot(unfoldMesh.N,unfoldMesh.X);
title ('Unfolded mesh'); axis equal; axis off; zoom on
return;

%----------------------------------
function h = unfoldDistFigure(mesh)
h = figure;
imagesc(mesh.distMap);
axis image; colormap hot; title('Manifold distance map'); colorbar;

% Added the abs to cope with the fact that we sometimes get -ve numbers here...
% imagesc(abs(log(areaErrorMap))); 
% axis image;
% colorbar;
% title('Log 3D/2D area');
% colormap hot;

return;
