/*
PseudoCode Interpreted Language (PCIL): Part of the algoviz@vt collection of algorithm visualizations.
Copyright (C) 2008 Brandon Malone, Frank Hadlock
This file is part of the PseudoCode Interpreted Language.
PseudoCode Interpreted Language 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.
PseudoCode Interpreted Language 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
PseudoCode Interpreted Language. If not, see
.
*/
/*
* PrimitiveGraph.java
*
* Created on March 6, 2008, 7:18 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package dynamicmvc;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
/**
*
* @author Brandon
*/
public class PrimitiveGraph extends Primitive {
public static String pseudocodeTypeName() {
return "Graph";
}
public String getType() {
return pseudocodeTypeName();
}
public boolean isResizable() {
return true;
}
//
private String name;
private PrimitivePointer vertices;
private PrimitivePointer edges;
//
//
public Primitive copy() throws DynamicMVCException {
PrimitiveGraph i = new PrimitiveGraph(getName(), getVertices(), getEdges());
return i;
}
public Primitive deepCopy(HashMap alreadyCopiedAddresses) throws DynamicMVCException {
PrimitivePointer p = getPointer();
if (alreadyCopiedAddresses.containsKey(Integer.valueOf(p.getAddress()))) {
return PrimitiveFactory.getFromMemory(alreadyCopiedAddresses.get(p.getAddress()));
}
PrimitivePointer pp = null;
if (this instanceof PrimitiveDirectedGraph) {
pp = PrimitiveFactory.create(PrimitiveDirectedGraph.pseudocodeTypeName(), name);
} else {
pp = PrimitiveFactory.create(PrimitiveGraph.pseudocodeTypeName(), name);
}
alreadyCopiedAddresses.put(p.getAddress(), pp.getAddress());
PrimitiveGraph i = (PrimitiveGraph)pp.dereference();
i.setName(name);
i.setVertices(vertices.deepCopy(alreadyCopiedAddresses));
i.setEdges(edges.deepCopy(alreadyCopiedAddresses));
super.deepCopyDefinedProperties(i, alreadyCopiedAddresses);
return i;
}
public boolean deepEquals(Primitive p) throws DynamicMVCException {
if (!(p instanceof PrimitiveGraph)) {
DynamicController.errorMessage = "Expecting Graph, but found " + p.getType();
return false;
}
// GRAPH DEEP EQUALS IS NOT REALLY IMPLEMENTED
return true;
/*
PrimitiveGraph g = (PrimitiveGraph)p;
if(!vertices.deepEquals(g.getVertices())) {
return false;
}
if (!edges.deepEquals(g.getEdges())) {
return false;
}
return super.deepEqualsDefinedProperties(p);
*/
}
public void set(Primitive other) throws DynamicMVCException {
// if other is an integer, copy its values
if (other instanceof PrimitiveGraph) {
PrimitiveGraph o = (PrimitiveGraph)other;
//setName(o.getName());
setName(o.getName());
setVertices(o.getVertices());
setEdges(o.getEdges());
} else {
// otherwise, throw an DynamicMVCException
throw new DynamicMVCException("Invalid assignment.");
}
}
/** Creates a new instance of PrimitiveGraph */
public PrimitiveGraph(String name) {
super();
setName(name);
}
public PrimitiveGraph(String name, PrimitivePointer vertices, PrimitivePointer edges) throws DynamicMVCException {
setName(name);
setVertices(vertices);
setEdges(edges);
// update the names in the vertex and edge lists
int i = 0;
for(PrimitivePointer v : ((PrimitiveList)vertices.dereference()).getList()) {
((PrimitiveList)this.vertices.dereference()).get(i).dereference().setName(v.dereference().getName());
i++;
}
i = 0;
for(PrimitivePointer v : ((PrimitiveList)edges.dereference()).getList()) {
((PrimitiveList)this.edges.dereference()).get(i).dereference().setName(v.dereference().getName());
i++;
}
}
public PrimitiveGraph() {
super();
setName("");
PrimitivePointer vertices = PrimitiveFactory.create("List", "vertices");
PrimitivePointer edges = PrimitiveFactory.create("List", "edges");
PrimitivePointer displayProperties = PrimitiveFactory.create("List", "displayProperties");
this.set("vertices", vertices);
this.set("edges", edges);
this.set("displayProperties", displayProperties);
this.vertices = vertices;
this.edges = edges;
}
//
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PrimitivePointer getVertices() {
return vertices;
}
public void setVertices(PrimitivePointer vertices) {
this.vertices = vertices;
}
public PrimitivePointer getEdges() {
return edges;
}
public void setEdges(PrimitivePointer edges) {
this.edges = edges;
}
//
//
public void populateFromEditComponentWrapper(JComponent editComponentWrapper) {
// no work to be done, since the GraphInput panel already updates this reference
}
public String getEditComponentWrapperName() {
return "pnl" + getName();
}
public String getEditComponentName() {
return "txt" + getName();
}
public JComponent getEditComponent() {
// wrap everything in a panel
JPanel wrapper = new JPanel();
wrapper.setName(getEditComponentWrapperName());
try {
int width = 300;
int height = 300;
if(this.getDefinedProperties().containsKey("__width")) {
PrimitivePointer pWidth = get("__width");
PrimitiveInteger w = (PrimitiveInteger)pWidth.dereference();
width = w.getValue();
}
if(this.getDefinedProperties().containsKey("__height")) {
PrimitivePointer pHeight = get("__height");
PrimitiveInteger h = (PrimitiveInteger)pHeight.dereference();
height = h.getValue();
}
JPanel graph = new GraphInput(PrimitiveFactory.getPointer(this), width, height, false);
wrapper.add(graph);
wrapper.setPreferredSize(graph.getPreferredSize());
} catch (DynamicMVCException ex) {
ex.printStackTrace();
}
return wrapper;
}
public JComponent getReadOnlyComponent() {
// wrap everything in a panel
JPanel wrapper = new JPanel();
try {
int width = 300;
int height = 300;
if(this.getDefinedProperties().containsKey("__width")) {
PrimitivePointer pWidth = get("__width");
PrimitiveInteger w = (PrimitiveInteger)pWidth.dereference();
width = w.getValue();
}
if(this.getDefinedProperties().containsKey("__height")) {
PrimitivePointer pHeight = get("__height");
PrimitiveInteger h = (PrimitiveInteger)pHeight.dereference();
height = h.getValue();
}
JPanel graph = new GraphInput(PrimitiveFactory.getPointer(this), width, height, true);
wrapper.add(graph);
wrapper.setPreferredSize(graph.getPreferredSize());
} catch (DynamicMVCException ex) {
ex.printStackTrace();
}
return wrapper;
}
//
public PrimitivePointer getVertex(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 1) {
PrimitiveString vertexName = (PrimitiveString)arguments.get(0).dereference();
return getVertex(vertexName);
}
throw new DynamicMVCException("Invalid number of arguments.");
}
public PrimitivePointer getVertex(String name) {
for(PrimitivePointer p : ((PrimitiveList)vertices.dereference()).getList()) {
PrimitiveVertex v = (PrimitiveVertex)p.dereference();
if (v.getName().equalsIgnoreCase(name)) {
return p;
}
}
return null;
}
public PrimitivePointer getVertex(PrimitiveString name) {
return getVertex(name.getValue());
}
public void addVertex(PrimitivePointer name, PrimitivePointer x, PrimitivePointer y) throws DynamicMVCException {
String n = ((PrimitiveString)name.dereference()).getValue();
PrimitivePointer v = PrimitiveFactory.create(PrimitiveVertex.pseudocodeTypeName(), n);
PrimitivePointer value = PrimitiveFactory.create(PrimitiveString.pseudocodeTypeName(), "value");
PrimitivePointer originalName = PrimitiveFactory.create(PrimitiveString.pseudocodeTypeName(), "originalName");
((PrimitiveString)value.dereference()).setValue(n);
((PrimitiveString)originalName.dereference()).setValue(n);
((PrimitiveVertex)v.dereference()).setX(x);
((PrimitiveVertex)v.dereference()).setY(y);
((PrimitiveVertex)v.dereference()).setValue(value);
addVertex(v);
}
public void addVertex(PrimitivePointer v) {
String name = ((PrimitiveVertex)v.dereference()).getName();
((PrimitiveList)vertices.dereference()).add(v);
// don't loose the name
v.setName(name);
//v.dereference().setName(name);
//v.dereference().setParent(this);
}
public PrimitivePointer deleteVertex(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 1) {
PrimitivePointer v = arguments.get(0);
return deleteVertex(v);
}
throw new DynamicMVCException("Invalid number of arguments.");
}
public PrimitivePointer deleteVertex(PrimitivePointer v) throws DynamicMVCException {
// delete this from the vertex list
((PrimitiveList)vertices.dereference()).remove(v);
PrimitiveVertex vertex = (PrimitiveVertex)v.dereference();
// delete any connected edges
PrimitiveList edgeList = ((PrimitiveList)this.edges.dereference());
ArrayList edges = edgeList.getList();
for(int i = 0; i < edges.size(); i++) {
PrimitivePointer e = edges.get(i);
PrimitiveEdge edge = (PrimitiveEdge)e.dereference();
PrimitiveBoolean hasEndPoint = (PrimitiveBoolean)(edge.hasEndPoint(v).dereference());
if (hasEndPoint.getValue()) {
// find the other neighbor and delete the edge
PrimitivePointer pov = edge.findOtherVertex(vertex);
PrimitiveVertex otherV = (PrimitiveVertex)pov.dereference();
((PrimitiveList)otherV.getEdges().dereference()).remove(e);
edges.remove(i);
i--;
}
}
return PrimitiveFactory.create(PrimitiveNull.pseudocodeTypeName(), "null");
}
public Object execute(String methodName, ArrayList arguments) throws DynamicMVCException {
// is this a method of mine?
if (methodName.equalsIgnoreCase("equals")) {
return equals(arguments);
} else if (methodName.equalsIgnoreCase("notEqual")) {
return !equals(arguments);
} else if (methodName.equalsIgnoreCase("assign")) {
assign(arguments);
return null;
} else if (methodName.equalsIgnoreCase("addVertex")) {
addVertex(arguments);
return null;
} else if (methodName.equalsIgnoreCase("addEdge")) {
addEdge(arguments);
return null;
} else if (methodName.equalsIgnoreCase("getVertex")) {
return getVertex(arguments);
} else if (methodName.equalsIgnoreCase("d")) {
return d(arguments);
} else if (methodName.equalsIgnoreCase("deleteVertex")) {
return deleteVertex(arguments);
} else {
throw new DynamicMVCException("Invalid method name:'" + methodName + "' on object '" + getName() + "'.");
}
}
public int compareTo(Object o) throws DynamicMVCException {
if (o instanceof PrimitiveGraph) {
PrimitiveGraph i = (PrimitiveGraph)o;
return compareTo(i);
}
throw new DynamicMVCException("Invalid comparison");
}
public int compareTo(Primitive p) throws DynamicMVCException {
return compareTo(p);
}
public boolean equals(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 1) {
PrimitiveGraph i = (PrimitiveGraph)arguments.get(0).dereference();
return equals(i);
}
throw new DynamicMVCException("Wrong number of arguments.");
}
public boolean equals(PrimitiveGraph i) {
return (compareTo(i) == 0);
}
public int compareTo(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 1) {
PrimitiveGraph i = (PrimitiveGraph)arguments.get(0).dereference();
return compareTo(i);
}
throw new DynamicMVCException("Wrong number of arguments.");
}
public int compareTo(PrimitiveGraph i) {
String otherName = i.getName();
return name.compareTo(otherName);
}
public void assign(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 1) {
PrimitiveGraph i = (PrimitiveGraph)arguments.get(0).dereference();
assign(i);
}
throw new DynamicMVCException("Wrong number of arguments.");
}
public void assign(PrimitiveGraph i) {
String otherName = i.getName();
PrimitivePointer vertices = i.getVertices();
PrimitivePointer edges = i.getEdges();
setName(otherName);
setVertices(vertices);
setEdges(edges);
}
public void addVertex(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 3) {
// in reverse order because stack
PrimitivePointer name = arguments.get(2);
PrimitivePointer x = arguments.get(1);
PrimitivePointer y = arguments.get(0);
addVertex(name, x, y);
return;
} else if (arguments.size() == 1) {
PrimitivePointer v = arguments.get(0);
addVertex(v);
return;
}
throw new DynamicMVCException("Wrong number of arguments.");
}
public void addEdge(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 2) {
// in reverse order
PrimitiveString secondName = (PrimitiveString)arguments.get(1).dereference();
PrimitiveString firstName = (PrimitiveString)arguments.get(0).dereference();
addEdge(firstName, secondName);
return;
}
throw new DynamicMVCException("Wrong number of arguments.");
}
public void addEdge(PrimitiveString firstName, PrimitiveString secondName) {
PrimitivePointer first = getVertex(firstName);
PrimitivePointer second = getVertex(secondName);
addEdge(first, second);
}
public void addEdge(PrimitivePointer first, PrimitivePointer second) {
PrimitivePointer distance = ((PrimitiveVertex)first.dereference()).distance(second);
addEdge(first, second, distance);
}
public void addEdge(PrimitivePointer first, PrimitivePointer second, PrimitivePointer distance) {
PrimitivePointer eP = PrimitiveFactory.create("Edge", "");
PrimitiveEdge e = (PrimitiveEdge)eP.dereference();
e.setFirst(first);
e.setSecond(second);
e.setWeight(distance);
try {
e.setG(this.getPointer());
} catch (DynamicMVCException ex) {
ex.printStackTrace();
}
//e.setParent(this);
((PrimitiveList)edges.dereference()).add(eP);
((PrimitiveVertex)first.dereference()).addEdge(eP);
if(!(this instanceof PrimitiveDirectedGraph)) {
((PrimitiveVertex)second.dereference()).addEdge(eP);
}
}
public String toString() {
return getName();
}
public PrimitivePointer d(ArrayList arguments) throws DynamicMVCException {
if (arguments.size() == 2) {
PrimitivePointer v1 = arguments.get(0);
PrimitivePointer v2 = arguments.get(1);
return d(v1, v2);
} else {
throw new DynamicMVCException("Wrong number of arguments.");
}
}
public PrimitivePointer d(PrimitivePointer v1, PrimitivePointer v2) {
// find an edge from v1 to v2
for(PrimitivePointer p : ((PrimitiveList)edges.dereference()).getList()) {
PrimitiveEdge e = (PrimitiveEdge)p.dereference();
if (((PrimitiveBoolean)e.hasEndPoints(v1, v2).dereference()).getValue()) {
return e.getWeight();
}
}
return null;
}
}