/**
     * Constructor.
     *
     * @param iBranchIndex int Index which identifies the branch.
     * @param kFlyPathGraph FlyPathGraphCurve Data structure which contains all of the information
     *     about each branch and its connections.
     */
    public BranchState(int iBranchIndex, FlyPathGraphCurve kFlyPathGraph) {
      m_iBranchIndex = iBranchIndex;
      m_kBranchCurve = kFlyPathGraph.getCurvePosition(iBranchIndex);

      m_fDistUnvisitedMin = 0.0f;
      m_fDistUnvisitedMax = 1.0f;

      m_afBranchPoint = kFlyPathGraph.getBranchPoints(iBranchIndex);
      m_iParentBranchIndex = kFlyPathGraph.getBranchParentIndex(iBranchIndex);
      m_fParentBranchPoint = kFlyPathGraph.getBranchParentNormalizedDist(iBranchIndex);

      start();
    }
  /**
   * Setup to fly along the specified path and look around.
   *
   * @param kFlyPathGraph FlyPathGraphCurve contains the information regarding the graph
   *     representation of 3D path segments represented by Curve3 instances
   * @param kAnnotateList FlyPathAnnotateList contains the list of annotation points.
   * @param kTransformPosition TransformGroup contains the Transform3D for the current viewing
   *     position.
   * @param kTransformDirection TransformGroup contains the Transform3D for the current viewing
   *     direction.
   * @param kTransformOrientation TransformGroup contains the Transform3D for the current viewing
   *     orientation.
   * @param _parentScene the parent frame which hold Canvas3D.
   */
  public FlyPathBehavior_WM(
      FlyPathGraphCurve kFlyPathGraph,
      FlyPathAnnotateList_WM kAnnotateList,
      FlyThroughRender _parentScene) {

    // Keep references to these.
    m_kFlyPathGraph = kFlyPathGraph;
    m_kAnnotateList = kAnnotateList;
    parentScene = _parentScene;
    parentScene.GetCanvas().addKeyListener(this);

    // Create array to store the state of each branch.
    int iNumBranches = kFlyPathGraph.getNumBranches();

    m_akBranchState = new BranchState[iNumBranches];

    for (int iBranch = 0; iBranch < iNumBranches; iBranch++) {
      m_akBranchState[iBranch] = new BranchState(iBranch, kFlyPathGraph);
    }

    // Set initial branch, position, and step.
    // Compute the distance increment along the path that each
    // step will take.
    m_fPathStep = 1.0f;
    m_fGazeDist = 10.0f;
    setBranch(0);
  }
  /**
   * Create the array of branch choices and set the mode which forces the user to select from among
   * the branch choices.
   *
   * @param iBranchParent int Index which identifies the parent branch.
   * @param iBranchPoint int Index which identifies the point along the branch path where the
   *     branching occurs for the choices.
   */
  private void setupBranchChoices(int iBranchParent, int iBranchPoint) {

    // Get list of possible sub-branches for the parent.
    int[] aiBranchChildIndex = m_kFlyPathGraph.getBranchPointBranches(iBranchParent, iBranchPoint);

    // Get the information for the parent branch.
    BranchState kBranchStateParent = m_akBranchState[iBranchParent];

    // Build the list of possible branches.
    // First branch choice is the parent branch, current direction
    // Last branch choice is the parent branch, reverse direction
    // Reset all of the sub-branches to their start state.
    m_akBranchChoice = new BranchState[2 + aiBranchChildIndex.length];
    m_akBranchChoice[0] = kBranchStateParent.createCopy();
    m_akBranchChoice[m_akBranchChoice.length - 1] = kBranchStateParent.createReverseCopy();

    for (int i = 0; i < aiBranchChildIndex.length; i++) {
      int iBranchChild = aiBranchChildIndex[i];

      m_akBranchState[iBranchChild].start();
      m_akBranchChoice[i + 1] = m_akBranchState[iBranchChild].createCopy();
    }

    m_bChooseBranch = true;
    m_iBranchChoiceIndex = -1;
  }