JAL-2089 patch broken merge to master for Release 2.10.0b1
[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
27 import java.awt.Color;
28 import java.util.Map;
29 import java.util.StringTokenizer;
30
31 public class UserColourScheme extends ResidueColourScheme
32 {
33   Color[] lowerCaseColours;
34
35   protected String schemeName;
36
37   public UserColourScheme()
38   {
39     super(ResidueProperties.aaIndex);
40   }
41
42   public UserColourScheme(Color[] newColors)
43   {
44     super(ResidueProperties.aaIndex);
45     colors = newColors;
46   }
47
48   @Override
49   public ColourSchemeI applyTo(AnnotatedCollectionI sg,
50           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
51   {
52     UserColourScheme usc = new UserColourScheme(colors);
53     if (lowerCaseColours != null)
54     {
55       usc.schemeName = new String(schemeName);
56       usc.lowerCaseColours = new Color[lowerCaseColours.length];
57       System.arraycopy(lowerCaseColours, 0, usc.lowerCaseColours, 0,
58               lowerCaseColours.length);
59     }
60     return usc;
61   }
62
63   public UserColourScheme(String colour)
64   {
65     super(ResidueProperties.aaIndex);
66     Color col = getColourFromString(colour);
67
68     if (col == null)
69     {
70       System.out.println("Making colour from name: " + colour);
71       col = createColourFromName(colour);
72     }
73
74     colors = new Color[24];
75     for (int i = 0; i < 24; i++)
76     {
77       colors[i] = col;
78     }
79     schemeName = colour;
80   }
81
82   public Color[] getColours()
83   {
84     return colors;
85   }
86
87   public Color[] getLowerCaseColours()
88   {
89     return lowerCaseColours;
90   }
91
92   public void setName(String name)
93   {
94     schemeName = name;
95   }
96
97   public String getName()
98   {
99     return schemeName;
100   }
101
102   public static Color getColourFromString(String colour)
103   {
104     if (colour == null)
105     {
106       return null;
107     }
108     colour = colour.trim();
109
110     Color col = null;
111     try
112     {
113       int value = Integer.parseInt(colour, 16);
114       col = new Color(value);
115     } catch (NumberFormatException ex)
116     {
117     }
118
119     if (col == null)
120     {
121       col = ColourSchemeProperty.getAWTColorFromName(colour);
122     }
123
124     if (col == null)
125     {
126       try
127       {
128         java.util.StringTokenizer st = new java.util.StringTokenizer(
129                 colour, ",");
130         int r = Integer.parseInt(st.nextToken());
131         int g = Integer.parseInt(st.nextToken());
132         int b = Integer.parseInt(st.nextToken());
133         col = new Color(r, g, b);
134       } catch (Exception ex)
135       {
136       }
137     }
138
139     return col;
140
141   }
142
143   public static Color createColourFromName(String name)
144   {
145     int r, g, b;
146
147     int lsize = name.length();
148     int start = 0, end = lsize / 3;
149
150     int rgbOffset = Math.abs(name.hashCode() % 10) * 15;
151
152     r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
153     start = end;
154     end += lsize / 3;
155     if (end > lsize)
156     {
157       end = lsize;
158     }
159
160     g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
161
162     b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20;
163
164     Color color = new Color(r, g, b);
165
166     return color;
167   }
168
169   public void parseAppletParameter(String paramValue)
170   {
171     // TODO: need a function to generate appletParameter colour string from a
172     // UCS
173     StringTokenizer st = new StringTokenizer(paramValue, ";");
174     StringTokenizer st2;
175     String token = null, colour, residues;
176     try
177     {
178       while (st.hasMoreElements())
179       {
180         token = st.nextToken().trim();
181         residues = token.substring(0, token.indexOf("="));
182         colour = token.substring(token.indexOf("=") + 1);
183
184         st2 = new StringTokenizer(residues, " ,");
185         while (st2.hasMoreTokens())
186         {
187           token = st2.nextToken();
188
189           if (ResidueProperties.aaIndex[token.charAt(0)] == -1)
190           {
191             continue;
192           }
193
194           int colIndex = ResidueProperties.aaIndex[token.charAt(0)];
195
196           if (token.equalsIgnoreCase("lowerCase"))
197           {
198             if (lowerCaseColours == null)
199             {
200               lowerCaseColours = new Color[23];
201             }
202             for (int i = 0; i < 23; i++)
203             {
204               if (lowerCaseColours[i] == null)
205               {
206                 lowerCaseColours[i] = getColourFromString(colour);
207               }
208             }
209
210             continue;
211           }
212
213           if (token.equals(token.toLowerCase()))
214           {
215             if (lowerCaseColours == null)
216             {
217               lowerCaseColours = new Color[23];
218             }
219             lowerCaseColours[colIndex] = getColourFromString(colour);
220           }
221           else
222           {
223             colors[colIndex] = getColourFromString(colour);
224           }
225         }
226       }
227     } catch (Exception ex)
228     {
229       System.out.println("Error parsing userDefinedColours:\n" + token
230               + "\n" + ex);
231     }
232
233   }
234
235   @Override
236   public Color findColour(char c, int j, SequenceI seq)
237   {
238     Color currentColour;
239     int index = ResidueProperties.aaIndex[c];
240
241     if ((threshold == 0) || aboveThreshold(c, j))
242     {
243       if (lowerCaseColours != null && 'a' <= c && c <= 'z')
244       {
245         currentColour = lowerCaseColours[index];
246       }
247       else
248       {
249         currentColour = colors[index];
250       }
251     }
252     else
253     {
254       currentColour = Color.white;
255     }
256
257     if (conservationColouring)
258     {
259       currentColour = applyConservation(currentColour, j);
260     }
261
262     return currentColour;
263   }
264
265   public void setLowerCaseColours(Color[] lcolours)
266   {
267     lowerCaseColours = lcolours;
268   }
269
270 }