package org.iplantc.phyloviewer.viewer.client.style;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.iplantc.phyloviewer.shared.parsers.CSVParser;
import org.iplantc.phyloviewer.shared.model.INode;
import org.iplantc.phyloviewer.shared.render.Defaults;
import org.iplantc.phyloviewer.shared.render.style.CompositeStyle;
import org.iplantc.phyloviewer.shared.render.style.IBranchStyle;
import org.iplantc.phyloviewer.shared.render.style.IGlyphStyle;
import org.iplantc.phyloviewer.shared.render.style.ILabelStyle;
import org.iplantc.phyloviewer.shared.render.style.INodeStyle;
import org.iplantc.phyloviewer.shared.render.style.IStyleMap;
import org.iplantc.phyloviewer.shared.render.style.IStyle;
/**
* Stores node styles indexed by label
*/
public class StyleByLabel implements IStyleMap
{
HashMap<String, IStyle> map = new HashMap<String,IStyle>();
@Override
public IStyle get(INode node)
{
return map.get(node.getLabel());
}
@Override
public void put(INode node, IStyle style)
{
map.put(node.getLabel(), style);
}
public void clear()
{
map.clear();
}
/**
* Adds style mappings based on a string of comma-separated values.
* <pre>
* 1st column: node label
* 2nd column: element (one of NODE, BRANCH, GLYPH, LABEL)
* 3rd column: feature (one of STROKE, FILL, WIDTH)
* 4th column: value
* FILL and STROKE values should be a color as defined in http://dev.w3.org/html5/canvas-api/canvas-2d-api.html#serialization-of-a-color
* WIDTH values should be a positive number
* any value that contains a comma should be quoted
* </pre>
* @see Element
* @see Feature
*/
public void put(String csv)
{
if (csv == null || csv.isEmpty())
{
clear();
return;
}
List<String[]> rows = new ArrayList<String[]>();
CSVParser parser = new CSVParser();
String[] lines = csv.split("\n");
try
{
for (String line : lines)
{
rows.add(parser.parseLine(line));
}
}
catch(IOException e1)
{
throw new IllegalArgumentException("Unable to parse CSV string.", e1);
}
for (int i = 0; i < rows.size(); i++)
{
String[] row = rows.get(i);
IStyle currentNodeStyle = lazyGet(row[0]);
try
{
this.setElementStyle(currentNodeStyle, row[1], row[2], row[3]);
}
catch(NumberFormatException e)
{
Logger.getLogger("").log(Level.WARNING, "NumberFormatException in line " + i, e);
}
catch(IllegalArgumentException e)
{
Logger.getLogger("").log(Level.WARNING, "Bad element or feature name in line " + i, e);
}
}
}
private void setElementStyle(IStyle style,String type,String feature,String value) {
if(type.equalsIgnoreCase("node"))
{
this.setNodeStyleValue(style.getNodeStyle(),feature,value);
}
else if(type.equalsIgnoreCase("branch"))
{
this.setBranchStyleValue(style.getBranchStyle(),feature,value);
}
else if(type.equalsIgnoreCase("glyph"))
{
this.setGlyphStyleValue(style.getGlyphStyle(),feature,value);
}
else if(type.equalsIgnoreCase("label"))
{
this.setLabelStyleValue(style.getLabelStyle(),feature,value);
}
}
private void setLabelStyleValue(ILabelStyle labelStyle, String feature, String value) {
if(feature.equalsIgnoreCase("fill") || feature.equalsIgnoreCase("stroke") || feature.equalsIgnoreCase("color")) {
//TODO check if value is a valid color string
labelStyle.setColor(value);
}
}
private void setGlyphStyleValue(IGlyphStyle glyphStyle, String feature, String value) {
if(feature.equalsIgnoreCase("stroke")) {
//TODO check if value is a valid color string
glyphStyle.setStrokeColor(value);
}
else if(feature.equalsIgnoreCase("fill")) {
//TODO check if value is a valid color string
glyphStyle.setFillColor(value);
}
else if(feature.equalsIgnoreCase("width")) {
double width = Double.parseDouble(value);
glyphStyle.setLineWidth(width);
}
}
private void setBranchStyleValue(IBranchStyle branchStyle, String feature, String value) {
if(feature.equalsIgnoreCase("stroke")) {
//TODO check if value is a valid color string
branchStyle.setStrokeColor(value);
}
else if(feature.equalsIgnoreCase("width")) {
double width = Double.parseDouble(value);
branchStyle.setLineWidth(width);
}
}
private void setNodeStyleValue(INodeStyle nodeStyle,String feature,String value) {
if(feature.equalsIgnoreCase("fill") || feature.equalsIgnoreCase("stroke") || feature.equalsIgnoreCase("color")) {
//TODO check if value is a valid color string
nodeStyle.setColor(value);
}
else if(feature.equalsIgnoreCase("width")) {
double size = Double.parseDouble(value);
nodeStyle.setPointSize(size);
}
}
private IStyle lazyGet(String label)
{
IStyle style = map.get(label);
if (style == null)
{
style = new CompositeStyle(label, Defaults.DEFAULT_STYLE);
map.put(label, style);
}
return style;
}
@Override
public boolean hasBranchDecoration(int nodeId)
{
// TODO Auto-generated method stub
return false;
}
}