inprogress
[jalview.git] / forester / java / src / org / forester / phylogeny / data / NodeVisualData.java
1 \r
2 package org.forester.phylogeny.data;\r
3 \r
4 import java.awt.Color;\r
5 import java.awt.Font;\r
6 import java.io.IOException;\r
7 import java.io.Writer;\r
8 import java.util.ArrayList;\r
9 import java.util.List;\r
10 \r
11 import org.forester.phylogeny.data.Property.AppliesTo;\r
12 import org.forester.util.ForesterUtil;\r
13 \r
14 public final class NodeVisualData implements PhylogenyData {\r
15 \r
16     public static final String APTX_VISUALIZATION_REF = "style:";\r
17     public static final String FONT_COLOR_REF         = APTX_VISUALIZATION_REF + "font_color";\r
18     public static final String FONT_COLOR_TYPE        = "xsd:token";\r
19     public static final String FONT_REF               = APTX_VISUALIZATION_REF + "font";\r
20     public static final String FONT_SIZE_REF          = APTX_VISUALIZATION_REF + "font_size";\r
21     public static final String FONT_SIZE_TYPE         = "xsd:unsignedByte";\r
22     public static final String FONT_STYLE_BOLD        = "bold";\r
23     public static final String FONT_STYLE_BOLD_ITALIC = "bold_italic";\r
24     public static final String FONT_STYLE_ITALIC      = "italic";\r
25     public static final String FONT_STYLE_PLAIN       = "plain";\r
26     public static final String FONT_STYLE_REF         = APTX_VISUALIZATION_REF + "font_style";\r
27     public static final String FONT_STYLE_TYPE        = "xsd:token";\r
28     public static final String FONT_TYPE              = "xsd:token";\r
29     public static final String NODE_BORDER_COLOR_REF  = APTX_VISUALIZATION_REF + "border_color";\r
30     public static final String NODE_BORDER_COLOR_TYPE = "xsd:token";\r
31     public static final String NODE_FILL_COLOR_REF    = APTX_VISUALIZATION_REF + "fill_color";\r
32     public static final String NODE_FILL_COLOR_TYPE   = "xsd:token";\r
33     public static final String NODE_FILL_GRADIENT     = "gradient";\r
34     public static final String NODE_FILL_NONE         = "none";\r
35     public static final String NODE_FILL_SOLID        = "solid";\r
36     public static final String NODE_FILL_TYPE_REF     = APTX_VISUALIZATION_REF + "fill_type";\r
37     public static final String NODE_FILL_TYPE_TYPE    = "xsd:token";\r
38     public static final String NODE_SHAPE_CIRCLE      = "cicle";\r
39     public static final String NODE_SHAPE_RECTANGLE   = "rectangle";\r
40     public static final String NODE_SHAPE_REF         = APTX_VISUALIZATION_REF + "shape";\r
41     public static final String NODE_SHAPE_TYPE        = "xsd:token";\r
42     public static final String NODE_SIZE_REF          = APTX_VISUALIZATION_REF + "size";\r
43     public static final String NODE_SIZE_TYPE         = "xsd:float";\r
44     public static final String NODE_TRANSPARENCY_REF  = APTX_VISUALIZATION_REF + "transparency";\r
45     public static final String NODE_TRANSPARENCY_TYPE = "xsd:float";\r
46     private static final byte  DEFAULT_FONT_SIZE      = -1;\r
47     private static final int   DEFAULT_SIZE           = -1;\r
48     private static final int   DEFAULT_TRANSPARENCY   = -1;\r
49     private Color              _border_color;\r
50     private Color              _fill_color;\r
51     private NodeFill           _fill_type;\r
52     private Font               _font;\r
53     private Color              _font_color;\r
54     private String             _font_name;\r
55     private byte               _font_size;\r
56     private FontType           _font_style;\r
57     private NodeShape          _shape;\r
58     private float              _size;\r
59     private float              _transparency;\r
60 \r
61     public NodeVisualData() {\r
62         init();\r
63     }\r
64 \r
65     public NodeVisualData( final String font_name,\r
66                            final FontType font_style,\r
67                            final byte font_size,\r
68                            final Color font_color,\r
69                            final NodeShape shape,\r
70                            final NodeFill fill_type,\r
71                            final Color border_color,\r
72                            final Color fill_color,\r
73                            final float size,\r
74                            final float transparency ) {\r
75         setFontName( font_name );\r
76         setFontStyle( font_style );\r
77         setFontSize( font_size );\r
78         setFontColor( font_color );\r
79         setShape( shape );\r
80         setFillType( fill_type );\r
81         setBorderColor( border_color );\r
82         setFillColor( fill_color );\r
83         setSize( size );\r
84         setTransparency( transparency );\r
85     }\r
86 \r
87     @Override\r
88     public final StringBuffer asSimpleText() {\r
89         return asText();\r
90     }\r
91 \r
92     @Override\r
93     public final StringBuffer asText() {\r
94         final StringBuffer sb = new StringBuffer();\r
95         return sb;\r
96     }\r
97 \r
98     @Override\r
99     public final PhylogenyData copy() {\r
100         return new NodeVisualData( !ForesterUtil.isEmpty( getFontName() ) ? new String( getFontName() ) : null,\r
101                                    getFontStyle(),\r
102                                    getFontSize(),\r
103                                    getFontColor() != null ? new Color( getFontColor().getRed(), getFontColor()\r
104                                            .getGreen(), getFontColor().getBlue() ) : null,\r
105                                    getShape(),\r
106                                    getFillType(),\r
107                                    getBorderColor() != null ? new Color( getBorderColor().getRed(), getBorderColor()\r
108                                            .getGreen(), getBorderColor().getBlue() ) : null,\r
109                                    getFillColor() != null ? new Color( getFillColor().getRed(), getFillColor()\r
110                                            .getGreen(), getFillColor().getBlue() ) : null,\r
111                                    getSize(),\r
112                                    getTransparency() );\r
113     }\r
114 \r
115     public final Color getBorderColor() {\r
116         return _border_color;\r
117     }\r
118 \r
119     public final Color getFillColor() {\r
120         return _fill_color;\r
121     }\r
122 \r
123     public final NodeFill getFillType() {\r
124         return _fill_type;\r
125     }\r
126 \r
127     public final Font getFont() {\r
128         if ( _font != null ) {\r
129             return _font;\r
130         }\r
131         else if ( !ForesterUtil.isEmpty( getFontName() ) ) {\r
132             _font = new Font( getFontName(), getFontStyleInt(), getFontSize() );\r
133             return _font;\r
134         }\r
135         return null;\r
136     }\r
137 \r
138     public final Color getFontColor() {\r
139         return _font_color;\r
140     }\r
141 \r
142     public final String getFontName() {\r
143         return _font_name;\r
144     }\r
145 \r
146     public final byte getFontSize() {\r
147         return _font_size;\r
148     }\r
149 \r
150     public final FontType getFontStyle() {\r
151         return _font_style;\r
152     }\r
153 \r
154     public final int getFontStyleInt() {\r
155         if ( getFontStyle() == FontType.BOLD ) {\r
156             return Font.BOLD;\r
157         }\r
158         else if ( getFontStyle() == FontType.ITALIC ) {\r
159             return Font.ITALIC;\r
160         }\r
161         else if ( getFontStyle() == FontType.BOLD_ITALIC ) {\r
162             return Font.BOLD + Font.ITALIC;\r
163         }\r
164         return Font.PLAIN;\r
165     }\r
166 \r
167     public final NodeShape getShape() {\r
168         return _shape;\r
169     }\r
170 \r
171     public final float getSize() {\r
172         return _size;\r
173     }\r
174 \r
175     public final float getTransparency() {\r
176         return _transparency;\r
177     }\r
178 \r
179     public final boolean isEmpty() {\r
180         return ( ForesterUtil.isEmpty( getFontName() ) && ( getFontStyle() == FontType.PLAIN )\r
181                 && ( getFontSize() == DEFAULT_FONT_SIZE ) && ( getFontColor() == null )\r
182                 && ( getShape() == NodeShape.DEFAULT ) && ( getFillType() == NodeFill.DEFAULT )\r
183                 && ( getBorderColor() == null ) && ( getFillColor() == null ) && ( getSize() == DEFAULT_SIZE ) && ( getTransparency() == DEFAULT_TRANSPARENCY ) );\r
184     }\r
185 \r
186     @Override\r
187     public final boolean isEqual( final PhylogenyData data ) {\r
188         throw new UnsupportedOperationException();\r
189     }\r
190 \r
191     public void parseProperty( final Property prop ) {\r
192         if ( prop.getRef().equals( FONT_REF ) ) {\r
193             setFontName( prop.getValue().trim() );\r
194         }\r
195         else if ( prop.getRef().equals( FONT_SIZE_REF ) ) {\r
196             int s = -1;\r
197             try {\r
198                 s = Integer.parseInt( prop.getValue() );\r
199             }\r
200             catch ( final NumberFormatException e ) {\r
201                 return;\r
202             }\r
203             if ( ( s >= 0 ) && ( s < Byte.MAX_VALUE ) ) {\r
204                 setFontSize( s );\r
205             }\r
206         }\r
207         else if ( prop.getRef().equals( FONT_STYLE_REF ) ) {\r
208             setFontStyle( prop.getValue() );\r
209         }\r
210         else if ( prop.getRef().equals( FONT_COLOR_REF ) ) {\r
211             try {\r
212                 setFontColor( Color.decode( prop.getValue() ) );\r
213             }\r
214             catch ( final NumberFormatException e ) {\r
215                 return;\r
216             }\r
217         }\r
218     }\r
219 \r
220     public final void setBorderColor( final Color border_color ) {\r
221         _border_color = border_color;\r
222     }\r
223 \r
224     public final void setFillColor( final Color fill_color ) {\r
225         _fill_color = fill_color;\r
226     }\r
227 \r
228     public final void setFillType( final NodeFill fill_type ) {\r
229         _fill_type = fill_type;\r
230     }\r
231 \r
232     public final void setFontColor( final Color font_color ) {\r
233         _font_color = font_color;\r
234     }\r
235 \r
236     public final void setFontName( final String font_name ) {\r
237         if ( !ForesterUtil.isEmpty( font_name ) ) {\r
238             _font_name = font_name;\r
239         }\r
240         else {\r
241             _font_name = null;\r
242         }\r
243         _font = null;\r
244     }\r
245 \r
246     public final void setFontSize( final int font_size ) {\r
247         if ( ( font_size != DEFAULT_FONT_SIZE ) && ( font_size < 0 ) ) {\r
248             throw new IllegalArgumentException( "negative font size: " + font_size );\r
249         }\r
250         else if ( font_size > Byte.MAX_VALUE ) {\r
251             throw new IllegalArgumentException( "font size is too large: " + font_size );\r
252         }\r
253         _font_size = ( byte ) font_size;\r
254         _font = null;\r
255     }\r
256 \r
257     public final void setFontStyle( final FontType font_style ) {\r
258         _font_style = font_style;\r
259         _font = null;\r
260     }\r
261 \r
262     public final void setFontStyle( final int font_style ) {\r
263         if ( ( font_style == ( Font.BOLD + Font.ITALIC ) ) ) {\r
264             setFontStyle( FontType.BOLD_ITALIC );\r
265         }\r
266         else if ( font_style == Font.ITALIC ) {\r
267             setFontStyle( FontType.ITALIC );\r
268         }\r
269         else if ( font_style == Font.BOLD ) {\r
270             setFontStyle( FontType.BOLD );\r
271         }\r
272         else {\r
273             setFontStyle( FontType.PLAIN );\r
274         }\r
275     }\r
276 \r
277     public final void setFontStyle( final String font_style ) {\r
278         if ( font_style.equalsIgnoreCase( FONT_STYLE_BOLD ) ) {\r
279             setFontStyle( FontType.BOLD );\r
280         }\r
281         else if ( font_style.equalsIgnoreCase( FONT_STYLE_ITALIC ) ) {\r
282             setFontStyle( FontType.ITALIC );\r
283         }\r
284         else if ( font_style.equalsIgnoreCase( FONT_STYLE_BOLD_ITALIC ) ) {\r
285             setFontStyle( FontType.BOLD_ITALIC );\r
286         }\r
287         else {\r
288             setFontStyle( FontType.PLAIN );\r
289         }\r
290     }\r
291 \r
292     public final void setShape( final NodeShape shape ) {\r
293         _shape = shape;\r
294     }\r
295 \r
296     public final void setSize( final float size ) {\r
297         _size = size;\r
298     }\r
299 \r
300     public final void setTransparency( final float transparency ) {\r
301         _transparency = transparency;\r
302     }\r
303 \r
304     @Override\r
305     public final StringBuffer toNHX() {\r
306         throw new UnsupportedOperationException();\r
307     }\r
308 \r
309     @Override\r
310     public final void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {\r
311         for( final Property p : toProperties() ) {\r
312             p.toPhyloXML( writer, level, indentation );\r
313         }\r
314     }\r
315 \r
316     @Override\r
317     public final String toString() {\r
318         return asText().toString();\r
319     }\r
320 \r
321     private String colorToHex( final Color c ) {\r
322         return String.format( "#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue() );\r
323     }\r
324 \r
325     private final void init() {\r
326         setFontName( null );\r
327         setFontStyle( FontType.PLAIN );\r
328         setFontSize( DEFAULT_FONT_SIZE );\r
329         setFontColor( null );\r
330         setShape( NodeShape.DEFAULT );\r
331         setFillType( NodeFill.DEFAULT );\r
332         setBorderColor( null );\r
333         setFillColor( null );\r
334         setSize( DEFAULT_SIZE );\r
335         setTransparency( DEFAULT_TRANSPARENCY );\r
336         _font = null;\r
337     }\r
338 \r
339     private final List<Property> toProperties() {\r
340         final List<Property> properties = new ArrayList<Property>();\r
341         if ( !ForesterUtil.isEmpty( getFontName() ) ) {\r
342             properties.add( new Property( FONT_REF, getFontName(), "", FONT_TYPE, AppliesTo.NODE ) );\r
343         }\r
344         if ( getFontSize() != DEFAULT_FONT_SIZE ) {\r
345             properties.add( new Property( FONT_SIZE_REF,\r
346                                           String.valueOf( getFontSize() ),\r
347                                           "",\r
348                                           FONT_SIZE_TYPE,\r
349                                           AppliesTo.NODE ) );\r
350         }\r
351         if ( getFontStyle() != FontType.PLAIN ) {\r
352             String font_style = "";\r
353             if ( getFontStyle() == FontType.ITALIC ) {\r
354                 font_style = FONT_STYLE_ITALIC;\r
355             }\r
356             else if ( getFontStyle() == FontType.BOLD ) {\r
357                 font_style = FONT_STYLE_BOLD;\r
358             }\r
359             else if ( getFontStyle() == FontType.BOLD_ITALIC ) {\r
360                 font_style = FONT_STYLE_BOLD_ITALIC;\r
361             }\r
362             else {\r
363                 throw new RuntimeException( "unknown font style" + getShape() );\r
364             }\r
365             properties.add( new Property( FONT_STYLE_REF, font_style, "", FONT_STYLE_TYPE, AppliesTo.NODE ) );\r
366         }\r
367         if ( getFontColor() != null ) {\r
368             properties.add( new Property( FONT_COLOR_REF,\r
369                                           colorToHex( getFontColor() ),\r
370                                           "",\r
371                                           FONT_COLOR_TYPE,\r
372                                           AppliesTo.NODE ) );\r
373         }\r
374         //\r
375         if ( getShape() != NodeShape.DEFAULT ) {\r
376             String shape = null;\r
377             if ( getShape() == NodeShape.RECTANGLE ) {\r
378                 shape = NODE_SHAPE_RECTANGLE;\r
379             }\r
380             else if ( getShape() == NodeShape.CIRCLE ) {\r
381                 shape = NODE_SHAPE_CIRCLE;\r
382             }\r
383             else {\r
384                 throw new RuntimeException( "unknown node shape" + getShape() );\r
385             }\r
386             properties.add( new Property( NODE_SHAPE_REF, shape, "", NODE_SHAPE_TYPE, AppliesTo.NODE ) );\r
387         }\r
388         if ( getSize() != DEFAULT_SIZE ) {\r
389             properties.add( new Property( NODE_SIZE_REF,\r
390                                           String.valueOf( getSize() ),\r
391                                           "",\r
392                                           NODE_SIZE_TYPE,\r
393                                           AppliesTo.NODE ) );\r
394         }\r
395         if ( getFillColor() != null ) {\r
396             properties.add( new Property( NODE_FILL_COLOR_REF,\r
397                                           colorToHex( getFillColor() ),\r
398                                           "",\r
399                                           NODE_FILL_COLOR_TYPE,\r
400                                           AppliesTo.NODE ) );\r
401         }\r
402         if ( getBorderColor() != null ) {\r
403             properties.add( new Property( NODE_BORDER_COLOR_REF,\r
404                                           colorToHex( getBorderColor() ),\r
405                                           "",\r
406                                           NODE_BORDER_COLOR_TYPE,\r
407                                           AppliesTo.NODE ) );\r
408         }\r
409         if ( getFillType() != NodeFill.DEFAULT ) {\r
410             String fill = null;\r
411             if ( getFillType() == NodeFill.GRADIENT ) {\r
412                 fill = NODE_FILL_GRADIENT;\r
413             }\r
414             else if ( getFillType() == NodeFill.NONE ) {\r
415                 fill = NODE_FILL_NONE;\r
416             }\r
417             else if ( getFillType() == NodeFill.SOLID ) {\r
418                 fill = NODE_FILL_SOLID;\r
419             }\r
420             else {\r
421                 throw new RuntimeException( "unknown fill type " + getFillType() );\r
422             }\r
423             properties.add( new Property( NODE_FILL_TYPE_REF, fill, "", NODE_FILL_TYPE_TYPE, AppliesTo.NODE ) );\r
424         }\r
425         if ( getTransparency() != DEFAULT_TRANSPARENCY ) {\r
426             properties.add( new Property( NODE_TRANSPARENCY_REF,\r
427                                           String.valueOf( getTransparency() ),\r
428                                           "",\r
429                                           NODE_TRANSPARENCY_TYPE,\r
430                                           AppliesTo.NODE ) );\r
431         }\r
432         return properties;\r
433     }\r
434 \r
435     public enum FontType {\r
436         BOLD, BOLD_ITALIC, ITALIC, PLAIN\r
437     }\r
438 \r
439     public enum NodeFill {\r
440         DEFAULT, GRADIENT, NONE, SOLID\r
441     }\r
442 \r
443     public enum NodeShape {\r
444         CIRCLE, DEFAULT, RECTANGLE\r
445     }\r
446 }\r