JAL-2360 refactoring for JalviewColourScheme enum,
[jalview.git] / src / jalview / schemes / UserColourScheme.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.schemes;
22
23 import jalview.datamodel.AnnotatedCollectionI;
24 import jalview.datamodel.SequenceCollectionI;
25 import jalview.datamodel.SequenceI;
26 import jalview.util.ColorUtils;
27
28 import java.awt.Color;
29 import java.util.Map;
30 import java.util.StringTokenizer;
31
32 public class UserColourScheme extends ResidueColourScheme
33 {
34   Color[] lowerCaseColours;
35
36   protected String schemeName;
37
38   public UserColourScheme()
39   {
40     super(ResidueProperties.aaIndex);
41   }
42
43   public UserColourScheme(Color[] newColors)
44   {
45     super(ResidueProperties.aaIndex);
46     colors = newColors;
47   }
48
49   @Override
50   public ColourSchemeI applyTo(AnnotatedCollectionI sg,
51           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
52   {
53     UserColourScheme usc = new UserColourScheme(colors);
54     if (lowerCaseColours != null)
55     {
56       usc.schemeName = new String(schemeName);
57       usc.lowerCaseColours = new Color[lowerCaseColours.length];
58       System.arraycopy(lowerCaseColours, 0, usc.lowerCaseColours, 0,
59               lowerCaseColours.length);
60     }
61     return usc;
62   }
63
64   public UserColourScheme(String colour)
65   {
66     super(ResidueProperties.aaIndex);
67     Color col = ColorUtils.parseColourString(colour);
68
69     if (col == null)
70     {
71       System.out.println("Making colour from name: " + colour);
72       col = ColorUtils.createColourFromName(colour);
73     }
74
75     colors = new Color[24];
76     for (int i = 0; i < 24; i++)
77     {
78       colors[i] = col;
79     }
80     schemeName = colour;
81   }
82
83   public Color[] getColours()
84   {
85     return colors;
86   }
87
88   public Color[] getLowerCaseColours()
89   {
90     return lowerCaseColours;
91   }
92
93   public void setName(String name)
94   {
95     schemeName = name;
96   }
97
98   public String getName()
99   {
100     return schemeName;
101   }
102
103   /**
104    * Parse and save residue colours specified as (for example)
105    * 
106    * <pre>
107    *     D,E=red; K,R,H=0022FF; c=100,50,75
108    * </pre>
109    * 
110    * This should be a semi-colon separated list of colours, which may be defined
111    * by colour name, hex value or comma-separated RGB triple. Each colour is
112    * defined for a comma-separated list of amino acid single letter codes. (Note
113    * that this also allows a colour scheme to be defined for ACGT, but not for
114    * U.)
115    * 
116    * @param paramValue
117    */
118   public void parseAppletParameter(String paramValue)
119   {
120     // TODO: need a function to generate appletParameter colour string from a
121     // UCS
122     StringTokenizer st = new StringTokenizer(paramValue, ";");
123     StringTokenizer st2;
124     String token = null, colour, residues;
125     try
126     {
127       while (st.hasMoreElements())
128       {
129         token = st.nextToken().trim();
130         residues = token.substring(0, token.indexOf("="));
131         colour = token.substring(token.indexOf("=") + 1);
132
133         st2 = new StringTokenizer(residues, " ,");
134         while (st2.hasMoreTokens())
135         {
136           String residue = st2.nextToken();
137
138           int colIndex = ResidueProperties.aaIndex[residue.charAt(0)];
139           if (colIndex == -1)
140           {
141             continue;
142           }
143
144           if (residue.equalsIgnoreCase("lowerCase"))
145           {
146             if (lowerCaseColours == null)
147             {
148               lowerCaseColours = new Color[23];
149             }
150             for (int i = 0; i < 23; i++)
151             {
152               if (lowerCaseColours[i] == null)
153               {
154                 lowerCaseColours[i] = ColorUtils.parseColourString(colour);
155               }
156             }
157
158             continue;
159           }
160
161           if (residue.equals(residue.toLowerCase()))
162           {
163             if (lowerCaseColours == null)
164             {
165               lowerCaseColours = new Color[23];
166             }
167             lowerCaseColours[colIndex] = ColorUtils.parseColourString(colour);
168           }
169           else
170           {
171             colors[colIndex] = ColorUtils.parseColourString(colour);
172           }
173         }
174       }
175     } catch (Exception ex)
176     {
177       System.out.println("Error parsing userDefinedColours:\n" + token
178               + "\n" + ex);
179     }
180
181   }
182
183   @Override
184   public Color findColour(char c, int j, SequenceI seq)
185   {
186     Color currentColour;
187     int index = ResidueProperties.aaIndex[c];
188
189     if ((threshold == 0) || aboveThreshold(c, j))
190     {
191       if (lowerCaseColours != null && 'a' <= c && c <= 'z')
192       {
193         currentColour = lowerCaseColours[index];
194       }
195       else
196       {
197         currentColour = colors[index];
198       }
199     }
200     else
201     {
202       currentColour = Color.white;
203     }
204
205     if (conservationColouring)
206     {
207       currentColour = applyConservation(currentColour, j);
208     }
209
210     return currentColour;
211   }
212
213   public void setLowerCaseColours(Color[] lcolours)
214   {
215     lowerCaseColours = lcolours;
216   }
217
218   /**
219    * Returns the colour for the given residue character. If the residue is
220    * lower-case, and there is a specific colour defined for lower case, that
221    * colour is returned, else the colour for the upper case residue.
222    */
223   @Override
224   public Color findColour(char c)
225   {
226     if ('a' <= c && c <= 'z' && lowerCaseColours != null)
227     {
228       Color colour = lowerCaseColours[symbolIndex[c]];
229       if (colour != null)
230       {
231         return colour;
232       }
233     }
234     return super.findColour(c);
235   }
236
237   /**
238    * Answers the customised name of the colour scheme, if it has one, else
239    * "User Defined"
240    */
241   @Override
242   public String getSchemeName()
243   {
244     if (schemeName != null && schemeName.length() > 0)
245     {
246       return schemeName;
247     }
248     return JalviewColourScheme.UserDefined.toString();
249   }
250
251 }