Files
Autopilot-Data-ParserOLD/src/Converters/TreeVariable.java
2025-08-16 12:59:01 -05:00

484 lines
14 KiB
Java

package Converters;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.UUID;
public class TreeVariable extends Variable { //Used for Enumerations and Structures
private TreeVariable trunk;
private ArrayList<Variable> branches;
private UUID uuid = UUID.randomUUID(); //Used for Linking
/* Constructor */
public TreeVariable(String name, Ctype type, TreeVariable trunk) {
super(type, name);
this.branches = new ArrayList<Variable>();
this.trunk = trunk;
}
/* Getters and Setters */
public String getUUIDString( ) {
return uuid.toString();
}
public String getHTMLID( ) {
if (getType() != Ctype.Struct) {
return super.getHTMLID();
} else {
return uuid.toString(); //Not used by the ESP32 getter and setter
}
}
public TreeVariable getTrunk() {
return this.trunk;
}
public void setTrunk(TreeVariable trunk) {
this.trunk = trunk;
}
public ArrayList<Variable> getBranches( ) {
return this.branches;
}
//Overrides the Variable.setArraySize()
public void setArraySize( int arraySize ) {
ArrayList<Variable> array = new ArrayList<Variable>();
setVarNum(); //Change the location of the variable number
for(int i = 0; i < arraySize; i++) {
array.add(this.deepCopy());
}
super.setArray(array);
super.setPlainArraySize(arraySize); //ONLY sets the arraySize, NOTHING with varNums or spans
// if (arraySize > 0) {
// IDPrefix.removeAllScatch(this);
// }
}
/* Class Methods */
public void addBranch(Variable branch) {
this.branches.add(branch);
}
public String generateJSEnumHelper(String prefix) {
return generateJSEnumHelper( null, prefix );
}
public String generateJSEnumHelper( String functionName, String prefix ) {
if (super.getType() != Ctype.Enum) { return ""; } //make sure its an enum
String enumDef = prefix + "const " + this.getDisplayName() + " = Object.freeze({\n";
String funcDef = prefix + "//returns a string\n";
if (functionName == null) {
funcDef = prefix + "function parse_" + this.getName() + "(value, id) {\n";
} else {
funcDef = prefix + "function " + functionName + "(value, id) {\n";
}
// String funcDef = "//returns a string\n"
// + "function parseStatus(statusValue) {\n";
funcDef += prefix + " switch (value) {\n";
for(int i = 0; i < this.branches.size(); i++) { //Iterate over the branches
if (branches.get(i) instanceof EnumItemVariable) {
EnumItemVariable enumItem = (EnumItemVariable) branches.get(i);
enumDef += prefix + "\t\"%s\": %d,\n".formatted(enumItem.getDisplayName(), enumItem.getEnumValue());
funcDef += prefix + "\tcase %s[\"%s\"]:\n".formatted(this.getDisplayName(), enumItem.getDisplayName())
+ prefix + "\t\treturn \"%s\";\n".formatted(enumItem.getDisplayName());
}
}//for
enumDef += prefix + "});\n\n";
funcDef += prefix + "\tdefault:\n"
+ prefix + "\t\treturn \"\";\n"
+ prefix + "\t}\n"
+ prefix + "}\n";
return enumDef + funcDef;
}
/**
* Generates the HTML code that displays the value and each branch as drop down lists.
* @param selected: true if the title should be hidden, or indented again
*/
public String generateHTML( String tabs, boolean selected ) {
if (this.getHTMLType() == null) {
System.out.println("WARNING: generateHTML() for '" + super.getName() + "' Has no set HTML type.");
return "";
} else if (htmlIsHidden()) {
return "";
} else {
String htmlString = "";
if (super.getArraySize() > 0) {
htmlString += tabs + Variable.getIndentation( ) + "<details id=\"" + getUUIDString() + "\"class=\"array-details\">\n"; //Creates details view with a css class
htmlString += tabs + Variable.getIndentation( ) + " <summary class=\"array-summary indented-section\">" + this.getFormatedName() + " (" + this.getArraySize() + ")" + "</summary>\n";
htmlString += tabs + Variable.getIndentation( ) + " <ol>\n"; //Crate Ordered list for each item in the array
ArrayList<Variable> array = getArray();
for(int i = 0; i < array.size(); i++) { //Add in special list open and close ability
htmlString += tabs + Variable.getIndentation( ) + " <div id=\"" + ((TreeVariable)array.get(i)).getUUIDString() + "\" class=\"indented-section\">\n"; //before the list item so the ordered list number is closer to the html code
htmlString += tabs + Variable.getIndentation( ) + " <li>\n"; //Start of the list Item
htmlString += array.get(i).generateHTML(tabs + " ", true);
htmlString += tabs + Variable.getIndentation( ) + " </li>\n"; //End of the list Item
htmlString += tabs + Variable.getIndentation( ) + " </div>\n";
}//for
htmlString += tabs + Variable.getIndentation( ) + " </ol>\n"; //end of ordered list
htmlString += tabs + Variable.getIndentation( ) + "</details>\n";
} else {
if (!selected && super.getType() != Ctype.Enum) {
htmlString = tabs + Variable.getIndentation( ) + "<p class=\"u-form-group u-form-text u-label-left u-text structure-title\">" + this.getFormatedName() + "</p>\n";
}
if (super.getType() != Ctype.Enum && !selected)
htmlString += tabs + Variable.getIndentation( ) + "<div class=\"indented-section\">\n";
htmlString += this.getHTMLType().getVarHTML(this, tabs + ""); //This does not have an array and is plainly displayed
if (super.getType() != Ctype.Enum && !selected)
htmlString += tabs + Variable.getIndentation( ) + "</div>\n";
}
return htmlString;
}
} //generateHTML
public String generateCGetCase( String tabs, VariableDirectoryPath path ) {
return generateCGetCase(tabs, path, -1);
}
public String generateCGetCase( String tabs, VariableDirectoryPath path, int arrayIndex ) {
if (super.getHTMLType() == null) {
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null HTML type.");
return "";
}
if (super.getType() == null) {
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null CType type.");
return "";
}
String caseString = "";
switch(super.getType()) {
case Struct: //NOTE: This does not actually allow the struct to be copied but the components inside of it
if (this.getArraySize() > 0) {
for(int i = 0; i < this.getArraySize(); i++) {
for(int j = 0; j < branches.size(); j++) {
caseString += ((TreeVariable) this.getArray().get(i)).branches.get(j).generateCGetCase(tabs, path.add(this, arrayIndex), i);
}
}//for
} else {
for(int i = 0; i < branches.size(); i++) {
caseString += branches.get(i).generateCGetCase(tabs, path.add(this, arrayIndex));
}
}
break;
case Enum:
caseString += super.generateCGetCase(tabs, path, arrayIndex); //The super class handles enums
break;
default:
break;
}
return caseString;
}
public void resetVarNum() {
switch (super.getType()) {
case Struct:
if (this.getArraySize() > 0) {
for(int i = 0; i < this.getArraySize(); i++) {
for(int j = 0; j < branches.size(); j++) {
((TreeVariable) this.getArray().get(i)).branches.get(j).resetVarNum();
}
}//for
} else {
for(int i = 0; i < branches.size(); i++) {
branches.get(i).resetVarNum();
}
}
break;
case Enum:
if (this.getArraySize() > 0) {
for(int i = 0; i < this.getArraySize(); i++) {
this.getArray().get(i).setVarNum();
}//for
} else {
super.setVarNum();
}
break;
default:
}
}
// public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path ) {
// return this.generateArduinoJSONSet(tabs, path, -1);
// }
public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path, int arrayIndex, boolean forLiveData ) {
if (super.getHTMLType() == null) {
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null HTML type.");
return "";
}
if (super.getType() == null) {
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null CType type.");
return "";
}
String caseString = "";
switch(super.getType()) {
case Struct: //NOTE: This does not actually allow the struct to be copied but the components inside of it
if (this.getArraySize() > 0) {
for(int i = 0; i < this.getArraySize(); i++) {
for(int j = 0; j < branches.size(); j++) {
caseString += ((TreeVariable) this.getArray().get(i)).branches.get(j).generateArduinoJSONSet(tabs, path.add(this, arrayIndex), i, forLiveData);
}
}//for
} else {
for(int i = 0; i < branches.size(); i++) {
caseString += branches.get(i).generateArduinoJSONSet(tabs, path.add(this, arrayIndex), forLiveData);
}
}
break;
case Enum:
caseString += super.generateArduinoJSONSet(tabs, path, arrayIndex, forLiveData); //The super class handles enums
break;
default:
break;
}
return caseString;
}
private class NumberLink {
Variable controller = null;
Variable slave = null;
private String pendingName = null;
private boolean pendingIsSlave = true;
public NumberLink(Variable var, String pendingName, boolean pendingIsSlave) {
this.pendingIsSlave = pendingIsSlave;
this.pendingName = pendingName;
if (pendingIsSlave) {
this.controller = var;
} else {
this.slave = var;
}
}
public NumberLink(Variable controller, Variable slave) {
this.controller = controller;
this.slave = slave;
}
public Variable getController() {
return controller;
}
public Variable getSlave() {
return slave;
}
public String getControllerName() {
if (controller != null)
return controller.getName();
else
return null;
}
public String getSlaveName() {
if (controller != null)
return controller.getName();
else
return null;
}
public void setSlave(Variable slave) {
this.slave = slave;
}
public String getPendingName() {
return pendingName;
}
public boolean isPendingSlave() {
return this.pendingIsSlave;
}
}
/**
* This function is only for Structures
*/
public String generateLinkJavaScript(String spacer) {
if (getType() != Ctype.Struct) { return ""; }
String js = "";
if (getArraySize() > 0) {
ArrayList<Variable> array = getArray();
for(int i = 0; i < array.size(); i++) {
js += ((TreeVariable) array.get(i)).generateLinkJavaScript(spacer);
}
} else {
//This is not an Array
Queue<Variable> queue = new LinkedList<>();
queue.addAll(branches);
Variable next = null;
ArrayList<NumberLink> pendingLinks = new ArrayList<>();
ArrayList<NumberLink> confirmedLinks = new ArrayList<>();
while ((next = queue.poll()) != null) {
if (next.getArraySize() > 0) {
for(int i = 0; i < pendingLinks.size(); i++) {
NumberLink link = pendingLinks.get(i);
if (link.isPendingSlave() && link.getPendingName().equals(next.getName())) {
link.setSlave(next);
confirmedLinks.add(link);
pendingLinks.remove(i);
break; //exit for loop
}
}//for loop
} else {
String linkName = next.getLinkedName();
if (linkName != null) {
pendingLinks.add(new NumberLink(next, linkName, true));
}
}
//check if the next is a Structure, then check its children
if (next.getType() == Ctype.Struct) {
js += ((TreeVariable) next).generateLinkJavaScript(spacer);
}
}
for(int i = 0; i < confirmedLinks.size(); i++) {
Variable controller = confirmedLinks.get(i).getController();
Variable slave = confirmedLinks.get(i).getSlave();
String uuidName = "item" + controller.getHTMLID().replace("-", "");
js += spacer + "const " + uuidName + " = document.getElementById(\"" + controller.getHTMLID() + "\");\n"
+ spacer + uuidName + ".addEventListener(\"change\", (event) => {\n"
+ spacer + "\tconst newValue = Number(event.target.value);\n";
ArrayList<Variable> array = slave.getArray();
for(int j = 0; j < array.size(); j++) {
// js += spacer + "\tdocument.getElementById(\"" + array.get(j).getHTMLID() + "\").style.visibility = newValue > " + j + " ? 'visible' : 'hidden';\n";
js += spacer + "\tdocument.getElementById(\"" + array.get(j).getHTMLID() + "\").hidden = !(newValue > " + j + ");\n";
}
js += spacer + "});\n"
+ spacer + uuidName + ".dispatchEvent(new Event('change', { bubbles: true }));\n\n";
}
}
return js;
}
// public TreeVariable makeCopy( ) {
// TreeVariable newTree = new TreeVariable(super.getName(), super.getType(), this.getTrunk());
// newTree.setArraySize(getArraySize());
// newTree.setSuperName(getSuperName());
// newTree.setLinkedName(getLinkedName());
// newTree.setDisplayName(getDisplayName());
// newTree.setHTMLType(getHTMLType());
// newTree.setDecimalPlaces(getDecimalPlaces());
// newTree.branches = this.branches;
//
// return newTree;
// }
public Variable deepCopy() {
TreeVariable copy = new TreeVariable(getName(), getType(), trunk);
copy.setSuperName(getSuperName());
copy.setLinkedName(getLinkedName());
copy.setDisplayName(getDisplayName());
copy.setHTMLType(getHTMLType());
copy.setDecimalPlaces(getDecimalPlaces());
// if (getArraySize() > 0) {
//// getPrefixID().resetCounter();
// CPath.resetSubPrefixes(this);
// }
copy.setPrefixID(getPrefixID());
for(int i = 0; i < this.branches.size(); i++) {
copy.branches.add(branches.get(i).deepCopy());
}
copy.setArraySize(super.getArraySize());
return copy;
}
public String toString() {
return "TreeVariable: " + getName() + "";
}
}