/// <summary>
        /// Adds the IDs of the downstream nodes to the main JPanel. </summary>
        /// <param name="panel"> the panel to which to add the node IDs. </param>
        /// <param name="y"> the y coordinate at which to start adding them. </param>
        private void addDownstreamNodeToPanel(JPanel panel, int y)
        {
            HydrologyNode node = StateMod_NodeNetwork.findNextRealDownstreamNode(__nodes[__nodeNum]);

            JGUIUtil.addComponent(panel, new JLabel("Downstream node: "), 0, y, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.EAST);
            JGUIUtil.addComponent(panel, new JLabel("" + node.getCommonID() + " (model node)"), 1, y, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.WEST);

            y++;

            node = __nodes[__nodeNum].getDownstreamNode();
            if (node != null)
            {
                JGUIUtil.addComponent(panel, new JLabel("" + node.getCommonID() + " (diagram node)"), 1, y, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.WEST);
            }
            else
            {
                JGUIUtil.addComponent(panel, new JLabel("[None] (diagram node)"), 1, y, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.WEST);
            }
        }
 /// <summary>
 /// Constructor.  The major objects used in editing are passed in, but may not be required for all actions. </summary>
 /// <param name="editorJFrame"> the controlling editor window (e.g., to allow popup dialogs to position) </param>
 /// <param name="editorComponent"> the graphical editor component that renders the network, which does some internal
 /// optimized data management </param>
 /// <param name="network"> the network that will be manipulated, although subsets of the network may be passed in to
 /// specific methods </param>
 public StateMod_Network_EditorToolkit(StateMod_Network_JFrame editorJFrame, StateMod_Network_JComponent editorJComponent, StateMod_NodeNetwork network)
 {
     this.__editorJFrame     = editorJFrame;
     this.__editorJComponent = editorJComponent;
     this.__network          = network;
 }
        /// <summary>
        /// Write list files for the main station lists.  These can then be used with
        /// list-based commands in StateDMI.
        /// The user is prompted for a list file name.
        /// </summary>
        protected internal virtual void writeListFiles()
        {
            string routine = "StateMod_Network_JComponent.writeListFiles";

            string       lastDirectorySelected = JGUIUtil.getLastFileDialogDirectory();
            JFileChooser fc = JFileChooserFactory.createJFileChooser(lastDirectorySelected);

            fc.setDialogTitle("Select Base Filename for List Files");
            SimpleFileFilter tff = new SimpleFileFilter("txt", "Text Files");

            fc.addChoosableFileFilter(tff);
            SimpleFileFilter csv_ff = new SimpleFileFilter("csv", "Comma-separated Values");

            fc.addChoosableFileFilter(csv_ff);
            fc.setFileFilter(csv_ff);
            fc.setDialogType(JFileChooser.SAVE_DIALOG);

            int retVal = fc.showSaveDialog(this.__editorJComponent);

            if (retVal != JFileChooser.APPROVE_OPTION)
            {
                return;
            }

            string currDir = (fc.getCurrentDirectory()).ToString();

            if (!currDir.Equals(lastDirectorySelected, StringComparison.OrdinalIgnoreCase))
            {
                JGUIUtil.setLastFileDialogDirectory(currDir);
            }
            string filename = fc.getSelectedFile().getPath();

            // Station types...

            int[] types = new int[] { -1, HydrologyNode.NODE_TYPE_FLOW, HydrologyNode.NODE_TYPE_DIV, HydrologyNode.NODE_TYPE_DIV_AND_WELL, HydrologyNode.NODE_TYPE_PLAN, HydrologyNode.NODE_TYPE_RES, HydrologyNode.NODE_TYPE_ISF, HydrologyNode.NODE_TYPE_WELL, HydrologyNode.NODE_TYPE_OTHER };

            /* TODO SAM 2006-01-03 Just use node abbreviations from network
             * // Suffix for output, to be added to file basename...
             *
             * String[] nodetype_string = {
             *      "All",
             *      "StreamGage",
             *      "Diversion",
             *      "DiversionAndWell",
             *      "Plan",
             *      "Reservoir",
             *      "InstreamFlow",
             *      "Well",
             *      // TODO SAM 2006-01-03 Evaluate similar to node type above.
             *      //"StreamEstimate",
             *      "Other"
             * };
             */

            // Put the extension on the file (user may or may not have added)...

            if (fc.getFileFilter() == tff)
            {
                filename = IOUtil.enforceFileExtension(filename, "txt");
            }
            else if (fc.getFileFilter() == csv_ff)
            {
                filename = IOUtil.enforceFileExtension(filename, "csv");
            }

            // Now get the base name and remaining extension so that the basename can be adjusted below...

            int    lastIndex = filename.LastIndexOf(".", StringComparison.Ordinal);
            string front     = filename.Substring(0, lastIndex);
            string end       = filename.Substring((lastIndex + 1), filename.Length - (lastIndex + 1));

            string outputFilename   = null;
            IList <HydrologyNode> v = null;

            string warning = "";

            string[] comments = null;
            for (int i = 0; i < types.Length; i++)
            {
                v = this.__editorJComponent.getNodesForType(types[i]);

                if (v != null && v.Count > 0)
                {
                    comments = new string[1];
                    if (types[i] == -1)
                    {
                        comments[0]    = "The following list contains data for all node types.";
                        outputFilename = front + "_All." + end;
                    }
                    else
                    {
                        comments[0] = "The following list contains data for the following node type:  " + HydrologyNode.getTypeString(types[i], HydrologyNode.ABBREVIATION) +
                                      " (" + HydrologyNode.getTypeString(types[i], HydrologyNode.FULL) + ")";
                        outputFilename = front + "_" + HydrologyNode.getTypeString(types[i], HydrologyNode.ABBREVIATION) + "." + end;
                    }

                    try
                    {
                        StateMod_NodeNetwork.writeListFile(outputFilename, ",", false, v, comments, false);
                    }
                    catch (Exception e)
                    {
                        Message.printWarning(3, routine, e);
                        warning += "\nUnable to create list file \"" + outputFilename + "\"";
                    }
                }
            }
            // TODO SAM 2006-01-03 Write at level 1 since this is currently triggered from an
            // interactive action.  However, may need to change if executed in batch mode.
            if (warning.Length > 0)
            {
                Message.printWarning(1, routine, warning);
            }
        }
 /// <summary>
 /// Sets the HydrologyNodeNetwork to use. </summary>
 /// <param name="network"> the network to be drawn. </param>
 public virtual void setNetwork(StateMod_NodeNetwork network)
 {
     __network = network;
 }
        /// <summary>
        /// Draws the network between all the nodes.
        /// </summary>
        private void drawNetworkLines()
        {
            bool dash = false;

            float[] dashes = new float[] { 5f, 4f };
            float   offset = 0;

            double[]      x          = new double[2];
            double[]      y          = new double[2];
            HydrologyNode ds         = null;
            HydrologyNode dsRealNode = null;
            HydrologyNode holdNode   = null;
            HydrologyNode holdNode2  = null;
            HydrologyNode node       = null;
            HydrologyNode nodeTop    = __network.getMostUpstreamNode();

            GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);

            for (node = nodeTop; node != null; node = StateMod_NodeNetwork.getDownstreamNode(node, StateMod_NodeNetwork.POSITION_COMPUTATIONAL))
            {
                // move ahead and skip and blank or unknown nodes (which won't
                // be drawn, anyways -- check buildNodeArray()), so that
                // connections are only between visible nodes
                if (holdNode == node)
                {
                    GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);
                    return;
                }
                holdNode2 = node;
                while (node.getType() == HydrologyNode.NODE_TYPE_UNKNOWN)
                {
                    node = StateMod_NodeNetwork.getDownstreamNode(node, StateMod_NodeNetwork.POSITION_COMPUTATIONAL);
                    if (node == null || node == holdNode2)
                    {
                        GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);
                        return;
                    }
                }

                ds = node.getDownstreamNode();
                if (ds == null || node.getType() == HydrologyNode.NODE_TYPE_END)
                {
                    GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);
                    return;
                }

                dsRealNode = StateMod_NodeNetwork.findNextRealOrXConfluenceDownstreamNode(node);

                // if the confluence of the reach (as opposed to a trib coming
                // in) then this is the last real node in disappearing stream.
                // Use the end node for the downstream node.
                dash = false;
                if (dsRealNode == StateMod_NodeNetwork.getDownstreamNode(node, StateMod_NodeNetwork.POSITION_REACH))
                {
                    dash = true;
                }

                // move ahead and skip and blank or unknown nodes (which won't
                // be drawn, anyways -- check buildNodeArray()), so that
                // connections are only between visible nodes
                holdNode2 = ds;
                while (ds.getType() == HydrologyNode.NODE_TYPE_UNKNOWN)
                {
                    ds = ds.getDownstreamNode();
                    if (ds == null || ds == holdNode2)
                    {
                        GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);
                        return;
                    }
                }

                x[0] = node.getX();
                y[0] = node.getY();
                x[1] = ds.getX();
                y[1] = ds.getY();

                GRDrawingAreaUtil.setColor(__drawingArea, GRColor.black);
                GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);

                if (dash)
                {
                    __drawingArea.setFloatLineDash(dashes, offset);
                    GRDrawingAreaUtil.drawLine(__drawingArea, x, y);
                    __drawingArea.setFloatLineDash(null, (float)0);
                }
                else
                {
                    GRDrawingAreaUtil.drawLine(__drawingArea, x, y);
                }
                holdNode = node;
            }
            GRDrawingAreaUtil.setLineWidth(__drawingArea, 1);
        }
        /// <summary>
        /// Responds to action events. </summary>
        /// <param name="event"> the ActionEvent that happened. </param>
        public virtual void actionPerformed(ActionEvent @event)
        {
            string action = @event.getActionCommand();
            object o      = @event.getSource();

            if (action.Equals(__BUTTON_CANCEL))
            {
                dispose();
            }
            else if (action.Equals(__BUTTON_OK))
            {
                int    type = -1;
                string s    = __nodeTypeComboBox.getSelected();
                if (s.Equals(__NODE_CONFLUENCE))
                {
                    type = HydrologyNode.NODE_TYPE_CONFLUENCE;
                }
                else if (s.Equals(__NODE_DIVERSION))
                {
                    type = HydrologyNode.NODE_TYPE_DIV;
                }
                else if (s.Equals(__NODE_DIVERSION_AND_WELL))
                {
                    type = HydrologyNode.NODE_TYPE_DIV_AND_WELL;
                }
                else if (s.Equals(__NODE_END))
                {
                    type = HydrologyNode.NODE_TYPE_END;
                }
                else if (s.Equals(__NODE_INSTREAM_FLOW))
                {
                    type = HydrologyNode.NODE_TYPE_ISF;
                }
                else if (s.Equals(__NODE_OTHER))
                {
                    type = HydrologyNode.NODE_TYPE_OTHER;
                }
                else if (s.Equals(__NODE_PLAN))
                {
                    type = HydrologyNode.NODE_TYPE_PLAN;
                }
                else if (s.Equals(__NODE_RESERVOIR))
                {
                    type = HydrologyNode.NODE_TYPE_RES;
                }
                else if (s.Equals(__NODE_STREAMFLOW))
                {
                    type = HydrologyNode.NODE_TYPE_FLOW;
                }
                else if (s.Equals(__NODE_WELL))
                {
                    type = HydrologyNode.NODE_TYPE_WELL;
                }
                else if (s.Equals(__NODE_XCONFLUENCE))
                {
                    type = HydrologyNode.NODE_TYPE_XCONFLUENCE;
                }

                StateMod_NodeNetwork network = __parent.getNetwork();

                string up = __upstreamIDComboBox.getSelected().Trim();
                if (up.Equals("[none]"))
                {
                    up = null;
                }
                network.addNode(__nodeNameJTextField.getText().Trim(), type, up, __downstreamIDJTextField.getText().Trim(), __naturalFlowJCheckBox.isSelected(), __importJCheckBox.isSelected());
                __parent.setNetwork(network, true, true);
                //		__parent.resetNodeSize();
                __parent.endAddNode();
                dispose();
            }
            else if (o == __nodeTypeComboBox)
            {
                string selected = __nodeTypeComboBox.getSelected();

                if (!selected.Equals(__NODE_END))
                {
                    __naturalFlowJCheckBox.setEnabled(true);
                    __importJCheckBox.setEnabled(true);
                }
            }
        }