/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo 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 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.wkf.swleditor.gr;
import java.awt.Color;
import java.util.Observable;
import java.util.Vector;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import org.openflexo.fge.GraphicalRepresentation;
import org.openflexo.fge.ShapeGraphicalRepresentation;
import org.openflexo.fge.geom.FGEGeometricObject.SimplifiedCardinalDirection;
import org.openflexo.fge.geom.FGELine;
import org.openflexo.fge.geom.FGEPoint;
import org.openflexo.fge.graphics.BackgroundStyle;
import org.openflexo.fge.graphics.FGEShapeGraphics;
import org.openflexo.fge.graphics.ForegroundStyle;
import org.openflexo.fge.graphics.ShapePainter;
import org.openflexo.fge.notifications.ObjectHasMoved;
import org.openflexo.fge.notifications.ObjectHasResized;
import org.openflexo.fge.notifications.ObjectMove;
import org.openflexo.fge.notifications.ObjectResized;
import org.openflexo.fge.notifications.ObjectWillMove;
import org.openflexo.fge.notifications.ObjectWillResize;
import org.openflexo.fge.notifications.ShapeChanged;
import org.openflexo.fge.shapes.Shape.ShapeType;
import org.openflexo.foundation.DataModification;
import org.openflexo.foundation.FlexoObservable;
import org.openflexo.foundation.wkf.dm.ObjectVisibilityChanged;
import org.openflexo.foundation.wkf.ws.FlexoPortMap;
import org.openflexo.foundation.wkf.ws.PortMapRegistery;
import org.openflexo.icon.WKFIconLibrary;
import org.openflexo.wkf.swleditor.SwimmingLaneRepresentation;
public class PortmapGR extends AbstractNodeGR<FlexoPortMap> {
private static final Logger logger = Logger.getLogger(PortmapGR.class.getPackage().getName());
public static final int PORTMAP_SIZE = 16;
public static final int PORTMAP_ROUND_SIZE = 10;
protected SimplifiedCardinalDirection layoutedAs = null;
private PortmapRegisteryGR observedContainer;
public PortmapGR(FlexoPortMap portmap, SwimmingLaneRepresentation aDrawing) {
super(portmap, ShapeType.CIRCLE, aDrawing);
setWidth(PORTMAP_ROUND_SIZE);
setHeight(PORTMAP_ROUND_SIZE);
setLayer(ACTIVITY_LAYER);
setForeground(ForegroundStyle.makeStyle(Color.BLACK));
setBackground(BackgroundStyle.makeColoredBackground(getMainBgColor()));
// setBorder(new ShapeGraphicalRepresentation.ShapeBorder(0,10,0,0));
setDimensionConstraints(DimensionConstraints.UNRESIZABLE);
layoutAs(SimplifiedCardinalDirection.NORTH);
setShapePainter(new PortmapGRShapePainter());
updatePropertiesFromWKFPreferences();
}
@Override
public void updatePropertiesFromWKFPreferences() {
super.updatePropertiesFromWKFPreferences();
getShadowStyle().setShadowDepth(1);
getShadowStyle().setShadowBlur(3);
}
public FlexoPortMap getPortMap() {
return getDrawable();
}
@Override
public String getText() {
return null;
}
@Override
public void update(Observable observable, Object dataModification) {
if (observable == observedContainer) {
if (dataModification instanceof ObjectWillMove || dataModification instanceof ObjectWillResize
|| dataModification instanceof ObjectHasMoved || dataModification instanceof ObjectHasResized
|| dataModification instanceof ObjectMove || dataModification instanceof ObjectResized
|| dataModification instanceof ShapeChanged) {
updateLayout();
}
}
super.update(observable, dataModification);
}
@Override
public void delete() {
if (observedContainer != null) {
observedContainer.deleteObserver(this);
}
super.delete();
}
public SimplifiedCardinalDirection getOrientation() {
return layoutedAs;
}
private void updateLayout() {
if (getContainerGraphicalRepresentation() != null && getContainerGraphicalRepresentation() instanceof PortmapRegisteryGR) {
if (observedContainer != getContainerGraphicalRepresentation()) {
if (observedContainer != null) {
observedContainer.deleteObserver(this);
}
observedContainer = (PortmapRegisteryGR) getContainerGraphicalRepresentation();
if (observedContainer != null) {
observedContainer.addObserver(this);
}
}
SimplifiedCardinalDirection orientation = observedContainer.getOrientation();
if (orientation != layoutedAs) {
layoutAs(orientation);
}
} else {
logger.warning("Unexpected container: " + getContainerGraphicalRepresentation());
}
}
protected int getPortmapIndex() {
if (observedContainer == null) {
return 0;
}
Vector<FlexoPortMap> visiblePortmaps = new Vector<FlexoPortMap>();
for (FlexoPortMap pm : observedContainer.getPortMapRegistery().getPortMaps()) {
if (pm.getIsVisible()) {
visiblePortmaps.add(pm);
}
}
return visiblePortmaps.indexOf(getPortMap());
}
private void layoutAs(SimplifiedCardinalDirection orientation) {
if (observedContainer == null) {
return;
}
if (isLayingout) {
return;
}
isLayingout = true;
try {
int index = getPortmapIndex();
setLocationConstraints(LocationConstraints.AREA_CONSTRAINED);
if (orientation == SimplifiedCardinalDirection.NORTH) {
setX(PortmapRegisteryGR.PORTMAP_MARGIN + index * PORTMAP_SIZE);
setY(0);
setBorder(new ShapeGraphicalRepresentation.ShapeBorder(2, 18, 3, 3));
setLocationConstrainedArea(FGELine.makeHorizontalLine(new FGEPoint(0.5, 0.5)));
} else if (orientation == SimplifiedCardinalDirection.SOUTH) {
setX(PortmapRegisteryGR.PORTMAP_MARGIN + index * PORTMAP_SIZE);
setY(observedContainer.getHeight() - PortmapRegisteryGR.PORTMAP_REGISTERY_WIDTH);
setBorder(new ShapeGraphicalRepresentation.ShapeBorder(18, 2, 3, 3));
setLocationConstrainedArea(FGELine.makeHorizontalLine(new FGEPoint(0.5, 0.5)));
} else if (orientation == SimplifiedCardinalDirection.WEST) {
setX(0);
setY(PortmapRegisteryGR.PORTMAP_MARGIN + index * PORTMAP_SIZE);
setBorder(new ShapeGraphicalRepresentation.ShapeBorder(3, 3, 2, 18));
setLocationConstrainedArea(FGELine.makeVerticalLine(new FGEPoint(0.5, 0.5)));
} else if (orientation == SimplifiedCardinalDirection.EAST) {
setX(observedContainer.getWidth() - PortmapRegisteryGR.PORTMAP_REGISTERY_WIDTH);
setY(PortmapRegisteryGR.PORTMAP_MARGIN + index * PORTMAP_SIZE);
setBorder(new ShapeGraphicalRepresentation.ShapeBorder(3, 3, 18, 2));
setLocationConstrainedArea(FGELine.makeVerticalLine(new FGEPoint(0.5, 0.5)));
}
// System.out.println("layout as "+orientation+" index="+index);
layoutedAs = orientation;
} finally {
isLayingout = false;
}
}
@Override
public void notifyObjectHierarchyHasBeenUpdated() {
updateLayout();
super.notifyObjectHierarchyHasBeenUpdated();
}
protected ImageIcon getImageIcon() {
if (layoutedAs == SimplifiedCardinalDirection.NORTH) {
return WKFIconLibrary.getImageIconForPortmap(getPortMap(), PortMapRegistery.NORTH);
}
if (layoutedAs == SimplifiedCardinalDirection.SOUTH) {
return WKFIconLibrary.getImageIconForPortmap(getPortMap(), PortMapRegistery.SOUTH);
}
if (layoutedAs == SimplifiedCardinalDirection.EAST) {
return WKFIconLibrary.getImageIconForPortmap(getPortMap(), PortMapRegistery.EAST);
}
if (layoutedAs == SimplifiedCardinalDirection.WEST) {
return WKFIconLibrary.getImageIconForPortmap(getPortMap(), PortMapRegistery.WEST);
}
return WKFIconLibrary.getImageIconForPortmap(getPortMap());
}
private class PortmapGRShapePainter implements ShapePainter {
@Override
public void paintShape(FGEShapeGraphics g) {
if (layoutedAs == null) {
return;
}
if (getImageIcon() != null) {
if (layoutedAs == SimplifiedCardinalDirection.NORTH) {
g.drawImage(getImageIcon().getImage(), new FGEPoint(-0.4, 1));
} else if (layoutedAs == SimplifiedCardinalDirection.SOUTH) {
g.drawImage(getImageIcon().getImage(), new FGEPoint(-0.4, -1.8));
} else if (layoutedAs == SimplifiedCardinalDirection.WEST) {
g.drawImage(getImageIcon().getImage(), new FGEPoint(1, -0.4));
} else if (layoutedAs == SimplifiedCardinalDirection.EAST) {
g.drawImage(getImageIcon().getImage(), new FGEPoint(-1.8, -0.4));
}
}
};
}
@Override
public void notifyObjectWillMove() {
super.notifyObjectWillMove();
}
@Override
public void notifyObjectHasMoved() {
if (isLayingout) {
return;
}
super.notifyObjectHasMoved();
FlexoPortMap afterPortmap = null;
if (observedContainer != null) {
for (GraphicalRepresentation<?> gr : observedContainer.getContainedGraphicalRepresentations()) {
if (gr instanceof PortmapGR && gr != this && gr.getIsVisible()) {
PortmapGR portmapGR = (PortmapGR) gr;
if (getOrientation().isVertical()) {
if (portmapGR.getX() < getX()) {
afterPortmap = portmapGR.getPortMap();
}
}
if (getOrientation().isHorizontal()) {
if (portmapGR.getY() < getY()) {
afterPortmap = portmapGR.getPortMap();
}
}
}
}
observedContainer.getPortMapRegistery().reorderPortmaps(getPortMap(), afterPortmap);
for (GraphicalRepresentation gr : observedContainer.getContainedGraphicalRepresentations()) {
if (gr instanceof PortmapGR) {
((PortmapGR) gr).layoutAs(getOrientation());
}
}
}
}
@Override
public void update(FlexoObservable observable, DataModification dataModification) {
// logger.info(">>>>>>>>>>> Notified "+dataModification+" for "+observable);
if (observable == getModel()) {
if (dataModification instanceof ObjectVisibilityChanged) {
getDrawing().invalidateGraphicalObjectsHierarchy(getPortMap().getPortMapRegistery());
getDrawing().updateGraphicalObjectsHierarchy();
}
}
super.update(observable, dataModification);
}
}