gt: 				if (element instanceof SubTrack) {
context: /*
   * This file is part of the ZoRa project: http://www.photozora.org.
   *
   * ZoRa is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * ZoRa is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with ZoRa; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * (c) 2009 Berthold Daum  
   */
  package com.bdaum.zoom.gps.internal.dialogs;
  
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  
  import org.eclipse.jface.viewers.ArrayContentProvider;
  import org.eclipse.jface.viewers.ColumnLabelProvider;
  import org.eclipse.jface.viewers.ISelectionChangedListener;
  import org.eclipse.jface.viewers.IStructuredSelection;
  import org.eclipse.jface.viewers.SelectionChangedEvent;
  import org.eclipse.jface.viewers.StructuredSelection;
  import org.eclipse.jface.viewers.TableViewer;
  import org.eclipse.jface.viewers.TableViewerColumn;
  import org.eclipse.osgi.util.NLS;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Button;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Control;
  import org.eclipse.swt.widgets.Event;
  import org.eclipse.swt.widgets.Label;
  import org.eclipse.swt.widgets.Listener;
  import org.eclipse.swt.widgets.Shell;
  
  import com.bdaum.zoom.core.Constants;
  import com.bdaum.zoom.core.Format;
  import com.bdaum.zoom.gps.internal.GpsActivator;
  import com.bdaum.zoom.gps.internal.HelpContextIds;
  import com.bdaum.zoom.gps.internal.IMapComponent;
  import com.bdaum.zoom.gps.internal.views.Mapdata;
  import com.bdaum.zoom.ui.dialogs.ZTitleAreaDialog;
  import com.bdaum.zoom.ui.gps.Trackpoint;
  import com.bdaum.zoom.ui.widgets.DateInput;
  
  public class TrackpointDialog extends ZTitleAreaDialog  implements Listener {
  
  	public class EditDialog extends ZTitleAreaDialog implements Listener {
  
  		private final SubTrack track;
  		private final boolean split;
  		private final String message;
  		private DateInput startField;
  		private DateInput endField;
  		private Date start;
  		private Date end;
  		private final String title;
  		private final List<SubTrack> subtracks;
  
  		public EditDialog(Shell shell, List<SubTrack> subtracks, SubTrack track, boolean split, String title,
  				String message) {
  			super(shell);
  			this.subtracks = subtracks;
  			this.track = track;
  			this.split = split;
  			this.title = title;
  			this.message = message;
  		}
  
  		@Override
  		public void create() {
  			super.create();
  			getShell().setText(Constants.APPLICATION_NAME);
  			setTitle(title);
  			setMessage(message);
  			fillValues();
  			validate();
  			getShell().pack();
  		}
  
  		private void fillValues() {
  			if (split) {
  				long median = (track.getStart() + track.getEnd()) / 2;
  				long dur = (track.getEnd() - track.getStart()) / 6;
  				startField.setDate(new Date(median - dur));
  				endField.setDate(new Date(median + dur));
  			} else {
  				startField.setDate(new Date(track.getStart()));
  				endField.setDate(new Date(track.getEnd()));
  			}
  		}
  
  		@Override
  		protected Control createDialogArea(Composite parent) {
  			Composite area = (Composite) super.createDialogArea(parent);
  			Composite composite = new Composite(area, SWT.NONE);
  			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  			composite.setLayout(new GridLayout(2, false));
  			new Label(composite, SWT.NONE).setText(Messages.TrackpointDialog_start);
  			startField = new DateInput(composite, SWT.DATE | SWT.TIME | SWT.MEDIUM);
  			startField.addListener(SWT.Selection, this);
  			new Label(composite, SWT.NONE).setText(Messages.TrackpointDialog_end);
  			endField = new DateInput(composite, SWT.DATE | SWT.TIME | SWT.MEDIUM);
  			endField.addListener(SWT.Selection, this);
  			return area;
  		}
  
  		private void validate() {
  			String errorMessage = null;
  			long s = startField.getDate().getTime();
  			long e = endField.getDate().getTime();
  			if (s >= e)
  				errorMessage = Messages.TrackpointDialog_end_after_start;
  			else if (split) {
  				if (s <= track.getStart())
  					errorMessage = NLS.bind(split ? Messages.TrackpointDialog_wrong_gap_start_value
  							: Messages.TrackpointDialog_start_after_x, formatDate(track.getStart()));
  				else if (e >= track.getEnd())
  					errorMessage = NLS.bind(split ? Messages.TrackpointDialog_wrong_gap_end_value
  							: Messages.TrackpointDialog_end_before_x, formatDate(track.getEnd()));
  			} else
  				for (SubTrack t : subtracks)
  					if (s >= t.getStart() && s < t.getEnd() || e >= t.getStart() && e < t.getEnd()) {
  						errorMessage = NLS.bind(Messages.TrackpointDialog_subtrack_overlaps, formatTrack(t));
  						break;
  					}
  			setErrorMessage(errorMessage);
  			getButton(OK).setEnabled(errorMessage == null);
  		}
  
  		public long getStart() {
  			return start.getTime();
  		}
  
  		public long getEnd() {
  			return end.getTime();
  		}
  
  		public void handleEvent(Event e) {
  			validate();
  		}
  
  		@Override
  		protected void okPressed() {
  			start = startField.getDate();
  			end = endField.getDate();
  			super.okPressed();
  		}
  
  	}
  
  	public class SubTrack {
  		private long start, end;
  
  		public SubTrack(long time) {
  			start = time;
  		}
  
  		/**
  		 * @return start
  		 */
  		public long getStart() {
  			return start;
  		}
  
  		/**
  		 * @param start
  		 *            das zu setzende Objekt start
  		 */
  		public void setStart(long start) {
  			this.start = start;
  		}
  
  		/**
  		 * @return end
  		 */
  		public long getEnd() {
  			return end;
  		}
  
  		/**
  		 * @param end
  		 *            das zu setzende Objekt end
  		 */
  		public void setEnd(long end) {
  			this.end = end;
  		}
  	}
  
  	private static final long ONEMINUTE = 60000L;
  	private final List<SubTrack> subtracks = new LinkedList<TrackpointDialog.SubTrack>();
  	private TableViewer viewer;
  	private Button editButton;
  	private Button removeButton;
  	private Button joinButton;
  	private Button splitButton;
  	private final Trackpoint[] trackpoints;
  	private List<Trackpoint> result;
  	private IMapComponent mapComponent;
  	private final long tolerance;
  
  	public TrackpointDialog(Shell shell, Trackpoint[] trackpoints, long tolerance) {
  		super(shell, HelpContextIds.TRACKPOINTS);
  		this.trackpoints = trackpoints;
  		this.tolerance = tolerance;
  		SubTrack subtrack = null;
  		Trackpoint previous = null;
  		for (Trackpoint trackpoint : trackpoints) {
  			if (previous == null || subtrack == null)
  				subtrack = new SubTrack(trackpoint.getTime() - tolerance);
  			else if (previous.isSegmentEnd() || trackpoint.getTime() - previous.getTime() > 2 * tolerance) {
  				subtrack.setEnd(previous.getTime() + tolerance);
  				subtracks.add(subtrack);
  				subtrack = new SubTrack(trackpoint.getTime() - tolerance);
  			}
  			previous = trackpoint;
  		}
  		if (subtrack != null && previous != null) {
  			subtrack.setEnd(previous.getTime() + tolerance);
  			subtracks.add(subtrack);
  		}
  	}
  
  	@Override
  	public void create() {
  		super.create();
  		getShell().setText(Constants.APPLICATION_NAME);
  		setTitle(Messages.TrackpointDialog_edit_trackpoints);
  		setMessage(NLS.bind(Messages.TrackpointDialog_initial_message, formatTime(tolerance / ONEMINUTE)));
  		updateButtons();
  	}
  
  	@Override
  	protected Control createDialogArea(Composite parent) {
  		Composite area = (Composite) super.createDialogArea(parent);
  		Composite comp = new Composite(area, SWT.NONE);
  		comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  		comp.setLayout(new GridLayout(3, false));
  		createViewer(comp);
  		createButtons(comp);
  		createMapArea(comp);
  		return area;
  	}
  
  	private void createMapArea(Composite comp) {
  		mapComponent = GpsActivator.getMapComponent(GpsActivator.findCurrentMappingSystem());
  		if (mapComponent != null) {
  			mapComponent.createComponent(comp, false);
  			GridData layoutData = new GridData(GridData.FILL_BOTH);
  			layoutData.widthHint = layoutData.heightHint = 500;
  			mapComponent.getControl().setLayoutData(layoutData);
  			mapComponent.setInput(null, 12, IMapComponent.BLANK);
  		}
  	}
  
  	private void createButtons(Composite comp) {
  		Composite composite = new Composite(comp, SWT.NONE);
  		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  		composite.setLayout(new GridLayout(1, false));
  		editButton = new Button(composite, SWT.PUSH);
  		editButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
  		editButton.setText(Messages.TrackpointDialog_edit);
  		editButton.addListener(SWT.Selection, this);
  		removeButton = new Button(composite, SWT.PUSH);
  		removeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
  		removeButton.setText(Messages.TrackpointDialog_remove);
  		removeButton.addListener(SWT.Selection, this);
  		joinButton = new Button(composite, SWT.PUSH);
  		joinButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
  		joinButton.setText(Messages.TrackpointDialog_join);
  		joinButton.addListener(SWT.Selection, this);
  		splitButton = new Button(composite, SWT.PUSH);
  		splitButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
  		splitButton.setText(Messages.TrackpointDialog_split);
  		splitButton.addListener(SWT.Selection, this);
  	}
  
  	public void createViewer(Composite comp) {
  		viewer = new TableViewer(comp, SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);
  		GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
  		layoutData.widthHint = 410;
  		layoutData.heightHint = 500;
  		viewer.getControl().setLayoutData(layoutData);
  		viewer.getTable().setLinesVisible(true);
  		viewer.getTable().setHeaderVisible(true);
  		viewer.setContentProvider(ArrayContentProvider.getInstance());
  		TableViewerColumn col1 = new TableViewerColumn(viewer, SWT.NONE);
  		col1.getColumn().setWidth(170);
  		col1.getColumn().setText(Messages.TrackpointDialog_start);
  		col1.setLabelProvider(new ColumnLabelProvider() {
  			@Override
  			public String getText(Object element) {
  				if (element instanceof SubTrack)
  					return formatDate(((SubTrack) element).getStart());
  				return super.getText(element);
  			}
  		});
  		TableViewerColumn col2 = new TableViewerColumn(viewer, SWT.NONE);
  		col2.getColumn().setWidth(170);
  		col2.getColumn().setText(Messages.TrackpointDialog_end);
  		col2.setLabelProvider(new ColumnLabelProvider() {
  			@Override
  			public String getText(Object element) {
  				if (element instanceof SubTrack)
  					return formatDate(((SubTrack) element).getEnd());
  				return super.getText(element);
  			}
  		});
  		TableViewerColumn col3 = new TableViewerColumn(viewer, SWT.NONE);
  		col3.getColumn().setWidth(70);
  		col3.getColumn().setAlignment(SWT.RIGHT);
  		col3.getColumn().setText(Messages.TrackpointDialog_duration);
  		col3.setLabelProvider(new ColumnLabelProvider() {
  			@Override
  			public String getText(Object element) {
  