|
| 1 | +import javafx.scene.Node; |
| 2 | +import javafx.scene.layout.HBox; |
1 | 3 | import java.util.LinkedList; |
2 | 4 |
|
3 | | -public abstract class AbstractCompoundExpression implements CompoundExpression{ |
| 5 | +/** |
| 6 | + * Child function of CompoundExpression. Meant to abstract a lot of the code in |
| 7 | + * Multiplicative and Additive Expression classes |
| 8 | + */ |
| 9 | +public abstract class AbstractCompoundExpression implements CompoundExpression, CopyAble { |
4 | 10 | private CompoundExpression parent = null; |
5 | 11 | private LinkedList<Expression> children = new LinkedList<Expression>(); |
| 12 | + protected boolean focused; |
| 13 | + protected Node node; |
6 | 14 |
|
7 | 15 | /** |
8 | 16 | * Flatten's the expression's children. |
@@ -51,38 +59,188 @@ public void setChildren(LinkedList<Expression> children){ |
51 | 59 | * @param child An expression |
52 | 60 | */ |
53 | 61 | public void addSubexpression(Expression child){ |
| 62 | + child.setParent(this); |
| 63 | + |
54 | 64 | this.children.add(child); |
55 | 65 | } |
56 | 66 |
|
57 | 67 | /** |
58 | | - * Will generate a String representation for the the addition |
| 68 | + * Will generate a String representation for the current |
59 | 69 | * operator, with the appropiate number of tabs to properly |
60 | 70 | * represent it's position in the expression. |
61 | 71 | * @param indentLevel the indentation level |
62 | | - * @param name the name of the expression |
| 72 | + * @param name what the current operator is |
63 | 73 | * @return a String containing this expression and all its children in hierarchic format. |
64 | 74 | */ |
65 | 75 |
|
66 | | - public String convertToString(int indentLevel, String name){ |
| 76 | + public String convertToString(int indentLevel, String name) { |
67 | 77 | StringBuffer sb = new StringBuffer(); |
68 | 78 | Expression.indent(sb,indentLevel); |
69 | 79 | sb.append(name + "\n"); |
| 80 | + |
70 | 81 | for(Expression e: this.getChildren()){ |
71 | 82 | sb.append(e.convertToString(indentLevel+1)); |
72 | 83 | } |
| 84 | + |
73 | 85 | return sb.toString(); |
74 | 86 | } |
75 | 87 |
|
| 88 | + /** |
| 89 | + * Will generate a String representation for the operator, with no |
| 90 | + * space though. |
| 91 | + * @param delimiter the operator |
| 92 | + * @return a String containing this expresison. |
| 93 | + */ |
| 94 | + public String convertToStringFlat(String delimiter) { |
| 95 | + String outputString = ""; |
| 96 | + |
| 97 | + for(int i = 0; i < this.getChildren().size() - 1; i++) { |
| 98 | + outputString += ((CopyAble) this.getChildren().get(i)).convertToStringFlat(); |
| 99 | + outputString += delimiter; |
| 100 | + } |
| 101 | + |
| 102 | + outputString += ((CopyAble) this.getChildren().get(this.getChildren().size() - 1)).convertToStringFlat(); |
| 103 | + |
| 104 | + return outputString; |
| 105 | + } |
| 106 | + |
76 | 107 | /** |
77 | 108 | * Creates a deep copy of the expression |
78 | 109 | * @param copy, an empty Compound expression that will be returned. |
79 | 110 | * @return a deep copy of the expression |
80 | 111 | */ |
81 | 112 | public AbstractCompoundExpression deepCopy(AbstractCompoundExpression copy){ |
82 | | - for(Expression c: this.getChildren()){ |
83 | | - copy.addSubexpression(c.deepCopy()); |
| 113 | + for(Expression c: this.getChildren()) { |
| 114 | + copy.addSubexpression(c); |
| 115 | + } |
| 116 | + for(Expression c: copy.getChildren()) { |
| 117 | + c.setParent(copy); |
84 | 118 | } |
| 119 | + |
| 120 | + copy.node = node; |
85 | 121 | return copy; |
86 | 122 | } |
87 | 123 |
|
| 124 | + /** |
| 125 | + * Abstracted function for getNode() for Multiplicative and Additive Expressions |
| 126 | + * @param delimiter the operator |
| 127 | + * @return a Node represeneting the current Expression |
| 128 | + */ |
| 129 | + public Node getNode(String delimiter) { |
| 130 | + if(node == null) { |
| 131 | + final HBox hbox = new HBox(); |
| 132 | + hbox.getChildren().add(this.getChildren().get(0).getNode()); |
| 133 | + for (int i = 1; i < this.getChildren().size(); i++) { |
| 134 | + hbox.getChildren().add(ExpressionEditor.newLabel(delimiter)); |
| 135 | + hbox.getChildren().add(this.getChildren().get(i).getNode()); |
| 136 | + } |
| 137 | + if (this.getFocused()) { |
| 138 | + hbox.setBorder(RED_BORDER); |
| 139 | + } |
| 140 | + node = hbox; |
| 141 | + return hbox; |
| 142 | + } |
| 143 | + |
| 144 | + return node; |
| 145 | + } |
| 146 | + |
| 147 | + /** |
| 148 | + * Getter for if the current expression is focused. |
| 149 | + * @return true if the expression is focused, false |
| 150 | + * otherwise |
| 151 | + */ |
| 152 | + public boolean getFocused() { |
| 153 | + return focused; |
| 154 | + } |
| 155 | + |
| 156 | + /** |
| 157 | + * Setter for if the current expression is focused. |
| 158 | + * @param s A boolean representing if the current |
| 159 | + * expression is focused or not |
| 160 | + */ |
| 161 | + public void setFocused(boolean s) { |
| 162 | + focused = s; |
| 163 | + } |
| 164 | + |
| 165 | + /** |
| 166 | + * Will create a copy of the current expression, and transfer |
| 167 | + * the Node pointers as well |
| 168 | + * @return a copy of Expression with old Node pointers |
| 169 | + */ |
| 170 | + @Override |
| 171 | + public Expression trueCopy() { |
| 172 | + if(this.getParent() == null) { |
| 173 | + return this.deepCopy(); |
| 174 | + } |
| 175 | + |
| 176 | + AbstractCompoundExpression parent = ((AbstractCompoundExpression) this.getParent()); |
| 177 | + AbstractCompoundExpression copy = (AbstractCompoundExpression) parent.trueCopy(); |
| 178 | + |
| 179 | + for(Expression e:copy.getChildren()) { |
| 180 | + if(e.convertToString(0).equals(this.convertToString(0))) { |
| 181 | + return e; |
| 182 | + } |
| 183 | + } |
| 184 | + |
| 185 | + return null; |
| 186 | + } |
| 187 | + |
| 188 | + /** |
| 189 | + * Will generate all possible trees that an expression can take |
| 190 | + * @param parent Parent of the focused expression |
| 191 | + * @param selected the focused expression, represented by the .convertToString(0) method |
| 192 | + * @return a LinkedList of Expressions of all of the permutations of the Expression |
| 193 | + */ |
| 194 | + public static LinkedList<Expression> generateAllPossibleTrees(Expression parent, String selected) { |
| 195 | + Expression focused = null; |
| 196 | + |
| 197 | + for(Expression child : ((AbstractCompoundExpression) parent).getChildren()) { |
| 198 | + if (child.convertToString(0).equals(selected)) { |
| 199 | + focused = child; |
| 200 | + break; |
| 201 | + } |
| 202 | + } |
| 203 | + |
| 204 | + final LinkedList<Expression> children = ((AbstractCompoundExpression) parent).getChildren(); |
| 205 | + final int childrenSize = children.size(); |
| 206 | + |
| 207 | + int nodeIndex = -1; |
| 208 | + |
| 209 | + for(int i = 0; i < childrenSize; i++) { |
| 210 | + if (children.get(i) == focused) { |
| 211 | + nodeIndex = i; |
| 212 | + break; |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + if (nodeIndex == -1) { |
| 217 | + return new LinkedList<>(); |
| 218 | + } |
| 219 | + |
| 220 | + children.remove(nodeIndex); |
| 221 | + |
| 222 | + LinkedList<Expression> possibleTrees = new LinkedList<>(); |
| 223 | + |
| 224 | + for (int i = 0; i < childrenSize; i++) { |
| 225 | + AbstractCompoundExpression tempParent = (AbstractCompoundExpression) ((AbstractCompoundExpression) parent).trueCopy(); |
| 226 | + LinkedList<Expression> orderedChildren = new LinkedList<>(); |
| 227 | + |
| 228 | + for (int j = 0; j < children.size(); j++) { |
| 229 | + if (j == i) { |
| 230 | + orderedChildren.add(focused); |
| 231 | + } |
| 232 | + |
| 233 | + orderedChildren.add(children.get(j)); |
| 234 | + } |
| 235 | + |
| 236 | + if(i == childrenSize - 1) { |
| 237 | + orderedChildren.add(focused); |
| 238 | + } |
| 239 | + |
| 240 | + tempParent.setChildren(orderedChildren); |
| 241 | + possibleTrees.add(tempParent); |
| 242 | + } |
| 243 | + |
| 244 | + return possibleTrees; |
| 245 | + } |
88 | 246 | } |
0 commit comments