merge from 2_4_Release branch
[jalview.git] / src / jalview / datamodel / BinaryNode.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.datamodel;
20
21 /**
22  * DOCUMENT ME!
23  * 
24  * @author $author$
25  * @version $Revision$
26  */
27 public class BinaryNode
28 {
29   Object element;
30
31   String name;
32
33   BinaryNode left;
34
35   BinaryNode right;
36
37   BinaryNode parent;
38
39   /** DOCUMENT ME!! */
40   public int bootstrap;
41
42   /**
43    * Creates a new BinaryNode object.
44    */
45   public BinaryNode()
46   {
47     left = right = parent = null;
48     bootstrap = 0;
49   }
50
51   /**
52    * Creates a new BinaryNode object.
53    * 
54    * @param element
55    *                DOCUMENT ME!
56    * @param parent
57    *                DOCUMENT ME!
58    * @param name
59    *                DOCUMENT ME!
60    */
61   public BinaryNode(Object element, BinaryNode parent, String name)
62   {
63     this.element = element;
64     this.parent = parent;
65     this.name = name;
66
67     left = right = null;
68   }
69
70   /**
71    * DOCUMENT ME!
72    * 
73    * @return DOCUMENT ME!
74    */
75   public Object element()
76   {
77     return element;
78   }
79
80   /**
81    * DOCUMENT ME!
82    * 
83    * @param v
84    *                DOCUMENT ME!
85    * 
86    * @return DOCUMENT ME!
87    */
88   public Object setElement(Object v)
89   {
90     return element = v;
91   }
92
93   /**
94    * DOCUMENT ME!
95    * 
96    * @return DOCUMENT ME!
97    */
98   public BinaryNode left()
99   {
100     return left;
101   }
102
103   /**
104    * DOCUMENT ME!
105    * 
106    * @param n
107    *                DOCUMENT ME!
108    * 
109    * @return DOCUMENT ME!
110    */
111   public BinaryNode setLeft(BinaryNode n)
112   {
113     return left = n;
114   }
115
116   /**
117    * DOCUMENT ME!
118    * 
119    * @return DOCUMENT ME!
120    */
121   public BinaryNode right()
122   {
123     return right;
124   }
125
126   /**
127    * DOCUMENT ME!
128    * 
129    * @param n
130    *                DOCUMENT ME!
131    * 
132    * @return DOCUMENT ME!
133    */
134   public BinaryNode setRight(BinaryNode n)
135   {
136     return right = n;
137   }
138
139   /**
140    * DOCUMENT ME!
141    * 
142    * @return DOCUMENT ME!
143    */
144   public BinaryNode parent()
145   {
146     return parent;
147   }
148
149   /**
150    * DOCUMENT ME!
151    * 
152    * @param n
153    *                DOCUMENT ME!
154    * 
155    * @return DOCUMENT ME!
156    */
157   public BinaryNode setParent(BinaryNode n)
158   {
159     return parent = n;
160   }
161
162   /**
163    * DOCUMENT ME!
164    * 
165    * @return DOCUMENT ME!
166    */
167   public boolean isLeaf()
168   {
169     return (left == null) && (right == null);
170   }
171
172   /**
173    * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children of
174    * this node (removing any old references) a null parameter DOES NOT mean that
175    * the pointer to the corresponding child node is set to NULL - you should use
176    * setChild(null), or detach() for this.
177    * 
178    */
179   public void SetChildren(BinaryNode leftchild, BinaryNode rightchild)
180   {
181     if (leftchild != null)
182     {
183       this.setLeft(leftchild);
184       leftchild.detach();
185       leftchild.setParent(this);
186     }
187
188     if (rightchild != null)
189     {
190       this.setRight(rightchild);
191       rightchild.detach();
192       rightchild.setParent(this);
193     }
194   }
195
196   /**
197    * Detaches the node from the binary tree, along with all its child nodes.
198    * 
199    * @return BinaryNode The detached node.
200    */
201   public BinaryNode detach()
202   {
203     if (this.parent != null)
204     {
205       if (this.parent.left == this)
206       {
207         this.parent.left = null;
208       }
209       else
210       {
211         if (this.parent.right == this)
212         {
213           this.parent.right = null;
214         }
215       }
216     }
217
218     this.parent = null;
219
220     return this;
221   }
222
223   /**
224    * Traverses up through the tree until a node with a free leftchild is
225    * discovered.
226    * 
227    * @return BinaryNode
228    */
229   public BinaryNode ascendLeft()
230   {
231     BinaryNode c = this;
232
233     do
234     {
235       c = c.parent();
236     } while ((c != null) && (c.left() != null) && !c.left().isLeaf());
237
238     return c;
239   }
240
241   /**
242    * Traverses up through the tree until a node with a free rightchild is
243    * discovered. Jalview builds trees by descent on the left, so this may be
244    * unused.
245    * 
246    * @return BinaryNode
247    */
248   public BinaryNode ascendRight()
249   {
250     BinaryNode c = this;
251
252     do
253     {
254       c = c.parent();
255     } while ((c != null) && (c.right() != null) && !c.right().isLeaf());
256
257     return c;
258   }
259
260   /**
261    * DOCUMENT ME!
262    * 
263    * @param name
264    *                DOCUMENT ME!
265    */
266   public void setName(String name)
267   {
268     this.name = name;
269   }
270
271   /**
272    * DOCUMENT ME!
273    * 
274    * @return DOCUMENT ME!
275    */
276   public String getName()
277   {
278     return this.name;
279   }
280
281   /**
282    * DOCUMENT ME!
283    * 
284    * @param boot
285    *                DOCUMENT ME!
286    */
287   public void setBootstrap(int boot)
288   {
289     this.bootstrap = boot;
290   }
291
292   /**
293    * DOCUMENT ME!
294    * 
295    * @return DOCUMENT ME!
296    */
297   public int getBootstrap()
298   {
299     return bootstrap;
300   }
301 }