package haven;
import haven.Resource.AButton;
import haven.Resource.Tooltip;
import haven.RichText.Part;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class WikiBrowser extends Window implements DTarget2, DropTarget{
private static final int SEARCH_H = 20;
public static final RichText.Foundry fnd = new RichText.Foundry(new WikiParser(TextAttribute.FAMILY, "SansSerif", TextAttribute.SIZE, 12, TextAttribute.FOREGROUND, Color.WHITE));
private static class WikiParser extends RichText.Parser {
public WikiParser(Object... args) {
super(args);
}
@Override
protected Part tag(PState s, String tn, String[] args, Map<? extends Attribute, ?> attrs) throws IOException {
if(tn.equals("table")){
return new Table(args, attrs);
}
return super.tag(s, tn, args, attrs);
}
}
private static class Table extends RichText.Part {
private static final int PAD_W = 5;
private static final int PAD_H = 3;
private int tabc, w=1, h=0, lh = 0;
private int[] twidth;
private BufferedImage[] tnames;
private List<BufferedImage[]> rows = new ArrayList<BufferedImage[]>();
public Table(String[] args, Map<? extends Attribute, ?> attrs) {
super();
tabc = Integer.parseInt(args[0]);
tnames = new BufferedImage[tabc];
twidth = new int[tabc];
int i=0;
for(i=0; i<tabc; i++){
tnames[i] = fnd.render(args[i+1]).img;
twidth[i] = tnames[i].getWidth() + 2*PAD_W;
lh = Math.max(h, tnames[i].getHeight()+2*PAD_H);
}
i = tabc+1;
while(i < args.length){
BufferedImage[] cols = new BufferedImage[tabc];
for(int k=0; k<tabc; k++, i++){
cols[k] = fnd.render(args[i]).img;
twidth[k] = Math.max(twidth[k], cols[k].getWidth() + 2*PAD_W);
lh = Math.max(h, cols[k].getHeight()+2*PAD_H);
}
rows.add(cols);
}
for(i=0; i<tabc; i++){w += twidth[i];}
h = lh*(rows.size()+1);
}
@Override
public int height() {return h;}
@Override
public int width() {return w;}
@Override
public int baseline() {return h-1;}
@Override
public void render(Graphics2D g) {
g.setColor(Color.WHITE);
int cx=x, cy=y, cw, i;
for(i=0; i<tabc; i++){
cw = twidth[i];
g.drawImage(tnames[i], cx+PAD_W, cy+PAD_H, null);
g.drawRect(cx, cy, cw, lh);
cx += cw;
}
i=1;
for(BufferedImage[] cols : rows){
cx = x;
cy = y+lh*i;
for(int j=0; j<tabc; j++){
cw = twidth[j];
g.drawImage(cols[j], cx+PAD_W, cy+PAD_H, null);
g.drawRect(cx, cy, cw, lh);
cx += cw;
}
i++;
}
}
}
private static final Coord gzsz = new Coord(15,15);
private static final Coord minsz = new Coord(200, 150);
private static final String OPT_SZ = "_sz";
private static WikiBrowser instance;
private Scrollport sp;
private TextEntry search;
private Button back;
private WikiPage page;
boolean rsm = false;
public WikiBrowser(Coord c, Coord sz, Widget parent) {
super(c, sz, parent, "Wiki");
justclose = true;
search = new TextEntry(Coord.z, new Coord(asz.x-30, SEARCH_H), this, "");
search.canactivate = true;
back = new Button(new Coord(asz.x - 20, 0), 20, this, "\u2190"){
@Override
public Object tooltip(Coord c, Widget prev) {
return "Back";
}
};
sp = new Scrollport(new Coord(0, SEARCH_H+3), asz.sub(0, SEARCH_H+3), this);
pack();
page = new WikiPage(Coord.z, sp.cont.sz, sp.cont);
}
@Override
protected void loadOpts() {
super.loadOpts();
resize(getOptCoord(OPT_SZ, sz));
}
@Override
public void wdgmsg(Widget sender, String msg, Object... args) {
if(msg.equals("activate")){
if(sender == search){
page.open(search.text, true);
return;
} else if(sender == back){
page.back();
return;
}
}
super.wdgmsg(sender, msg, args);
}
@Override
public void resize(Coord sz) {
super.resize(sz);
if(sp != null){sp.resize(sz.sub(0, SEARCH_H+3));}
if(search!= null){search.resize(new Coord(sz.x - 25, SEARCH_H));}
if(back!= null){back.c.x = sz.x - 20;}
}
@Override
public boolean mousedown(Coord c, int button) {
if (button == 1) {
ui.grabmouse(this);
doff = c;
if(c.isect(sz.sub(gzsz), gzsz)) {
rsm = true;
return true;
}
}
return super.mousedown(c, button);
}
@Override
public boolean mouseup(Coord c, int button) {
if (rsm){
ui.grabmouse(null);
rsm = false;
storeOpt(OPT_SZ, asz);
return true;
}
return super.mouseup(c, button);
}
@Override
public void mousemove(Coord c) {
if (rsm){
Coord d = c.sub(doff);
asz = asz.add(d);
asz.x = Math.max(minsz.x, asz.x);
asz.y = Math.max(minsz.y, asz.y);
doff = c;
resize(asz);
} else {
super.mousemove(c);
}
}
public static void toggle() {
if(instance == null){
instance = new WikiBrowser(new Coord(300, 200), minsz, UI.instance.gui);
} else {
close();
}
}
@Override
public void destroy() {
instance = null;
super.destroy();
}
public static void close() {
if(instance != null){
UI ui = UI.instance;
ui.destroy(instance);
}
}
@Override
public boolean dropthing(Coord cc, Object thing) {
if (thing instanceof Resource) {
Resource res = (Resource)thing;
String name = null;
Tooltip tt = res.layer(Resource.tooltip);
if(tt!=null){
name = tt.t;
} else {
AButton ad = res.layer(Resource.action);
if(ad != null) {
name = ad.name;
}
}
if(name!=null)
page.open(name, true);
return true;
}
return false;
}
@Override
public boolean drop(Coord cc, Coord ul, GItem item) {
String name = item.name();
if(name != null){
page.open(name, true);
}
return true;
}
@Override
public boolean iteminteract(Coord cc, Coord ul, GItem item) {
return false;
}
}