package se.cth.hedgehogphoto.map.model;
import java.awt.Point;
import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import se.cth.hedgehogphoto.database.LocationObject;
import se.cth.hedgehogphoto.database.PictureObject;
/**
* Logical representation of a "multiple marker".
* @author Florian Minges
*/
public class MultipleMarkerModel extends AbstractMarkerModel {
/* Will currently ALWAYS hold 2 markers. */
private List<AbstractMarkerModel> markers;
private Point.Double longlat;
public MultipleMarkerModel(AbstractMarkerModel markerOne, AbstractMarkerModel markerTwo) {
this.markers = new ArrayList<AbstractMarkerModel>();
this.markers.add(markerOne);
this.markers.add(markerTwo);
setIconPath(Global.MULTIPLE_MARKER_ICON_PATH);
initialize();
setProperPosition();
handleVisibility();
}
public List<AbstractMarkerModel> getMarkerModels() {
return this.markers;
}
private void setProperPosition() {
setPointerPosition(computePosition());
}
private Point computePosition() {
int xSum = 0;
int ySum = 0;
int nbrOfMarkers = this.markers.size();
for (int index = 0; index < nbrOfMarkers; index++) {
AbstractMarkerModel marker = this.markers.get(index);
xSum += marker.getXPointerPosition() * marker.getNumberOfLocations();
ySum += marker.getYPointerPosition() * marker.getNumberOfLocations();
}
int averageX = xSum / this.getNumberOfLocations();
int averageY = ySum / this.getNumberOfLocations();
return new Point(averageX, averageY);
}
public void handleVisibility() {
AbstractMarkerModel markerOne = this.markers.get(0);
AbstractMarkerModel markerTwo = this.markers.get(1);
markerOne.handleVisibility(); //let submarkers handle their visibility status first
markerTwo.handleVisibility(); //if they are invisible, this marker will be that too
if (markerOne.intersects(markerTwo) && markerOne.isVisible() && markerTwo.isVisible()) {
this.show();
} else {
this.hide();
}
}
public void show() {
this.markers.get(0).setVisible(false);
this.markers.get(1).setVisible(false);
this.setVisible(true);
}
public void hide() {
this.setVisible(false);
}
/** Responds to map-actions like drag and zoom. */
@Override
public void propertyChange(PropertyChangeEvent event) {
super.propertyChange(event);
this.markers.get(0).propertyChange(event);
this.markers.get(1).propertyChange(event);
if (event.getPropertyName().startsWith(Global.ZOOM)) {
handleVisibility();
}
}
@Override
protected int getXOffset() {
return getComponentWidth() / 2;
}
@Override
protected int getYOffset() {
return getComponentHeight() / 2;
}
@Override
public List<PictureObject> getPictures(List<PictureObject> pictures) {
int nbrOfMarkers = this.markers.size();
for (int index = 0; index < nbrOfMarkers; index++) {
pictures = this.markers.get(index).getPictures(pictures);
}
return pictures;
}
@Override
protected int computeNumberOfLocations() {
int nbrOfPictures = 0;
int nbrOfMarkers = this.markers.size();
for (int index = 0; index < nbrOfMarkers; index++) {
nbrOfPictures += this.markers.get(index).computeNumberOfLocations();
}
return nbrOfPictures;
}
@Override
protected Point.Double getLonglat() {
if (this.longlat == null)
computeLonglat();
return this.longlat;
}
private void computeLonglat() {
List<PictureObject> pictures = new LinkedList<PictureObject>();
pictures = this.getPictures(pictures);
double averageLongitude = 0.0;
double averageLatitude = 0.0;
for (PictureObject picture : pictures) {
LocationObject loc = picture.getLocation();
averageLongitude += loc.getLongitude();
averageLatitude += loc.getLatitude();
}
averageLongitude = averageLongitude / pictures.size();
averageLatitude = averageLatitude / pictures.size();
this.longlat = new Point.Double(averageLongitude, averageLatitude);
}
}