package haven;
import static haven.Inventory.sqlite;
import static haven.WItem.missing;
import haven.Resource.AButton;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import org.ender.wiki.Item;
import org.ender.wiki.Wiki;
public class ToolBeltWdg extends Window implements DropTarget{
private static final String OPT_FLIPPED = "_flipped";
private static final String OPT_LOCKED = "_locked";
private static final Coord invsz = sqlite.sz();
private static final int COUNT = 12;
private static final int BELTS = 6;
private static final Tex BELTNUMS[];
private static final BufferedImage ilockc = Resource.loadimg("gfx/hud/lockc");
private static final BufferedImage ilockch = Resource.loadimg("gfx/hud/lockch");
private static final BufferedImage ilocko = Resource.loadimg("gfx/hud/locko");
private static final BufferedImage ilockoh = Resource.loadimg("gfx/hud/lockoh");
GameUI gui;
private int curbelt = 0;
private int start = 0;
boolean locked, flipped;
private Resource pressed, dragging;
private int preslot;
private IButton lockbtn, flipbtn, minus, plus;
public final int beltkeys[];
private Tex[] nums;
private Coord beltNumC;
static {
BELTNUMS = new Tex[BELTS];
for(int i=0; i< BELTS; i++){
String num = String.format("%d", i);
BELTNUMS[i] = new TexI(Utils.outline2(Text.render(num).img, Color.BLACK, true));
}
}
public ToolBeltWdg(GameUI parent, String name, int beltn, final int[] keys) {
super(new Coord(5, 500), Coord.z, parent, name);
cap = null;
gui = parent;
start = beltn;
beltkeys = keys;
mrgn = new Coord(0,0);
cbtn.visible = false;
justclose = true;
init();
}
private void init() {
lockbtn = new IButton(Coord.z, this, locked?ilockc:ilocko, locked?ilocko:ilockc, locked?ilockch:ilockoh) {
public void click() {
locked = !locked;
if(locked) {
up = ilockc;
down = ilocko;
hover = ilockch;
} else {
up = ilocko;
down = ilockc;
hover = ilockoh;
}
storeOpt(OPT_LOCKED, locked);
}
};
lockbtn.recthit = true;
flipbtn = new IButton(Coord.z, this, Resource.loadimg("gfx/hud/flip"), Resource.loadimg("gfx/hud/flip"), Resource.loadimg("gfx/hud/flipo")) {
public void click() {
flip();
}
};
flipbtn.recthit = true;
minus = new IButton(Coord.z, this, Resource.loadimg("gfx/hud/charsh/minusup"), Resource.loadimg("gfx/hud/charsh/minusdown")) {
public void click() {
prevBelt();
}
};
plus = new IButton(Coord.z, this, Resource.loadimg("gfx/hud/charsh/plusup"), Resource.loadimg("gfx/hud/charsh/plusdown")) {
public void click() {
nextBelt();
}
};
resize();
/* Text rendering is slow, so pre-cache the hotbar numbers. */
nums = new Tex[COUNT];
for(int i = 0; i < COUNT; i++) {
String key = KeyEvent.getKeyText(beltkeys[i]);
nums[i] = new TexI(Utils.outline2(Text.render(key).img, Color.BLACK, true));
}
}
@Override
protected void loadOpts() {
super.loadOpts();
synchronized (Config.window_props) {
locked = getOptBool(OPT_LOCKED, false);
if(getOptBool(OPT_FLIPPED, false)) {
flip();
}
}
}
private void flip() {
flipped = !flipped;
storeOpt(OPT_FLIPPED, flipped);
resize();
}
private void resize() {
resize(beltc(COUNT-1).add(invsz).add(flipped?new Coord(0,14):new Coord(14,0)));
}
protected int getbelt(){
return getbelt(0);
}
protected int getbelt(int i){
return i + (start + curbelt)*COUNT;
}
protected void nextBelt() {
curbelt = (curbelt + 1)%BELTS;
}
protected void prevBelt() {
curbelt = (curbelt + BELTS - 1)%BELTS;
}
@Override
protected void placetwdgs() {
super.placetwdgs();
if(flipped){
if(flipbtn != null)
flipbtn.c = new Coord(asz.x - flipbtn.sz.x - 7, 0);
if(plus != null)
plus.c = new Coord(3, asz.y - plus.sz.y);
if(minus != null) {
minus.c = asz.sub(minus.sz).add(-3, 0);
beltNumC = plus.c.add(minus.c).add(minus.sz).div(2);
}
} else {
if(flipbtn != null)
flipbtn.c = new Coord(0, asz.y - flipbtn.sz.y - 7);
if(plus != null)
plus.c = new Coord(asz.x - plus.sz.x, 3);
if(minus != null) {
minus.c = asz.sub(minus.sz).add(0,-3);
beltNumC = plus.c.add(minus.c).add(minus.sz).div(2);
}
}
}
@Override
public void cdraw(GOut g) {
super.cdraw(g);
for(int i = 0; i < COUNT; i++) {
int slot = getbelt(i);
Coord c = beltc(i);
g.image(sqlite, beltc(i));
Tex tex = null;
try {
Indir<Resource> ir = gui.belt[slot];
if(ir != null)
tex = ir.get().layer(Resource.imgc).tex();
g.image(tex, c.add(4, 4));
} catch(Loading e) {
missing.loadwait();
tex = missing.layer(Resource.imgc).tex();
g.image(tex, c, invsz);
}
g.chcolor(200, 220, 200, 255);
g.aimage(nums[i], c.add(invsz), 1, 1);
g.chcolor();
}
g.aimage(BELTNUMS[curbelt], beltNumC, 0.5f, 0.5f);
}
@Override
public void draw(GOut og) {
super.draw(og);
if(dragging != null){
Tex tex = dragging.layer(Resource.imgc).tex();
og.root().aimage(tex, ui.mc, 0.5f, 0.5f);
}
}
@Override
public boolean mousedown(Coord c, int button) {
int slot = beltslot(c);
if (button == 1) {
pressed = beltres(slot);
preslot = slot;
if (pressed != null) {
ui.grabmouse(this);
} else {
super.mousedown(c, button);
if(locked){canceldm();}
}
} else if((button == 3)&&(!locked)){
clearslot(slot);
}
return (true);
}
@Override
public boolean mouseup(Coord c, int button) {
int slot = beltslot(c);
if (button == 1) {
if(dragging != null) {
ui.dropthing(ui.root, ui.mc, dragging);
dragging = pressed = null;
} else if (pressed != null) {
if (pressed == beltres(slot))
use(preslot);
pressed = null;
preslot = -1;
}
ui.grabmouse(null);
}
if(dm) {
Config.setWindowOpt(name+"_pos", this.c.toString());
}
super.mouseup(c, button);
return (true);
}
@Override
public void mousemove(Coord c) {
if ((!locked)&&(dragging == null) && (pressed != null)) {
dragging = pressed;
clearslot(beltslot(c));
pressed = null;
preslot = -1;
} else {
super.mousemove(c);
}
}
public boolean key(char key, KeyEvent ev) {
if(key != 0){return false;}
boolean M = (ev.getModifiersEx() & (KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)) != 0;
for(int i = 0; i < beltkeys.length; i++) {
if(ev.getKeyCode() == beltkeys[i]) {
if(M) {
curbelt = i%BELTS;
return(true);
} else {
keyact(i);
return(true);
}
}
}
return false;
}
public boolean globtype(char ch, KeyEvent ev) {
if(!key(ch, ev))
return(super.globtype(ch, ev));
else
return true;
}
public boolean type(char key, KeyEvent ev) {
return false;
}
private boolean checkmenu(int slot) {
Resource res = beltres(slot);
if(res == null){return false;}
AButton ab = res.layer(AButton.class);
if(ab != null && ((ab.ad.length == 0) || ab.ad[0].equals("@"))){
ui.mnu.useres(res);
}
return false;
}
private void use(int slot) {
if(slot == -1){return;}
if(checkmenu(slot)){return;}
slot = getbelt(slot);
ui.gui.wdgmsg("belt", slot, 1, ui.modflags());
}
private void keyact(int index) {
if(index == -1){return;}
if(checkmenu(index)){return;}
final int slot = getbelt(index);
MapView map = ui.gui.map;
if(map != null) {
Coord mvc = map.rootxlate(ui.mc);
if(mvc.isect(Coord.z, map.sz)) {
map.delay(map.new Hittest(mvc) {
protected void hit(Coord pc, Coord mc, MapView.ClickInfo inf) {
if(inf == null || inf.gob != null)
ui.gui.wdgmsg("belt", slot, 1, ui.modflags(), mc);
else
ui.gui.wdgmsg("belt", slot, 1, ui.modflags(), mc, (int)inf.gob.id, (int)inf.gob.id);
}
protected void nohit(Coord pc) {
ui.gui.wdgmsg("belt", slot, 1, ui.modflags());
}
});
}
}
}
private void clearslot(int slot) {
if(slot == -1){return;}
ui.gui.wdgmsg("setbelt", getbelt(slot), 1);
}
private Coord beltc(int i) {
if(flipped){
return(new Coord(0,
((invsz.y + 2) * i)
+ (10 * (i / 4)) + ilockc.getWidth() + 2));
} else {
return(new Coord(((invsz.x + 2) * i)
+ (10 * (i / 4)) + ilockc.getWidth() + 2,
0));
}
}
public int beltslot(Coord c){
c = c.sub(ctl);
for(int i = 0; i<COUNT; i++){
if(c.isect(beltc(i), invsz)){
return i;
}
}
return -1;
}
public Resource beltres(int slot){
if(slot == -1){return null;}
slot = getbelt(slot);
Resource res = null;
try {
Indir<Resource> ir = gui.belt[slot];
if(ir != null)
res = ir.get();
} catch (Loading e){}
return res;
}
private Resource curttr = null;
private boolean curttl = false;
private Tex curtt = null;
private long hoverstart;
Item ttitem = null;
@Override
public Object tooltip(Coord c, Widget prev) {
int slot = beltslot(c);
long now = System.currentTimeMillis();
if(slot != -1) {
slot = getbelt(slot);
Indir<Resource> ir = gui.belt[slot];
if(ir != null){
if(prev != this)
hoverstart = now;
boolean ttl = (now - hoverstart) > 500;
try {
Resource res = ir.get();
Item itm = Wiki.get(res.layer(Resource.action).name);
if((res != curttr) || (ttl != curttl) || itm != ttitem) {
ttitem = itm;
curtt = MenuGrid.rendertt(res, ttl, false);
curttr = res;
curttl = ttl;
}
return(curtt);
}catch(Loading e){return "...";}
}
}
hoverstart = now;
return null;
}
@Override
public boolean dropthing(Coord cc, Object thing) {
int slot = beltslot(cc);
if(slot != -1) {
slot = getbelt(slot);
if(thing instanceof Resource) {
Resource res = (Resource)thing;
if(res.layer(Resource.action) != null) {
gui.wdgmsg("setbelt", slot, res.name);
return(true);
}
}
}
return false;
}
}