content: package tim.prune.function;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  import javax.swing.JOptionPane;
  import tim.prune.App;
  import tim.prune.I18nManager;
  import tim.prune.cmd.CompoundCommand;
  import tim.prune.cmd.PointReference;
  import tim.prune.cmd.RearrangePointsCmd;
  import tim.prune.cmd.SetSegmentsCmd;
  import tim.prune.data.DataPoint;
  import tim.prune.data.SortMode;
  import tim.prune.data.Track;
  
  
  /**
   * Class to provide the function for rearranging photo points
   */
  public class RearrangePhotosFunction extends RearrangeFunction
  {
  	/**
  	 * Constructor
  	 * @param inApp app object
  	 */
  	public RearrangePhotosFunction(App inApp) {
  		super(inApp, false);
  	}
  
  	/** Get the name key */
  	public String getNameKey() {
  		return "function.rearrangephotos";
  	}
  
  	/** Get the description key */
  	public String getDescriptionKey() {
  		return "dialog.rearrangephotos.desc";
  	}
  
  	/** Sort by filename key */
  	protected String getSortNameKey() {
  		return "sortbyfilename";
  	}
  
  	/**
  	 * Perform the rearrange
  	 */
  	protected void finish()
  	{
  		Rearrange rearrangeOption = getRearrangeOption();
  		SortMode sortOption = getSortMode();
  
  		// Collect the waypoints to the start or end of the track
  		final List<PointReference> result = collectPhotoPoints(rearrangeOption, sortOption);
  
  		if (isResultANop(result))
  		{
  			JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.rearrange.noop"),
  				I18nManager.getText("error.function.noop.title"), JOptionPane.WARNING_MESSAGE);
  		}
  		else
  		{
  			// Add all the photo points to the command
  			SetSegmentsCmd segmentCommand = new SetSegmentsCmd();
  			Track track = _app.getTrackInfo().getTrack();
  			final int numPoints = track.getNumPoints();
  			for (int i=0; i<numPoints; i++)
  			{
  				DataPoint point = track.getPoint(i);
  				if (point.getPhoto() != null) {
  					segmentCommand.addSegmentFlag(point);
  				}
  			}
  			CompoundCommand command = new CompoundCommand()
  				.addCommand(RearrangePointsCmd.from(result))
  				.addCommand(segmentCommand);
  			command.setDescription(getName());
  			command.setConfirmText(I18nManager.getText("confirm.rearrangephotos"));
  			_app.execute(command);
  		}
  	}
  
  
  	/**
  	 * Do the collection and sorting of the points
  	 * @param inRearrangeOption beginning or end
  	 * @param inSortOption optional sort criterion
  	 * @return list of point references
  	 */
  	private List<PointReference> collectPhotoPoints(Rearrange inRearrangeOption, SortMode inSortOption)
  	{
  		Track track = _app.getTrackInfo().getTrack();
  		final int numPoints = track.getNumPoints();
  		ArrayList<PointReference> photoPoints = new ArrayList<>();
  		ArrayList<PointReference> nonPhotoPoints = new ArrayList<>();
  		for (int i=0; i<numPoints; i++)
  		{
  			DataPoint point = track.getPoint(i);
  			if (point.getPhoto() != null)
  			{
  				PointReference pointReference = new PointReference(i,
  					inSortOption == SortMode.SORTBY_NAME ? point.getPhoto().getName() : null,
  					inSortOption == SortMode.SORTBY_TIME ? point.getPhoto().getTimestamp() : null);
  				photoPoints.add(pointReference);
  			}
  			else {
  				nonPhotoPoints.add(new PointReference(i, null, null));
  			}
  		}
  
  		Collections.sort(photoPoints);
  
  		// Combine the two lists into a single one
  		List<PointReference> result = new ArrayList<>();
  		if (inRearrangeOption == Rearrange.TO_START)
  		{
  			result.addAll(photoPoints);
  			result.addAll(nonPhotoPoints);
  		}
  		else
  		{
  			result.addAll(nonPhotoPoints);
  			result.addAll(photoPoints);
  		}
  		return result;
  	}
  }
  