package es.iiia.shapegrammar.model;
import java.util.ArrayList;
import es.iiia.shapegrammar.enums.ShapeGrammarRuleType;
import es.iiia.shapegrammar.grammar.ShapeGrammarParser;
import es.iiia.shapegrammar.rule.RuleCreationFactory;
import es.iiia.shapegrammar.rule.RuleModel;
import es.iiia.shapegrammar.shape.ShapeModel;
public class ShapeGrammarModel extends NodeModel {
public static ShapeGrammarModel ACTIVE_SHAPE_GRAMMAR;
public static String SHAPE_ADDED = "ShapeAdded";
public static String SHAPE_REMOVED = "ShapeRemoved";
public static String RULE_ADDED = "RuleAdded";
public static String RULE_REMOVED = "RuleRemoved";
public static String START_SHAPE_CHANGED = "StartShapeChanged";
public static String RENAMED = "Renamed";
protected ArrayList<ShapeModel> shapes;
protected ArrayList<RuleModel> rules;
private ShapeGrammarParser parser;
private String currentFileName;
private ShapeModel startShape;
private String type;
private int ticket;
public ShapeGrammarModel() {
super();
// clear shapes and rules
this.shapes = new ArrayList<ShapeModel>();
this.rules = new ArrayList<RuleModel>();
// init tickets
this.ticket = 0;
// create initial objects
this.currentFileName = null;
// add first empty child
this.addShape();
this.startShape = this.shapes.get(0);
// Set globally active grammar element
ACTIVE_SHAPE_GRAMMAR = this;
}
public ShapeGrammarModel(String path) {
super();
// Set globally active grammar element
ACTIVE_SHAPE_GRAMMAR = this;
// init shapes and rules
this.shapes = new ArrayList<ShapeModel>();
this.rules = new ArrayList<RuleModel>();
// set current filename
this.currentFileName = path;
// init tickets
this.ticket = 0;
// use parser to load objects
this.getParser().loadXml(path);
}
// public methods
public int getTicket() {
return this.ticket++;
}
public void updateTicket(int id) {
if (this.ticket <= id) {
this.ticket = id + 1;
}
}
// used in specific shape grammar implementations
public String getType() {
return null;
}
public void setCurrentFileName(String fileName) {
currentFileName = fileName;
getListeners().firePropertyChange(RENAMED, null, fileName);
}
public String getCurrentFileName() {
return currentFileName;
}
public ArrayList<ShapeModel> getShapes() {
return this.shapes;
}
public ShapeModel getShape(int id) {
for (ShapeModel model : this.shapes) {
if (model.getId() == id)
return model;
}
return null;
}
public ShapeModel getShape(String name) {
for (ShapeModel model : this.shapes) {
if (model.getName().equals(name))
return model;
}
return null;
}
public ArrayList<RuleModel> getRules() {
return this.rules;
}
public RuleModel getRule(int id) {
for (RuleModel model : this.rules) {
if (model.getId() == id)
return model;
}
return null;
}
public RuleModel getRuleForShape(ShapeModel shape) {
for (RuleModel rule : this.rules) {
if (rule.getLeftShape() != null
&& rule.getLeftShape().getId() == shape.getId()) {
return rule;
}
}
return null;
}
public ArrayList<RuleModel> getRulesForShape(int shapeId) {
ArrayList<RuleModel> rules = new ArrayList<RuleModel>();
for (RuleModel rule : this.rules) {
if (rule.getLeftShape() != null
&& rule.getLeftShape().getId() == shapeId) {
rules.add(rule);
}
}
return rules;
}
// modification methods
public ShapeModel addShape() {
// create shape
ShapeModel model = this.initShape();
// add to XMLand retreive current ID
//model.setId(this.getShapeMaxId());
model.setId(this.getTicket());
// add to list of shapes
this.shapes.add(model);
// set parent
model.setParent(this);
// fire listener
getListeners().firePropertyChange(SHAPE_ADDED, null, model);
return model;
}
public void deleteShape(ShapeModel shape) {
// delete from list
this.getShapes().remove(shape);
// delete from XML
this.getParser().removeShape(shape);
// delete all rules that hold this shape
for (RuleModel rule : this.rules) {
if (rule.getLeftShape().getId() == shape.getId()
|| rule.getRightShape().getId() == shape.getId()) {
this.deleteRule(rule);
getListeners().firePropertyChange(RULE_REMOVED, rule, null);
}
}
// fire listener
getListeners().firePropertyChange(SHAPE_REMOVED, shape, null);
}
public ShapeModel getStartShape() {
return this.startShape;
}
public void setStartShape(ShapeModel startShape) {
if (this.startShape == startShape)
return;
ShapeModel oldStartShape = this.startShape;
this.startShape = startShape;
getListeners().firePropertyChange(START_SHAPE_CHANGED, oldStartShape,
this.startShape);
}
public RuleModel addRule(ShapeGrammarRuleType type) {
// create this rule
RuleModel model = this.initRule(type);
if (model != null) {
// add to list of rules
//model.setId(this.getRuleMaxId());
this.rules.add(model);
// fire listener
getListeners().firePropertyChange(RULE_ADDED, null, model);
}
return model;
}
public void deleteRule(RuleModel rule) {
// delete from list
this.getRules().remove(rule);
// delete from XML
this.getParser().removeRule(rule);
// fire listener
getListeners().firePropertyChange(RULE_REMOVED, rule, null);
}
// inform methods
public String getXml() {
return getParser().getXml();
}
public void save() {
this.getParser().saveXml(this.currentFileName);
}
public String saveAs(String path, NodeModel model) {
if (path != null && path != "") {
path = path.endsWith(".xml") ? path : path + ".xml";
// set path
this.setCurrentFileName(path);
// save original document
this.save();
// save either shape
if (model != null) {
if (model instanceof ShapeModel) {
((ShapeGrammarModel) model.getRootModel()).saveShape(path,
(ShapeModel) model);
}
// or save rule
else if (model instanceof RuleModel) {
((ShapeGrammarModel) model.getRootModel()).saveRule(path,
(RuleModel) model);
}
}
}
return this.currentFileName;
}
public void saveShape(String path, ShapeModel shape) {
this.currentFileName = path;
this.saveShape(shape);
}
public void saveShape(ShapeModel shape) {
this.getParser().saveShape(shape);
}
public void saveRule(String path, RuleModel rule) {
this.currentFileName = path;
this.saveRule(rule);
}
public void saveRule(RuleModel rule) {
this.getParser().saveRule(rule);
}
// protected methods
protected ShapeModel initShape() {
return new ShapeModel(this);
}
protected RuleModel initRule(ShapeGrammarRuleType type) {
return RuleCreationFactory.initRuleByType(this, type);
}
protected ShapeGrammarParser getParser() {
if (this.parser == null) {
this.parser = new ShapeGrammarParser(this);
}
return parser;
}
public GeometryModel getObjectById(int id) {
for (ShapeModel shape : this.shapes) {
if (shape.getId() == id) return shape;
}
return null;
}
}