package org.ender.wiki;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JComponent;
import javax.swing.JTextPane;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
public class HtmlDraw {
private static final Color BG_NULL = new Color(0,0,0,0);
private static final Color BG_COL = new Color(200,200,200,200);
private JTextPane htmlpane;
private HyperlinkListener links;
public HtmlDraw(String text, HyperlinkListener links){
this.links = links;
if(text == null){text = "<H1>Nothing found, sorry :(</H1>";}
text = text.replaceAll("=\"/", "=\"http://salemwiki.info/");//fix links
//fix food table backgrounds
Pattern rows = Pattern.compile("<tr style=\"background:(.*?);(.*?)\">(.*?)</tr>", Pattern.DOTALL|Pattern.MULTILINE);
Matcher mr = rows.matcher(text);
int i=0;
while(mr.find(i)){
String col = mr.group(1);
col = col.replace("darkred", "#8b0000");
col = col.replace("darkgreen", "#006400");
col = col.replace("darkblue", "#00008b");
col = col.replace("darkgoldenrod", "#b8860b");
String tmp = mr.group(2);
String cols = mr.group(3);
cols = cols.replaceAll("<td>", String.format("<td style=\"background-color: %s;\">", col));
tmp = String.format("<TR style=\"background:%s;%s\">%s</TR>", col, tmp, cols);
i = mr.start() + tmp.length() - 1;
text = mr.replaceFirst(tmp);
mr = rows.matcher(text);
}
htmlpane = new JTextPane();
htmlpane.setEditable(false);
htmlpane.setBackground(BG_NULL);
htmlpane.setOpaque(false);
// add an html editor kit
HTMLEditorKit kit = new HTMLEditorKit();
StyleSheet ss = kit.getStyleSheet();
ss.addRule(".searchmatch {color: green; font: bold}");
htmlpane.setEditorKit(kit);
HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
htmlpane.setDocument(doc);
htmlpane.setText(text);
htmlpane.setSize(htmlpane.getPreferredSize());
layoutComponent(htmlpane);
htmlpane.addHyperlinkListener(links);
}
public void setWidth(int w){
if(htmlpane == null){return;}
Dimension d = htmlpane.getSize();
d.width = w;
htmlpane.setSize(d);
//layoutComponent(htmlpane);
d = htmlpane.getPreferredScrollableViewportSize();
//d.width = w;
htmlpane.setSize(w, (int) d.getHeight());
}
public int getHeight(){
return htmlpane.getHeight();
}
public static void doClickInRectangle(Component component,
int x, int y,
boolean useRightClick,
int keyMods) {
int modifiers = useRightClick ? MouseEvent.BUTTON3_MASK : MouseEvent.BUTTON1_MASK;
modifiers |= keyMods;
final int nbClicks = 1;
component.dispatchEvent(new MouseEvent(component, MouseEvent.MOUSE_CLICKED, 1, modifiers, x, y, nbClicks, useRightClick));
}
public static BufferedImage createImage(JComponent component) {
Dimension d = component.getSize();
if (d.width == 0 || d.height == 0) {
d = component.getPreferredSize();
component.setSize(d);
}
Rectangle region = new Rectangle(0, 0, d.width, d.height);
return createImage(component, region);
}
public static BufferedImage createImage(JComponent component, Rectangle region) {
BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_ARGB);
return createImage(component, region, image);
}
public static BufferedImage createImage(JComponent component, Rectangle region, BufferedImage image) {
// Make sure the component has a size and has been layed out.
// (necessary check for components not added to a realized frame)
if (!component.isDisplayable()) {
Dimension d = component.getSize();
if (d.width == 0 || d.height == 0) {
d = component.getPreferredSize();
component.setSize(d);
}
layoutComponent(component);
}
Graphics2D g2d = image.createGraphics();
// Paint a background for non-opaque components,
// otherwise the background will be black
if (!component.isOpaque()) {
g2d.setColor(BG_COL);
g2d.fillRect(region.x, region.y, region.width, region.height);
}
g2d.translate(-region.x, -region.y);
component.paint(g2d);
g2d.dispose();
return image;
}
public void get(BufferedImage image, int w, int h) {
createImage(htmlpane, new Rectangle(w, h), image);
}
static void layoutComponent(Component component) {
synchronized (component.getTreeLock()) {
component.doLayout();
if (component instanceof Container) {
for (Component child : ((Container) component).getComponents()) {
layoutComponent(child);
}
}
}
}
public void mouseup(int x, int y, int button) {
doClickInRectangle(htmlpane, x, y, button != 1, 0);
}
public void destroy() {
htmlpane.removeHyperlinkListener(links);
links = null;
}
}