/*
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
.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package dynamicmvc;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.Set;
import javax.swing.JPanel;
/**
*
* @author Brandon
*/
public class GraphPanel extends JPanel {
protected static HashMap> combinations = new HashMap>();
PrimitivePointer g;
PrimitivePointer v;
private PrimitiveList getVertexList() {
return (PrimitiveList)((PrimitiveGraph)g.dereference()).getVertices().dereference();
}
private PrimitiveList getEdgeList() {
return (PrimitiveList)((PrimitiveGraph)g.dereference()).getEdges().dereference();
}
public GraphPanel(PrimitivePointer g) {
super();
this.g = g;
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(java.awt.Color.BLACK);
g.fillRect(10, 10, this.getWidth() - 15, this.getHeight() - 15);
for(PrimitivePointer p : getEdgeList().getList()) {
PrimitiveEdge e = (PrimitiveEdge)p.dereference();
e.draw(g);
}
setVertexColors();
PrimitiveVertex myV = null;
if (this.v != null) {
myV = (PrimitiveVertex)this.v.dereference();
}
for(PrimitivePointer p : getVertexList().getList()) {
PrimitiveVertex v = (PrimitiveVertex)p.dereference();
v.draw(g, myV);
}
}
private void setVertexColors() {
// first, determine all combination of properties and values for the vertices
//HashMap> combinations = getVertexPropertyValues();
combinations = getVertexPropertyValues();
for(PrimitivePointer p : getVertexList().getList()) {
PrimitiveVertex v = (PrimitiveVertex)p.dereference();
v.setC(getColor(0));
}
setVertexColors(convert(combinations.keySet()), combinations, new HashMap(), 0, new PrimitiveInteger(0));
}
private void setVertexColors(ArrayList optionNames, HashMap> combinations, HashMap thisCombination, int thisOption, PrimitiveInteger discoveredCombinations) {
// make sure to only change colors when necessary
if (optionNames.size() == 0) {
return;
}
if (thisOption == optionNames.size()) {
// color all of these vertices
colorVertices(thisCombination, getColor(discoveredCombinations.getValue() + 1));
PrimitiveInteger newValue = (PrimitiveInteger)discoveredCombinations.add(PrimitiveInteger.getConstant(1)).dereference();
discoveredCombinations.setValue(newValue.getValue());
return;
}
String thisOptionName = optionNames.get(thisOption);
ArrayList theseOptions = combinations.get(thisOptionName);
for(Primitive option : theseOptions) {
thisCombination.put(thisOptionName, option);
this.setVertexColors(optionNames, combinations, thisCombination, thisOption+1, discoveredCombinations);
thisCombination.remove(thisOptionName);
}
}
private void colorVertices(HashMap combination, Color c) {
// test each vertex to see if the defined properties of the vertex
// match the properties for this combination
for(PrimitivePointer p : getVertexList().getList()) {
PrimitiveVertex v = (PrimitiveVertex)p.dereference();
if(v.hasDefinedPrimitives(combination)) {
v.setC(c);
}
}
}
private ArrayList getGraphDisplayPropertyNames() {
ArrayList displayPropertyNames = new ArrayList();
try {
if(this.g.dereference().getDefinedProperties().containsKey("displayProperties")) {
PrimitivePointer l = g.dereference().get("displayProperties");
PrimitiveList displayProperties = (PrimitiveList)l.dereference();
if (displayProperties.getList().size() == 0) {
return null;
}
for(PrimitivePointer p : displayProperties.getList()) {
if(p.dereference() instanceof PrimitiveString) {
PrimitiveString s = (PrimitiveString)p.dereference();
String displayPropertyName = s.getValue();
displayPropertyNames.add(displayPropertyName);
}
}
} else {
return null;
}
} catch (DynamicMVCException ex) {
ex.printStackTrace();
return null;
}
return displayPropertyNames;
}
private HashMap> getVertexDisplayCombinations(ArrayList propertyNames) {
//
// for each vertex
for(PrimitivePointer p : getVertexList().getList()) {
PrimitiveVertex v = (PrimitiveVertex)p.dereference();
// check each defined property of the vertex
for(String propertyName : propertyNames) {
if(v.getDefinedProperties().containsKey(propertyName)) {
PrimitivePointer option = v.getDefinedProperties().get(propertyName);
addOption(combinations, propertyName, option);
}
}
}
return combinations;
}
private HashMap> getVertexPropertyValues() {
ArrayList graphDisplayPropertyNames = getGraphDisplayPropertyNames();
if (graphDisplayPropertyNames != null) {
return getVertexDisplayCombinations(graphDisplayPropertyNames);
}
//HashMap> combinations = new HashMap>();
// for each vertex
for(PrimitivePointer p : getVertexList().getList()) {
PrimitiveVertex v = (PrimitiveVertex)p.dereference();
// check each defined property of the vertex
for(String name : v.getDefinedProperties().keySet()) {
PrimitivePointer option = v.getDefinedProperties().get(name);
addOption(combinations, name, option);
}
}
return combinations;
}
private static ArrayList convert(Set set) {
ArrayList list = new ArrayList();
for(String s : set) {
list.add(s);
}
return list;
}
private static void addOption(HashMap> combinations, String name, PrimitivePointer option) {
if (name.startsWith("__")) {
return;
}
if (combinations.containsKey(name)) {
ArrayList options = combinations.get(name);
if (!options.contains(option)) {
options.add(option.dereference());
}
} else {
ArrayList options = new ArrayList();
options.add(option.dereference());
combinations.put(name, options);
}
}
private static ArrayList colors;
private static Random random;
private static Color getColor(int index) {
if (colors == null) {
colors = new ArrayList();
// because the seed needs to be the same each time
random = new Random(Long.valueOf("55491800284268"));
}
if (colors.size() > index) {
return colors.get(index);
} else {
getColors(index);
return colors.get(index);
}
}
private static ArrayList getColors(int count) {
if (colors.size() > count) {
return colors;
}
// generate enough random colors
while(colors.size() <= count) {
Color c = new java.awt.Color(random.nextFloat(), random.nextFloat(), random.nextFloat());
colors.add(c);
}
return colors;
}
}