package com.vmware.vcloud.nclient.ui;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.PlainDocument;
import javax.swing.text.PlainView;
import javax.swing.text.Segment;
import javax.swing.text.Utilities;
public class HighlightView extends PlainView {
final Map<Pattern, Color> patternToColor;
public HighlightView(Element element, Map<Pattern, Color> patternToColor) {
super(element);
this.patternToColor = patternToColor;
getDocument().putProperty(PlainDocument.tabSizeAttribute, 4);
}
@Override
protected int drawUnselectedText(Graphics graphics, int x, int y, int p0, int p1) throws BadLocationException {
Document doc = getDocument();
String text = doc.getText(p0, p1 - p0);
Segment segment = getLineBuffer();
Set<ColorSegment> colorSegments = getColorSegments(text);
int offset = 0;
for (ColorSegment cs : colorSegments) {
if (offset < cs.start) {
graphics.setColor(Color.black);
doc.getText(p0 + offset, cs.start - offset, segment);
x = Utilities.drawTabbedText(segment, x, y, graphics, this, offset);
}
graphics.setColor(cs.color);
doc.getText(p0 + cs.start, cs.end - cs.start, segment);
x = Utilities.drawTabbedText(segment, x, y, graphics, this, cs.start);
offset = cs.end;
}
if (offset < text.length()) {
graphics.setColor(Color.black);
doc.getText(p0 + offset, text.length() - offset, segment);
x = Utilities.drawTabbedText(segment, x, y, graphics, this, offset);
}
return x;
}
Set<ColorSegment> getColorSegments(String text) {
Set<ColorSegment> result = new TreeSet<ColorSegment>();
for (Pattern pattern : patternToColor.keySet()) {
Color color = patternToColor.get(pattern);
Matcher m = pattern.matcher(text);
while (m.find()) {
ColorSegment cs = new ColorSegment(m.start(1), m.end(1), color);
result.add(cs);
}
}
return result;
}
static class ColorSegment implements Comparable<ColorSegment> {
final int start;
final int end;
final Color color;
public ColorSegment(int start, int end, Color color) {
this.start = start;
this.end = end;
this.color = color;
}
@Override
public int compareTo(ColorSegment o) {
return this.start - o.start;
}
}
}