package org.chesmapper.view.cluster; import java.awt.Color; import java.util.BitSet; import java.util.HashMap; import javax.swing.ImageIcon; import javax.vecmath.Vector3f; import org.apache.commons.lang3.StringEscapeUtils; import org.chesmapper.map.dataInterface.CompoundData; import org.chesmapper.map.dataInterface.CompoundProperty; import org.chesmapper.map.dataInterface.NominalProperty; import org.chesmapper.map.dataInterface.NumericProperty; import org.chesmapper.map.dataInterface.SingleCompoundPropertyOwner; import org.chesmapper.map.main.Settings; import org.chesmapper.view.gui.MainPanel.Translucency; import org.chesmapper.view.gui.View; import org.chesmapper.view.gui.ViewControler; import org.chesmapper.view.gui.ViewControler.Style; import org.chesmapper.view.gui.Zoomable; import org.mg.javalib.gui.DoubleNameListCellRenderer.DoubleNameElement; import org.mg.javalib.util.ColorUtil; import org.mg.javalib.util.ObjectUtil; public class Compound implements Zoomable, Comparable<Compound>, DoubleNameElement, SingleCompoundPropertyOwner { private BitSet bitSet; private BitSet dotModeHideBitSet; private BitSet dotModeDisplayBitSet; private int jmolIndex; private CompoundData compoundData; private Translucency translucency = Translucency.None; private String label = null; private boolean showHoverBox = false; private boolean showActiveBox = false; private String smarts = null; private HashMap<String, BitSet> smartsMatches; private String compoundColor; private String highlightColorString; private Color highlightColorText; private String lastHighlightColorString; private Vector3f spherePosition; private CompoundProperty highlightCompoundProperty; private Style style; private CompoundProperty descriptorProperty = null; private boolean sphereVisible; private boolean lastFeatureSphereVisible; private boolean visible = true; private boolean featureSortingEnabled = true; private float diameter = -1; public final Vector3f origCenter; public final Vector3f origDotPosition; public Compound(int jmolIndex, CompoundData compoundData) { this.jmolIndex = jmolIndex; this.compoundData = compoundData; if (View.instance != null) { bitSet = View.instance.getCompoundBitSet(getJmolIndex()); dotModeHideBitSet = View.instance.getDotModeHideBitSet(bitSet); dotModeDisplayBitSet = View.instance.getDotModeDisplayBitSet(bitSet); origCenter = new Vector3f(View.instance.getAtomSetCenter(bitSet)); origDotPosition = new Vector3f(View.instance.getAtomSetCenter(getDotModeDisplayBitSet())); } else { //for export without graphics origCenter = null; origDotPosition = null; } smartsMatches = new HashMap<String, BitSet>(); setDescriptor(ViewControler.COMPOUND_INDEX_PROPERTY); } public String getFormattedValue(CompoundProperty property) { return compoundData.getFormattedValue(property); } @Override public String getStringValue(NominalProperty property) { return compoundData.getStringValue(property); } public Double getDoubleValue(NumericProperty property) { return compoundData.getDoubleValue(property); } public int getJmolIndex() { return jmolIndex; } public int getOrigIndex() { return compoundData.getOrigIndex(); } public static class DisplayName implements Comparable<DisplayName> { String valDisplay; @SuppressWarnings("rawtypes") Comparable valCompare[]; Integer compareIndex; String name; public String toString(boolean html, Color highlightColor) { StringBuffer b = new StringBuffer(); if (html) b.append(StringEscapeUtils.escapeHtml4(name)); else b.append(name); if (valDisplay != null && !valDisplay.equals(name)) { if (html) { b.append(": "); if (highlightColor != null) b.append("<font color='" + ColorUtil.toHtml(highlightColor) + "'>"); b.append("<i>"); b.append(StringEscapeUtils.escapeHtml4(valDisplay)); b.append("</i>"); if (highlightColor != null) b.append("</font>"); } else { b.append(": "); b.append(valDisplay); } } return b.toString(); } @Override public int compareTo(DisplayName d) { return compareTo(d, true); } public int compareTo(DisplayName d, boolean featureSortingEnabled) { if (featureSortingEnabled && valCompare != null) { for (int j = 0; j < valCompare.length; j++) { int i = ObjectUtil.compare(valCompare[j], d.valCompare[j]); if (i != 0) return i; } } if (compareIndex != null) return compareIndex.compareTo(d.compareIndex); // if nothing is selected, compound should be sorted according to identifier return name.compareTo(d.name); } } private DisplayName displayName = new DisplayName(); @Override public String toString() { return getFirstName(); } public String toStringWithValue() { return displayName.toString(false, null); } @Override public String getFirstName() { return displayName.name; } @Override public String getSecondName() { if (ObjectUtil.equals(displayName.valDisplay, displayName.name)) return null; else return displayName.valDisplay; } @Override public int compareTo(Compound m) { return displayName.compareTo(m.displayName, featureSortingEnabled); } public String getSmiles() { return compoundData.getSmiles(); } public Translucency getTranslucency() { return translucency; } public void setTranslucency(Translucency translucency) { this.translucency = translucency; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public boolean isShowHoverBox() { return showHoverBox; } public void setShowHoverBox(boolean showBox) { this.showHoverBox = showBox; } public boolean isShowActiveBox() { return showActiveBox; } public void setShowActiveBox(boolean showBox) { this.showActiveBox = showBox; } public String getHighlightedSmarts() { return smarts; } public void setHighlightedSmarts(String smarts) { this.smarts = smarts; } public void moveTo(Vector3f clusterPos) { Vector3f center = new Vector3f(View.instance.getAtomSetCenter(getBitSet())); Vector3f dest = new Vector3f(clusterPos); dest.sub(center); View.instance.setAtomCoordRelative(dest, getBitSet()); } public Vector3f getPosition(boolean scaled) { Vector3f v = new Vector3f(JitteringProvider.getPosition(compoundData)); if (scaled) v.scale(ClusteringUtil.SCALE); return v; } public Vector3f getPosition() { return getPosition(true); } public BitSet getSmartsMatch(String smarts) { //compute match dynamically if (!smartsMatches.containsKey(smarts)) { Settings.LOGGER.info("smarts-matching smarts: " + smarts + " smiles: " + getSmiles()); smartsMatches.put(smarts, View.instance.getSmartsMatch(smarts, bitSet)); } return smartsMatches.get(smarts); } public void setCompoundColor(String colorString) { this.compoundColor = colorString; } public String getCompoundColor() { return compoundColor; } public void setHighlightColor(String colorString, Color colorText) { if (!ObjectUtil.equals(highlightColorString, colorString) || lastHighlightColorString == null) { this.lastHighlightColorString = highlightColorString; this.highlightColorString = colorString; this.highlightColorText = colorText; } } public Color getHighlightColorText() { return highlightColorText; } public String getHighlightColorString() { return highlightColorString; } public String getLastHighlightColorString() { return lastHighlightColorString; } public Vector3f getSpherePosition() { return spherePosition; } public void setSpherePosition(Vector3f spherePosition) { this.spherePosition = spherePosition; } public void setHighlightCompoundProperty(CompoundProperty highlightCompoundProperty) { if (this.highlightCompoundProperty != highlightCompoundProperty) { displayName.valDisplay = null; displayName.valCompare = null; if (highlightCompoundProperty != null) { if (highlightCompoundProperty instanceof NumericProperty) displayName.valCompare = new Double[] { getDoubleValue((NumericProperty) highlightCompoundProperty) }; else displayName.valCompare = new String[] { getStringValue((NominalProperty) highlightCompoundProperty) }; displayName.valDisplay = getFormattedValue(highlightCompoundProperty); } this.highlightCompoundProperty = highlightCompoundProperty; lastHighlightColorString = null; } } public Object getHighlightCompoundProperty() { return highlightCompoundProperty; } public void setStyle(Style style) { this.style = style; } public Style getStyle() { return style; } @Override public Vector3f getCenter(boolean superimposed) { return new Vector3f(View.instance.getAtomSetCenter(bitSet)); } @Override public float getDiameter(boolean superimposed) { return getDiameter(); } public float getDiameter() { if (diameter == -1) diameter = View.instance.getDiameter(bitSet); return diameter; } @Override public boolean isSuperimposed() { return false; } public ImageIcon getIcon(boolean backgroundBlack, int width, int height, boolean translucent) { return compoundData.getIcon(backgroundBlack, width, height, translucent); } public void setDescriptor(CompoundProperty descriptorProperty) { if (this.descriptorProperty != descriptorProperty) { displayName.compareIndex = null; if (descriptorProperty == ViewControler.COMPOUND_INDEX_PROPERTY) { displayName.compareIndex = getOrigIndex(); displayName.name = "Compound " + (getOrigIndex() + 1); } else if (descriptorProperty == ViewControler.COMPOUND_SMILES_PROPERTY) displayName.name = getSmiles(); else displayName.name = getFormattedValue(descriptorProperty); this.descriptorProperty = descriptorProperty; } } public boolean isSphereVisible() { return sphereVisible; } public void setSphereVisible(boolean sphereVisible) { this.sphereVisible = sphereVisible; } public boolean isLastFeatureSphereVisible() { return lastFeatureSphereVisible; } public void setLastFeatureSphereVisible(boolean s) { this.lastFeatureSphereVisible = s; } public BitSet getBitSet() { return bitSet; } public BitSet getDotModeHideBitSet() { return dotModeHideBitSet; } public BitSet getDotModeDisplayBitSet() { return dotModeDisplayBitSet; } public DisplayName getDisplayName() { return displayName; } public boolean isVisible() { return visible; } public void setVisible(boolean visible) { this.visible = visible; } public void setFeatureSortingEnabled(boolean featureSortingEnabled) { this.featureSortingEnabled = featureSortingEnabled; } public CompoundData getCompoundData() { return compoundData; } }