package com.giftoftheembalmer.gotefarm.client; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; import java.util.ListIterator; public class Guilds extends Composite implements HasValue<JSGuild> { private JSAccount account; private JSGuild active_guild; VerticalPanel vpanel = new VerticalPanel(); private final FlexTable flex = new FlexTable(); private final Anchor change_tz = new Anchor("change"); private final ListBox time_zones = new ListBox(); private class ChangeTimeZone implements ClickHandler { public void onClick(ClickEvent event) { flex.setWidget(1, 1, time_zones); flex.removeCell(1, 2); time_zones.setFocus(true); // Only ask for the list of time zones once final int count = time_zones.getItemCount(); if (count == 0) { GoteFarm.goteService.getTimeZones(new GetTimeZonesCallback()); } else if (active_guild != null && active_guild.time_zone != null) { // This scrolls the listbox to make the current time zone // visible for (int i = 0; i < count; ++i) { if (time_zones.getItemText(i) .equals(active_guild.time_zone)) { time_zones.setSelectedIndex(i); break; } } } } } private class GetTimeZonesCallback implements AsyncCallback<String[]> { public void onSuccess(String[] results) { boolean matched = active_guild.time_zone == null; time_zones.clear(); for (String tz : results) { time_zones.addItem(tz); if (!matched && tz.equals(active_guild.time_zone)) { time_zones.setSelectedIndex( time_zones.getItemCount() - 1 ); matched = true; } } } public void onFailure(Throwable caught) { flex.setText(1, 1, caught.getMessage()); flex.setWidget(1, 2, change_tz); } } private class TimeZoneSelected implements ChangeHandler { public void onChange(ChangeEvent event) { final int index = time_zones.getSelectedIndex(); if (index < 0) { return; } final String time_zone = time_zones.getItemText(index); GoteFarm.goteService.setTimeZone( active_guild.key, time_zone, new AsyncCallback<JSGuild>() { public void onSuccess(JSGuild result) { flex.setText(1, 1, time_zone); flex.setWidget(1, 2, change_tz); refreshGuild(result); // inform listeners that the guild has changed setValue(result, true); } public void onFailure(Throwable caught) { flex.setText(1, 1, caught.getMessage()); flex.setWidget(1, 2, change_tz); } }); } } public Guilds() { vpanel.setWidth("100%"); vpanel.add(new Label("Loading ...")); initWidget(vpanel); setStyleName("Guilds"); GoteFarm.goteService.getAccount(new AsyncCallback<JSAccount>() { public void onSuccess(JSAccount result) { account = result; vpanel.clear(); if (result.guilds.isEmpty()) { enroll(); return; } showGuilds(result); } public void onFailure(Throwable caught) { vpanel.clear(); Label errmsg = new Label(caught.getMessage()); errmsg.addStyleName("error"); vpanel.add(errmsg); } }); time_zones.setVisibleItemCount(10); time_zones.addChangeHandler(new TimeZoneSelected()); time_zones.addBlurHandler(new BlurHandler() { public void onBlur(BlurEvent event) { updateGuildInfo(); } }); change_tz.addClickHandler(new ChangeTimeZone()); } void showGuilds(JSAccount account) { vpanel.clear(); final HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setWidth("100%"); final ListBox lb = new ListBox(); hpanel.add(lb); hpanel.add(flex); lb.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { final int index = lb.getSelectedIndex(); if (index < 0) { return; } final String key = lb.getValue(index); GoteFarm.goteService.setActiveGuild( key, new AsyncCallback<JSGuild>() { public void onSuccess(JSGuild guild) { // Update cached JSGuild with this latest one refreshGuild(guild); // Update active_guild Guilds.this.account.active_guild = guild; setValue(Guilds.this.account.active_guild, true); } public void onFailure(Throwable caught) { // TODO: show error message } } ); } }); lb.setVisibleItemCount(5); for (JSGuild g : account.guilds) { lb.addItem(g.name, g.key); if ( account.active_guild != null && g.key.equals(account.active_guild.key)) { lb.setSelectedIndex(lb.getItemCount()-1); } } vpanel.add(hpanel); // TODO: Add a way for a user to add additional guilds setValue(account.active_guild, true); } void enroll() { // fake a non-existent guild with a null key so other // panels indicate no guild is selected JSGuild fake = new JSGuild(); fake.name = "Not A Guild"; fake.owner = "nobody"; fake.officers = new java.util.HashSet<String>(); setValue(fake, true); vpanel.clear(); vpanel.add(new Label("You need to create or join a guild.")); vpanel.add(new HTML(" ")); vpanel.add(new Label( "To get started, paste the armory URL of your " + "main character who is a member of the guild " + "you would like to register here.")); HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setSpacing(10); hpanel.add(new Label("Armory URL:")); final TextBox tb = new TextBox(); tb.setMaxLength(100); tb.setVisibleLength(75); hpanel.add(tb); vpanel.add(hpanel); final Label errmsg = new Label(); errmsg.addStyleName("error"); vpanel.add(errmsg); tb.addValueChangeHandler(new ValueChangeHandler<String>() { public void onValueChange(ValueChangeEvent<String> event) { final String url = event.getValue(); if (!url.contains("wowarmory.com/")) { errmsg.setText("URL does not appear to be an armory URL"); return; } tb.setEnabled(false); errmsg.setText(""); GoteFarm.goteService.getGuildFromArmoryURL(tb.getText(), new AsyncCallback<JSGuild>() { public void onSuccess(JSGuild result) { account.guilds.add(result); account.active_guild = result; showGuilds(account); } public void onFailure(Throwable caught) { tb.setEnabled(true); errmsg.setText(caught.getMessage()); } }); } }); } public JSGuild getValue() { return active_guild; } public void setValue(JSGuild value) { setValue(value, false); } public void setValue(JSGuild value, boolean fireEvents) { if (value == null) { if (active_guild == null) { return; } } else if (value.equals(active_guild)) { return; } active_guild = value; updateGuildInfo(); if (fireEvents) { ValueChangeEvent.fire(this, value); } } private void updateGuildInfo() { flex.clear(); if (active_guild == null) { return; } flex.setText(0, 0, active_guild.name + " (" + active_guild.realm + " ." + active_guild.region + ")"); flex.setText(1, 0, "Server Time Zone:"); flex.setText(1, 1, active_guild.time_zone != null ? active_guild.time_zone : "Not Set"); if (active_guild.isOfficer(account.key)) { flex.setWidget(1, 2, change_tz); } } public HandlerRegistration addValueChangeHandler( ValueChangeHandler<JSGuild> handler) { return addHandler(handler, ValueChangeEvent.getType()); } private void refreshGuild(JSGuild guild) { ListIterator<JSGuild> iter = account.guilds.listIterator(); while (iter.hasNext()) { JSGuild curr = iter.next(); if (curr.key.equals(guild.key)) { iter.set(guild); break; } } if (account.active_guild != null && account.active_guild.key.equals(guild.key)) { account.active_guild = guild; } } }