text: class Variable{
      constructor(id, name, varName, symbol, domain, element, globalPointerReference){
          this.id = id;   // Fully qualified id that has variable name, equation, and workspace id
          // console.log(this.id)
          this.name = name;   // Only contains the context name for the quantity; eg: deform, thermalcoeff
  
          this.parentSymbolTemplateZero = symbol; // This is constant, unchangeable. This is the ground truth for
                                                  // variable names. Variables start with this name, and as blank
                                                  // boxes, can receive another name with subscript, and go on to
                                                  // get associated, etc. But, when the name is reset as a blank
                                                  // box, it gets reset to this name.
          this.parentSymbolTemplate = symbol; // Stores the original symbol LaTeX for restoration from subscripting, 
                                              // but can be changed when the variable is renamed when it is a
                                              // blank variable box. It resets to TemplateZero (TODO: Try to make this better)
          this.parentSymbol = symbol; // Stores the current symbol, related to subscripting
          // this.subscript = " "; // only for the single grayed out variable state.
          this.currentSymbol = varName;   // id generated by Window.getVarName, of the type x_y etc, internal use only.
  
          this.expectedDomain = domain;
          this.currentDomain = null;
          this.currentUnit = null;
          
          // TODO: decide if we should replace currentSymbol with delegating
          // everything to this.value; where this would have a numerical value
          // or just be used as a variable name if empty, or an Association object.
          // which can then be used
          this.value = null;
          this.valueNegated = false;
          this.valueRepr = null;
          this.valueType = null;
          
          this.element = element;
          this.globalPointerReference = globalPointerReference;
  
          this.valueDisplay = element.childNodes[0];
          this.unitDisplay = element.childNodes[1];
          this.valueDisplay.dataset.status = "empty";
          this.unitDisplay.dataset.status = "empty";
          // console.log(this.name, element);
  
          this.unitChangeHandler = null;  // Used as a workaround for removing clickhandlers for changeUnits
          
          // Creating the grayed out symbol representation
          this.grayOut();
  
          // this.element.addEventListener(
          //     "dblclick", e=> {
          //         console.log("double click",e);
          //         e.stopPropagation();
          //         this.removeValue();
          //         // TODO: INSERT DELETION logEvent here.
          //     }
          // )
          this.element.addEventListener(
              "click", e => {
                  e.stopPropagation();
                  Window.showBlankPrompt = false;
                  //console.log(this.id)
                  //MAJOR TODO: Clean up all the conditionals
                  /**
                   * 1. If a value box is clicked, followed by a variable box,
                   *  a) If there is an association, we remove it and replace it with a value
                   *  b) if not, just place a value there.
                   * 2. If a variable box is clicked, and nothing before it, and it only contains a value, remove it.
                   * 3. If a variable box is clicked, and nothing before it, and it is empty, we record start of an
                   * association.
                   * 4. If a variable box is clicked,  whether or not it is empty, 
                   * and we clicked on another variable box before it, and it is not the same object, we create a
                   * 2-way association. Create this as the value for the two variable objects as well. valueType is
                   * "association".
                   * 5. If a variable box is clicked, whether or not it is empty, if 
                   * we clicked on a variable box earlier that had a value of type association,
                   * and it is not the same object, 
                   * then we add a valueType "association" to this variable as well, and add it to the association.
                   * 6. If a variable box is clicked, whether or not it is empty, if 
                   * we clicked on a variable box earlier that had a value of type association,
                   * and it IS INFACT the same object, by calling removeAssociation().
                   */
                  
                  if(this.valueType==null) // Box was empty
                  {
                      if(this.globalPointerReference.currentClickedObject == null) // Clicked on nothing before this
                      {
                          var element = JSAV.utils.dialog(
                              '<ul><li>multiply by -1</li><li>start an association</li><li>rename variables</li><li>insert value/unit</li></ul>',
                              {width: 150}
                          );
                          element[0].style.top = e.pageY+5+"px"; element[0].style.left = e.pageX+10+"px";
                          element[0].childNodes[0].childNodes[0].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  // negate and clear context
                                  this.valueNegated = !this.valueNegated;
                                  if(this.valueNegated) {
                                      // Then add the '-' to the beginning of the current symbol text
                                      this.parentSymbol = '-'+this.parentSymbol;
                                      // Render the new symbol.
                                      this.grayOut();
                                      // Revert it back, since we don't want it to actually show up later.
                                      this.parentSymbol = this.parentSymbol.slice(1);
                                  }
                                  else {
                                      // Don't worry about it
                                      // Else, remove the first symbol only (which is the '-' symbol)
                                      // this.parentSymbol = this.parentSymbol.slice(1);
                                      // Render the new symbol.
                                      this.grayOut();
                                  }
  
                                  Window.clearGlobalPointerReference();
                                  // this.globalPointerReference.currentClickedObject = null;
                                  // this.globalPointerReference.currentClickedObjectType = null;
                                  // this.globalPointerReference.currentClickedObjectDescription = null;
                                  element.close();
                                  this.adjustParentEquationVisuals();
                              }
                          );
                          element[0].childNodes[0].childNodes[1].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  // Start recording a possible association
                                  this.globalPointerReference.currentClickedObject = this;
                                  this.globalPointerReference.currentClickedObjectType = "var-box";
                                  this.globalPointerReference.currentClickedObjectDescription = "started new assoc";
                                  this.globalPointerReference.currentClickedObject.element.classList.add("selectedvalue");
                                  // console.log("clicked first box");
                                  element.close();
                              }
                          );
                          element[0].childNodes[0].childNodes[2].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  element.close();
                                  
                                  // console.log("Renaming variables")
  
                                  var inputPromptHTML = 
                                  '<h4>Enter a variable name here.</h4>'+
                                  '<input type="text" id="varname" name="varname" size="8" />'+
                                  '<h4>Enter a subscript here.</h4>'+
                                  '<input type="text" id="subscriptname" name="subscriptname" size="8" />'+
                                  '<input type="button" id="submit" value="Set variable name"/>';
                                  var inputBox = JSAV.utils.dialog(inputPromptHTML, {width: 150});
                                  Window.box = inputBox;
                                  inputBox[0].querySelector("#submit").addEventListener("click", 
                                      e3=> { 
                                          e3.stopPropagation();
                                          this.valueNegated = false;
                                          this.changeVarName(
                                              Window.box[0].querySelector("#varname").value,
                                              Window.box[0].querySelector("#subscriptname").value
                                          );
                                          Window.box.close();
                                          Window.clearGlobalPointerReference();
                                          delete Window.box;
                                          this.adjustParentEquationVisuals();
                                      } 
                                  );
                                  inputBox[0].addEventListener("click", 
                                      e3=> { 
                                          e3.stopPropagation();
                                          Window.showBlankPrompt = false;
                                      }
                                  );
                              }
                          );
                          element[0].childNodes[0].childNodes[3].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  element.close();
                                  var listOfDomains = '<option value="--select a domain--"></option>';
                                  for (var d in Window.UNIT_DB)
                                      listOfDomains+=
                                      '<option value="'+d+'">'+d+'</option>';
  
                                  var inputPromptHTML = 
                                  '<h4>Enter value here.</h4>'+
                                  '<input type="text" id="value" name="value" size="8" />'+
                                  '<h4>Select the domain and the unit</h4>'+
                                  '<select id="domain">'+listOfDomains+'</select>'+
                                  '<select id="unit"></select>'+
                                  '<input type="button" id="submit" value="Set value/unit"/>';
  
                                  var inputBox = JSAV.utils.dialog(inputPromptHTML, {width: 150});
                                  Window.box = inputBox;
  
                                  inputBox[0].querySelector("#domain").addEventListener("change", 
                                      e3=> { 
                                          e3.stopPropagation();
                                          // console.log(this, Window.box[0])
                                          var unitlist = Window.box[0].querySelector("#unit");
                                          unitlist.innerHTML = "";
                                          for(var unit in Window.UNIT_DB[event.target.value])
                                          {
                                              unitlist.innerHTML+='<option value="'+unit+'">'+unit+'</option>';
                                          }
                                      }
                                  );
                                  
                                  // inputBox[0].querySelector("#domain").addEventListener("click", 
                                  inputBox[0].addEventListener("click", 
                                      e3=> { 
                                          e3.stopPropagation();
                                          Window.showBlankPrompt = false;
                                      }
                                  );
                                  // inputBox[0].querySelector("#unit").addEventListener("click", 
                                  inputBox[0].addEventListener("click", 
                                      e3=> { 
                                          e3.stopPropagation();
                                          Window.showBlankPrompt = false;
                                      }
                                  );
  
                                  inputBox[0].querySelector("#submit").addEventListener("click", 
                                      e3=> { 
                                          e3.stopPropagation();
                                          this.valueNegated = false;
                                          var domain = Window.box[0].querySelector("#domain").value;
                                          var unit = Window.box[0].querySelector("#unit").value;
                                          this.globalPointerReference.currentClickedObject = 
                                          new ValueBox(
                                              true,
                                              {
                                                  dataset: {
                                                      value: parseFloat(Window.box[0].querySelector("#value").value),
                                                      valueDisplay: null,
                                                      domain: domain,
                                                      unit: Window.UNIT_DB[domain][unit]['unit'],
                                                      unitDisplay: Window.UNIT_DB[domain][unit]['unitDisp']
                                                  }
                                              },
                                              null, null
                                          );
                                          this.globalPointerReference.currentClickedObjectType = "value-box";
                                          // this.changeVarName(
                                          //     Window.box[0].querySelector("#value").value,
                                          //     Window.box[0].querySelector("#subscriptname").value
                                          // );
                                          this.clickAddValue();
                                          Window.clearGlobalPointerReference();
                                          Window.box.close();
                                          this.adjustParentEquationVisuals();
                                          delete Window.box;
                                      }
                                  );
                              }
                          );
                      }
                      else if(this.globalPointerReference.currentClickedObject == this) // Clicked on the same thing
                      {
                          // negate and clear context
                          // this.valueNegated = !this.valueNegated;
                          // if(this.valueNegated) {
                          //     // Then add the '-' to the beginning of the current symbol text
                          //     this.parentSymbol = '-'+this.parentSymbol;
                          //     // Render the new symbol.
                          //     this.grayOut();
                          //     // Revert it back, since we don't want it to actually show up later.
                          //     this.parentSymbol = this.parentSymbol.slice(1);
                          // }
                          // else {
                          //     // Don't worry about it
                          //     // Else, remove the first symbol only (which is the '-' symbol)
                          //     // this.parentSymbol = this.parentSymbol.slice(1);
                          //     // Render the new symbol.
                          //     this.grayOut();
                          // }
  
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                      }
                      else if(this.globalPointerReference.currentClickedObject.valueType == "association") // Clicked on an existing association
                      {
                          // "association type is always with a var-box type"
                          // console.log("creating multiway association");
                          this.valueType = "association";
                          this.globalPointerReference.currentClickedObject.value.addVariable(this);
                          this.value = this.globalPointerReference.currentClickedObject.value;
  
                          // console.log(this.globalPointerReference.currentClickedObject.id);
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                      }
                      else if(this.globalPointerReference.currentClickedObjectDescription == "started new assoc"){
                          // Create the 2-way association and clear the global pointer
                          // console.log("creating two way association");
                          this.valueType = "association";
                          this.globalPointerReference.currentClickedObject.valueType = "association";
                          this.globalPointerReference.currentClickedObject.valueNegated = false; // for now, we reset that status.
                          this.value = new Association(this.globalPointerReference.currentClickedObject, this);
                          this.globalPointerReference.currentClickedObject.value = this.value;
  
                          // console.log(this.globalPointerReference.currentClickedObject.id);
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                      }
                      else if(this.globalPointerReference.currentClickedObjectType == "value-box")
                      {
                          // If it's empty, or has a numerical value, just add/overwrite the values in here.
                          this.clickAddValue();
                          // console.log("added value to a box");
                          Window.clearGlobalPointerReference();
                      }
                      else if(this.globalPointerReference.currentClickedObjectDescription == "copy number")
                      {
                          this.clickAddValue();
                          // console.log("copied a number over");
                          Window.clearGlobalPointerReference();
                      }
                  }
                  else if(this.valueType=="number")
                  {
                      if (this.globalPointerReference.currentClickedObject == null)
                      // If there is no other complicated context, simply the number needs to be manipulated.
                      {
                          var element = JSAV.utils.dialog(
                              "<ul><li>multiply by -1</li><li>copy</li><li>clear value from box</li></ul>",
                              {width: 150}
                          );
                          element[0].style.top = e.pageY+5+"px"; element[0].style.left = e.pageX+10+"px";
                          element[0].childNodes[0].childNodes[0].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  this.valueNegated = !this.valueNegated;
                                  this.value = -1 * this.value;
                                  // this.valueRepr = Window.valueTruncate(this.value);
                                  this.valueRepr = Window.valueStringRepr(this.value);
                                  this.setValueUnit(String(this.valueRepr), Window.unitDomainMap[this.currentUnit][1]);
  
                                  Window.clearGlobalPointerReference();
                                  // this.globalPointerReference.currentClickedObject = null;
                                  // this.globalPointerReference.currentClickedObjectType = null;
                                  // this.globalPointerReference.currentClickedObjectDescription = null;
                                  element.close();
                                  this.adjustParentEquationVisuals();
                              }
                          );
                          element[0].childNodes[0].childNodes[1].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  // console.log("started copying variable");
  
                                  this.globalPointerReference.currentClickedObject = this;
                                  this.globalPointerReference.currentClickedObjectType = "var-box";
                                  this.globalPointerReference.currentClickedObjectDescription = "copy number";
                                  this.globalPointerReference.currentClickedObject.element.classList.add("selectedvalue")
  
                                  element.close();
                                  this.adjustParentEquationVisuals();
                              }
                          )
                          element[0].childNodes[0].childNodes[2].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  this.removeValue();
                                  // console.log("remove value from a box");
  
                                  Window.clearGlobalPointerReference();
                                  // this.globalPointerReference.currentClickedObject = null;
                                  // this.globalPointerReference.currentClickedObjectType = null;
                                  // this.globalPointerReference.currentClickedObjectDescription = null;
                                  element.close();
                                  this.adjustParentEquationVisuals();
                              }
                          )
                      }
                      else if(this.globalPointerReference.currentClickedObject.valueType == "association")
                      {
                          this.removeValue();
                          // An existing association is involved
                          // "association type is always with a var-box type"
                          // console.log("creating multiway association");
                          this.valueType = "association";
                          this.globalPointerReference.currentClickedObject.value.addVariable(this);
                          this.value = this.globalPointerReference.currentClickedObject.value;
  
                          // console.log(this.globalPointerReference.currentClickedObject.id);
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                      }
                      else if(this.globalPointerReference.currentClickedObjectDescription == "started new assoc")
                      {
                          this.removeValue();
                          // Create the 2-way association and clear the global pointer
                          // console.log("creating two way association");
                          this.valueType = "association";
                          this.globalPointerReference.currentClickedObject.valueType = "association";
                          this.value = new Association(this.globalPointerReference.currentClickedObject, this);
                          this.globalPointerReference.currentClickedObject.value = this.value;
  
                          // console.log(this.globalPointerReference.currentClickedObject.id);
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                      }
                      else if(this.globalPointerReference.currentClickedObjectType == "value-box")
                      {
                          // If it's empty, or has a numerical value, just add/overwrite the values in here.
                          this.removeValue();
                          this.clickAddValue();
                          Window.clearGlobalPointerReference();
                          // console.log("replaced a value in a box from prose");
                      }
                      else if(this.globalPointerReference.currentClickedObjectDescription == "copy number")
                      {
                          this.removeValue();
                          this.clickAddValue();
                          Window.clearGlobalPointerReference();
                          // console.log("copied a number over");
                      }
                  }
                  else if(this.valueType=="association")
                  {
                      if (this.globalPointerReference.currentClickedObject == null)
                      {
                          var element = JSAV.utils.dialog(
                              "<ul><li>multiply by -1</li><li>add new to association</li><li>Rename association</li><li>clear association</li></ul>",
                              {width: 150}
                          );
                          element[0].style.top = e.pageY+5+"px"; element[0].style.left = e.pageX+10+"px";
                          element[0].childNodes[0].childNodes[0].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  // negate and clear context
                                  this.valueNegated = !this.valueNegated;
                                  if(this.valueNegated) {
                                      // Then add the '-' to the beginning of the current symbol text
                                      // BUT since this is an association, and we're only doing it for
                                      // this example, we only change the variable's display text.
                                      var tempElement = Window.jsavObject.label(
                                          katex.renderToString('-'+this.value.varDisplay)).hide();
                                      this.valueDisplay.innerHTML = 
                                      tempElement.element[0].childNodes[0].childNodes[1].childNodes[2].innerHTML;
                                      tempElement.clear();
                                      // vvv: this line might be too risky by itself; so we manually updated it.
                                      // This is mainly because we didn't want to disturb the parentSymbol
                                      // attribute by itself; we preserved what it originally looked like.
                                      // We don't know if this messes up anything elsewhere; this is just being
                                      // extra careful.
                                      
                                      // This vv-- logic on the other hand, may work; just leave it be though.
                                      // this.parentSymbol = '-'+this.value.varDisplay;
                                      // NOTE: grayOut() and line 48 in Association.updateVarDisplay()
                                      // Are the same in that this.varDisplay and this.parentSymbol
                                      // are the Assoc and non-assoc versions of the symbols, and
                                      // the code modifies the same HTML element.
                                      // updateVarDisplay() changes for all variables in an assoc,
                                      // while changing parentSymbol only does it for this one.
                                      // this.grayOut();
                                      // Revert it back, since we don't want it to actually show up later.
                                      // This saves effort for negging a negation, which must revert to
                                      // the original symbol used for the association
                                      // (the version with subscripts)
                                      // this.parentSymbol = this.value.varDisplay;
                                  }
                                  else {
                                      var tempElement = Window.jsavObject.label(
                                          katex.renderToString(this.value.varDisplay)).hide();
                                      this.valueDisplay.innerHTML = 
                                      tempElement.element[0].childNodes[0].childNodes[1].childNodes[2].innerHTML;
                                      tempElement.clear();
                                      // Leave it be, is counterpart to commented part above.
                                      // Don't worry about it
                                      // Else, remove the first symbol only (which is the '-' symbol)
                                      // this.parentSymbol = this.parentSymbol.slice(1);
                                      // Render the new symbol.
                                      // this.grayOut();
                                  }
  
                                  Window.clearGlobalPointerReference();
                                  // this.globalPointerReference.currentClickedObject = null;
                                  // this.globalPointerReference.currentClickedObjectType = null;
                                  // this.globalPointerReference.currentClickedObjectDescription = null;
                                  element.close();
                                  this.adjustParentEquationVisuals();
                              }
                          );
                          element[0].childNodes[0].childNodes[1].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  // For this menu, it simply starts recording the context.
                                  // Start recording a possible association
                                  this.globalPointerReference.currentClickedObject = this;
                                  this.globalPointerReference.currentClickedObjectType = "var-box";
                                  this.globalPointerReference.currentClickedObjectDescription = "started additional assoc";
                                  this.globalPointerReference.currentClickedObject.element.classList.add("selectedvalue");
                                  
                                  // console.log("clicked existing assoc box");
                                  element.close();
                                  // this.adjustParentEquationVisuals();
                              }
                          );
                          element[0].childNodes[0].childNodes[2].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  // console.log("started renaming variable association");
                                  element.close();
  
                                  var inputPromptHTML = 
                                  '<h4>Enter a variable name here.</h4>'+
                                  '<input type="text" id="varname" name="varname" size="8" />'+
                                  '<h4>Enter a subscript here.</h4>'+
                                  '<input type="text" id="subscriptname" name="subscriptname" size="8" />'+
                                  '<input type="button" id="submit" value="Set variable name"/>';
                                  var inputBox = JSAV.utils.dialog(inputPromptHTML, {width: 150});
                                  Window.box = inputBox;
                                  inputBox[0].querySelector("#submit").addEventListener("click", 
                                      e=> { 
                                          e.stopPropagation();
                                          this.valueNegated = false;
                                          this.value.setAssocVarDisplay(
                                              Window.box[0].querySelector("#varname").value,
                                              Window.box[0].querySelector("#subscriptname").value
                                          );
                                          Window.box.close();
                                          delete Window.box;
                                          this.adjustParentEquationVisuals();
                                      } 
                                  );
                              }
                          );
                          element[0].childNodes[0].childNodes[3].addEventListener(
                              "click", e2=> {
                                  e2.stopPropagation();
                                  this.value.removeAssociation(this);
                                  // console.log("assoc deletion");
  
                                  Window.clearGlobalPointerReference();
                                  // this.globalPointerReference.currentClickedObject = null;
                                  // this.globalPointerReference.currentClickedObjectType = null;
                                  // this.globalPointerReference.currentClickedObjectDescription = null;
                                  element.close();
                                  this.adjustParentEquationVisuals()
                              }
                          );
                      }
                      else if(this.globalPointerReference.currentClickedObjectType == "value-box") {
                          this.value.removeAssociation(this);
                          this.clickAddValue();
                          // console.log("replaced association with value from prose");
                      }
                      else if(this.globalPointerReference.currentClickedObjectDescription == "copy number") {
                          this.value.removeAssociation(this);
                          this.clickAddValue();
                          Window.clearGlobalPointerReference();
                          // console.log("replaced association with value copied over");
                      }
                      else if(this.globalPointerReference.currentClickedObject.valueType == "association") {
                          this.value.removeAssociation(this);
                          // console.log("creating multiway association");
                          this.valueType = "association";
                          this.globalPointerReference.currentClickedObject.value.addVariable(this);
                          this.value = this.globalPointerReference.currentClickedObject.value;
  
                          // console.log(this.globalPointerReference.currentClickedObject.id);
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                          // console.log("replacing an existing association with another existing association")
                      }
                      else if(this.globalPointerReference.currentClickedObjectDescription == "started new assoc")
                      {
                          this.value.removeAssociation(this);
                          // Create the 2-way association and clear the global pointer
                          // console.log("creating two way association");
                          this.valueType = "association";
                          this.globalPointerReference.currentClickedObject.valueType = "association";
                          this.value = new Association(this.globalPointerReference.currentClickedObject, this);
                          this.globalPointerReference.currentClickedObject.value = this.value;
  
                          // console.log(this.globalPointerReference.currentClickedObject.id);
                          Window.clearGlobalPointerReference();
                          // this.globalPointerReference.currentClickedObject = null;
                          // this.globalPointerReference.currentClickedObjectType = null;
                          // this.globalPointerReference.currentClickedObjectDescription = null;
                      }
                  }
  
                  this.adjustParentEquationVisuals();
                  // console.log("Adjusting visuals of the equation")
                  // var activeEq = Window.windowManager.shiftActiveEqDown(this.id);
                  // // console.log(id);
                  // if(activeEq != null) {
                  //     var split = id.split("_");
          
                  //     var wkspaceNum = split[0].substring(2, split[0].length);
                  //     Window.windowManager.shiftDown(activeEq, wkspaceNum);
                  // }
  
              }
          )
      }
  
      adjustParentEquationVisuals()
      {
          // var shiftChain = Window.windowManager.shiftRight(equationObject);
          // console.log(shiftChain);
          // if(shiftChain == "shiftActiveEqDown") {
          //     // console.log(Window.parentObject);
          //     var extend = Window.windowManager.shiftActiveEqDown(equationObject.name);
          //     if(extend != null) {
          //         var split = equationObject.name.split("_");
          //         var wkspaceNum = split[0].substring(2, split[0].length);
          //         Window.windowManager.shiftDown(extend, wkspaceNum);
          //     }
              
          // }
          // else if(shiftChain == "shiftActiveEqUp") {
          //     Window.windowManager.shiftActiveEqUp(equationObject.name);
          
          var extend = Window.windowManager.shiftActiveEqDown(this.id);
          if(extend != null) {
              var split = this.id.split("_");
              var wkspaceNum = split[0].substring(2, split[0].length);
              Window.windowManager.shiftDown(extend, wkspaceNum);
          }
          Window.windowManager.shiftActiveEqUp(this.id);
  
          // console.log("Adjusting visuals of the equation")
          // var activeEq = Window.windowManager.shiftActiveEqDown(this.id);
          // // console.log(id);
          // if(activeEq != null) {
          //     var split = id.split("_");
  
          //     var wkspaceNum = split[0].substring(2, split[0].length);
          //     Window.windowManager.shiftDown(activeEq, wkspaceNum);
          // }
      }
  
      clickAddValue()
      {
          // Works just fine, no need for console.log()
          
          // domain check: to be checked later at solving stage
          // if(this.expectedDomain != this.globalPointerReference.currentClickedObject.domain
          //     && this.expectedDomain != "dimensionless"
          //     )
          // {
          //     alert("\nYou tried to put a '"+
          //     this.globalPointerReference.currentClickedObject.domain
          //     +"' type value in the box."
          //     +"\n Expected domain: "+this.expectedDomain
          //     +"\nPlease try a value of another type (the colors might help).\n\n");
          //     return;
          // }
  
          // console.log(this.globalPointerReference)
          // add the value
          this.value = String(this.globalPointerReference.currentClickedObject.value).slice();
          if(this.globalPointerReference.currentClickedObjectType == "value-box") {
              this.currentDomain = this.globalPointerReference.currentClickedObject.domain;
              this.currentUnit = this.globalPointerReference.currentClickedObject.unit;
          }
          else {
              this.currentDomain = this.globalPointerReference.currentClickedObject.currentDomain;
              this.currentUnit = this.globalPointerReference.currentClickedObject.currentUnit;
          }
          // this.valueRepr = Window.valueTruncate(this.value);
          this.valueRepr = Window.valueStringRepr(this.value);
          this.element.setAttribute("data-domain", this.currentDomain);
          this.valueType = "number";
          this.valueNegated = false;
          
          if(this.globalPointerReference.currentClickedObjectType == "value-box") {
              this.setValueUnit(
                  // this.globalPointerReference.currentClickedObject.valueDisplay,
                  this.valueRepr,
                  this.globalPointerReference.currentClickedObject.unitDisplay
              )
          }
          else {
              // The innerHTML is already set, so copying it over covers what setValueUnit does.
              this.valueDisplay.dataset.status = "filled";
              this.unitDisplay.dataset.status = "filled";
              this.valueDisplay.innerHTML = this.globalPointerReference.currentClickedObject.valueDisplay.innerHTML;
              this.unitDisplay.innerHTML = this.globalPointerReference.currentClickedObject.unitDisplay.innerHTML;
          }        
          // Clear up the clicked context; the values and everything
          // this.globalPointerReference.currentClickedObject = null;
          // this.globalPointerReference.currentClickedObjectType = null;
          // this.globalPointerReference.currentClickedObjectDescription = null;
          //console.log(this.globalPointerReference);
  
          // clickHandler for unit changes()
          this.unitChangeHandler = e => this.changeUnits(e, this);
          this.unitDisplay.addEventListener("click", this.unitChangeHandler);
      }
      setValueUnit(value, unit)
      {
          // value, unit are the actual text representations to be put in there. So, this would be
          // unitDisp from the UNIT_DB entries.
          this.valueDisplay.innerHTML = "";
          this.unitDisplay.innerHTML = "";
          this.valueDisplay.dataset.status = "filled";
          this.unitDisplay.dataset.status = "filled";
  
          for(var digitindex=0; digitindex<value.split("").length; digitindex++)
          {
              this.valueDisplay.innerHTML+='<span class="mord">'+value.split("")[digitindex]+'</span>';
          }
          for(var u=0; u<unit.split("").length;
              u++)
          {
              this.unitDisplay.innerHTML+='<span class="mord mathit">'+unit.split("")[u]+'</span>';
          }
      }
      removeValue()
      {
          // console.log("removed value");
          // Double click replaces the container with the empty box from before.
          // Possibly with the grayed out letters, once we've fixed that.
          this.element.setAttribute("data-domain","empty");
          this.valueDisplay.innerHTML="";
          this.unitDisplay.innerHTML="";
          this.currentDomain = null;
          this.value = null;
          this.valueType = null;
          this.valueNegated = false;
  
          this.unitDisplay.removeEventListener("click", this.unitChangeHandler);
          this.valueDisplay.dataset.status = "empty";
          this.grayOut();
  
          Window.windowManager.shiftActiveEqUp(this.id);
  
      }
      grayOut()
      {
          // Create a JSAV element temporarily based on the symbol, hide it;
          // copy over the katex element to the innerHTML, and save it.
          var tempElement = Window.jsavObject.label(katex.renderToString(this.parentSymbol)).hide();
          this.valueDisplay.innerHTML = tempElement.element[0].childNodes[0].childNodes[1].childNodes[2].innerHTML;
          tempElement.clear();
      }
      changeVarName(varname, subscript)
      {
          // Logic: update the parentSymbolTemplate and the current parentSymbol
          // This is safe since this gets called only if the box is empty.
          // Also, since the parentSymbol is updated to this, any subsequent associations made
          // will use this name, and 
          if(varname == "" && subscript == "")
          {
              this.parentSymbolTemplate = this.parentSymbolTemplateZero;  // reset to the original template symbol defined in the equationbank
              // this.parentSymbol = this.parentSymbolTemplate;
          }
          else if(varname == ""){
              // not very obvious, just means only the subscript will be updated, main text remains the same.
              // this.subscript = subscript;
  
              // This means the parentSymbolTemplate doesn't necessarily change a lot
              this.parentSymbolTemplate = this.parentSymbolTemplate.replace(
                  new RegExp('_\{[A-Za-z0-9 ]+\}', 'g'),"_{"+subscript+"}");
              // this.parentSymbol = this.parentSymbolTemplate;
          }
          else
          {
              this.parentSymbolTemplate = varname+"_{"+subscript+"}";
              // this.parentSymbol = varname+"_{"+subscript+"}";
          }
          this.parentSymbol = this.parentSymbolTemplate;
          this.grayOut();
      }
      getParentEquationId()
      {
          return (x => x.slice(0,x.lastIndexOf("_")))(this.id);
      }
      changeUnits(event, varObj){
          /**
           * Define list of units and standard value conversions in here
           * grouped by domain
           * UNIT_DB = {};
           */
          // Creating other units, to delegate this to a Singleton global object
          
          /**
           * Populate var text with the list of units for this domain.
           * Click handlers are associated with each element, create data-unit domains for them
           * to match with.
          */
          event.stopPropagation();
          console.log(event, varObj);
          
          var text = "<ul>";
          // console.log(UNIT_DB[event.target.parentNode.parentNode.dataset.domain]);
          if(Window.UNIT_DB[event.target.parentNode.parentNode.dataset.domain] == null)
              text += "<li>No options available</li>"
          else for(var x in Window.UNIT_DB[event.target.parentNode.parentNode.dataset.domain])
          {
              text+='<li data-unitname="'+x+'">'+x+' ('+
              Window.UNIT_DB[event.target.parentNode.parentNode.dataset.domain][x]['unitDisp']+')</li>';
          }
          text+="</ul>";
  
          var element = JSAV.utils.dialog(text, {width: 100});
          Window.obj = event.target;
          Window.showBlankPrompt = false; // TODO: Replace with explicit calls to createContext with details
          element[0].style.top = event.pageY+5+"px";
          element[0].style.left = event.pageX+10+"px";
          element[0].childNodes[0].childNodes.forEach(x => {
              x.addEventListener(
                  "click", e=> {
                      e.stopPropagation();
                      
                      console.log(varObj.currentUnit, x.dataset.unitname);
  
                      // Change internals
                      // var oldUnit = this.currentUnit;
                      // this.currentUnit = Window.UNIT_DB[event.target.parentNode.parentNode.dataset.domain][x.dataset.unitname]['unit'];
                      // this.value = mathjs.evaluate("number("+this.value+" "+oldUnit+", "+this.currentUnit+")")
                      // // this.valueRepr = Window.valueTruncate(this.value);
                      // this.valueRepr = Window.valueStringRepr(this.value);
  
                      var oldUnit = varObj.currentUnit;
                      varObj.currentUnit = Window.UNIT_DB[event.target.parentNode.parentNode.dataset.domain][x.dataset.unitname]['unit'];
                      varObj.value = mathjs.evaluate("number("+varObj.value+" "+oldUnit+", "+varObj.currentUnit+")")
                      // this.valueRepr = Window.valueTruncate(this.value);
                      varObj.valueRepr = Window.valueStringRepr(varObj.value);
  
                      // Change external views
                      varObj.setValueUnit(String(varObj.valueRepr),
                      Window.UNIT_DB[event.target.parentNode.parentNode.dataset.domain][x.dataset.unitname]['unitDisp']);
                      element.close();
                      Window.clearGlobalPointerReference();
                      varObj.adjustParentEquationVisuals();
                  }
              )
          });
      }
  }
  window.Variable = window.Variable || Variable