/* 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; } }