/**
   * Constructs a new AlgebraicValueEditor.
   *
   * @param valueEditorHierarchyManager
   */
  public AlgebraicValueEditor(ValueEditorHierarchyManager valueEditorHierarchyManager) {
    super(valueEditorHierarchyManager);

    setFocusCycleRoot(true);
    setLayout(new BorderLayout());
    setResizable(true);
    add(contentScrollPane, BorderLayout.CENTER);

    contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));

    contentScrollPane.getHorizontalScrollBar().setCursor(Cursor.getDefaultCursor());
    contentScrollPane.getVerticalScrollBar().setCursor(Cursor.getDefaultCursor());

    KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
    focusManager.addPropertyChangeListener("permanentFocusOwner", focusChangeListener);
  }
  /** @see org.openquark.gems.client.valueentry.ValueEditor#setInitialValue() */
  @Override
  public void setInitialValue() {

    DataConstructorValueNode valueNode = getDataConstructorValueNode();
    TypeExpr valueNodeTypeExpr = valueNode.getTypeExpr();

    QualifiedName typeConstructorName = valueNode.getTypeExpr().rootTypeConsApp().getName();
    DataConstructor[] dataConsList =
        valueEditorManager.getPerspective().getDataConstructorsForType(typeConstructorName);

    DataConstructor currentDataCons = valueNode.getDataConstructor();

    ValueEditorListener childListener = new ChildValueEditorListener();
    KeyAdapter editorPanelKeyListener = new EditorPanelKeyListener();

    boolean haveAddedPanel = false;
    FontMetrics fontMetrics = getFontMetrics(getFont().deriveFont(Font.BOLD));
    ScopedEntityNamingPolicy namingPolicy =
        new UnqualifiedUnlessAmbiguous(
            valueEditorManager.getPerspective().getWorkingModuleTypeInfo());

    // Remove components in case this is called twice.
    contentPanel.removeAll();

    // Create an editor panel for each supported data constructor.
    for (final DataConstructor dataCons : dataConsList) {

      DataConstructorValueNode newValueNode = null;

      if (currentDataCons.getName().equals(dataCons.getName())) {

        // If this is the current data constructor, just transmute the value node.
        newValueNode =
            (DataConstructorValueNode)
                valueNode.transmuteValueNode(
                    valueEditorManager.getValueNodeBuilderHelper(),
                    valueEditorManager.getValueNodeTransformer(),
                    valueNodeTypeExpr);
      } else {

        // Create a new value node.  newValueNode will be null if the data constructor is not
        // supported.
        newValueNode =
            valueEditorManager
                .getValueNodeBuilderHelper()
                .getValueNodeProvider(DataConstructorValueNode.class)
                .getNodeInstance(null, dataCons, valueNodeTypeExpr);
      }

      // Create a data constructor editor panel if the data constructor is supported.
      if (newValueNode != null) {

        DataConstructorEditorPanel editorPanel = new DataConstructorEditorPanel(this, newValueNode);
        editorPanel.setFocusedLook(false);
        editorPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        editorPanel.addArgumentEditorListener(childListener);
        editorPanel.addKeyListener(editorPanelKeyListener);

        if (haveAddedPanel) {
          contentPanel.add(new JSeparator(SwingConstants.HORIZONTAL));
        }

        editorPanelList.add(editorPanel);
        contentPanel.add(editorPanel);

        haveAddedPanel = true;

        int titleLength = fontMetrics.stringWidth(dataCons.getAdaptedName(namingPolicy));
        if (titleLength > longestNameLength) {
          longestNameLength = titleLength;
        }
      }
    }

    // Make the width of all title labels the same so that the editor panels align.
    for (final DataConstructorEditorPanel dataConstructorEditorPanel : editorPanelList) {
      dataConstructorEditorPanel.setTitleLabelWidth(longestNameLength);
    }

    // If we have only one child editor, remove the focus listener.
    // Also make the only editor's value entry panels visible, but give it the normal background.
    if (editorPanelList.size() == 1) {
      removeFocusListener();
      DataConstructorEditorPanel childEditor = editorPanelList.get(0);
      childEditor.setFocusedLook(false);
      childEditor.setArgumentEditorsVisible(true);
    }

    resetSize();
  }