package scrum.client.estimation;
import ilarkesto.core.logging.Log;
import ilarkesto.gwt.client.Gwt;
import ilarkesto.gwt.client.HyperlinkWidget;
import ilarkesto.gwt.client.TableBuilder;
import scrum.client.admin.User;
import scrum.client.common.AScrumWidget;
import scrum.client.project.CloseRequirementEstimationVotingAction;
import scrum.client.project.Project;
import scrum.client.project.Requirement;
import scrum.client.project.RequirementEstimationVotingShowoffAction;
import scrum.client.project.ResetRequirementEstimationVotingAction;
import scrum.client.workspace.VisibleDataChangedEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
public class PlanningPokerTableWidget extends AScrumWidget {
private static final Log LOG = Log.get(PlanningPokerTableWidget.class);
private Requirement requirement;
private SimplePanel cardSlotsWrapper;
private SimplePanel handCardsWrapper;
private SimplePanel actionsWrapper;
public PlanningPokerTableWidget(Requirement requirement) {
super();
this.requirement = requirement;
}
@Override
protected Widget onInitialization() {
cardSlotsWrapper = new SimplePanel();
handCardsWrapper = new SimplePanel();
actionsWrapper = new SimplePanel();
FlowPanel pokerTable = new FlowPanel();
pokerTable.setStyleName("PlanningPokerWidget-table");
pokerTable.add(createTableBranding());
pokerTable.add(cardSlotsWrapper);
if (getCurrentProject().isTeamMember(getCurrentUser())) {
pokerTable.add(Gwt.createSpacer(1, 20));
pokerTable.add(handCardsWrapper);
}
pokerTable.add(Gwt.createSpacer(1, 20));
pokerTable.add(actionsWrapper);
SimplePanel pokerTableBorder = Gwt.createDiv("PlanningPokerWidget-table-border", pokerTable);
return pokerTableBorder;
}
@Override
protected void onUpdate() {
cardSlotsWrapper.setWidget(createCardSlots());
handCardsWrapper.setWidget(createHandCards());
actionsWrapper.setWidget(createActions());
super.onUpdate();
}
private Widget createActions() {
ResetRequirementEstimationVotingAction reset = new ResetRequirementEstimationVotingAction(requirement);
RequirementEstimationVotingShowoffAction showoff = new RequirementEstimationVotingShowoffAction(requirement);
CloseRequirementEstimationVotingAction close = new CloseRequirementEstimationVotingAction(requirement);
TableBuilder tb = new TableBuilder();
tb.setWidth(null);
if (showoff.isExecutable() && showoff.isPermitted()) {
tb.add(new HyperlinkWidget(showoff));
tb.add(Gwt.createSpacer(10, 1));
}
if (reset.isExecutable() && reset.isPermitted()) {
tb.add(new HyperlinkWidget(reset));
tb.add(Gwt.createSpacer(10, 1));
}
if (close.isExecutable() && close.isPermitted()) {
tb.add(new HyperlinkWidget(close));
tb.add(Gwt.createSpacer(10, 1));
}
return tb.createTable();
}
private Widget createHandCards() {
Project project = getCurrentProject();
RequirementEstimationVote vote = requirement.getEstimationVote(getCurrentUser());
Float voteValue = vote == null ? null : vote.getEstimatedWork();
boolean showoff = requirement.isWorkEstimationVotingShowoff();
TableBuilder tb = new TableBuilder();
tb.setWidth(null);
for (String value : Requirement.WORK_ESTIMATION_VALUES) {
if (value.length() == 0) continue;
float estimation = Float.parseFloat(value);
PlanningPokerCardWidget card = null;
if (!showoff && (voteValue == null || estimation != voteValue)) {
card = new PlanningPokerCardWidget(estimation, true, new SetEstimationClickHandler(estimation),
"Put this card on the table.");
}
tb.add(new PlanningPokerCardSlotWidget(value + " " + project.getEffortUnit(), card));
tb.add(Gwt.createSpacer(5, 1));
}
return tb.createTable();
}
private Widget createCardSlots() {
TableBuilder tb = new TableBuilder();
tb.setWidth(null);
for (User user : getCurrentProject().getTeamMembers()) {
boolean currentUser = user == getCurrentUser();
RequirementEstimationVote vote = requirement.getEstimationVote(user);
Float estimation = vote == null ? null : vote.getEstimatedWork();
LOG.debug("Estimation:", user.getName(), "->", estimation);
Widget card;
if (estimation == null) {
card = null;
} else {
ClickHandler clickHandler = null;
String clickTooltip = null;
if (requirement.isWorkEstimationVotingShowoff()) {
clickHandler = new SelectEstimationClickHandler(estimation);
clickTooltip = "Use this card as the estimation for this Story. Planning Poker will be closed.";
} else if (currentUser) {
clickHandler = new RemoveEstimationClickHandler();
clickTooltip = "Remove this card from table.";
}
boolean visible = requirement.isWorkEstimationVotingShowoff();
card = new PlanningPokerCardWidget(estimation, visible, clickHandler, clickTooltip);
}
tb.add(new PlanningPokerCardSlotWidget(user.getName(), card));
tb.add(Gwt.createSpacer(5, 1));
}
return tb.createTable();
}
private Widget createTableBranding() {
return Gwt.createDiv("PlanningPokerWidget-table-branding", "Planning Poker");
}
private class SelectEstimationClickHandler implements ClickHandler {
private float estimation;
public SelectEstimationClickHandler(float estimation) {
super();
this.estimation = estimation;
}
public void onClick(ClickEvent event) {
requirement.setEstimatedWork(estimation);
new VisibleDataChangedEvent().fireInCurrentScope();
}
}
private class SetEstimationClickHandler implements ClickHandler {
private float estimation;
public SetEstimationClickHandler(float estimation) {
super();
this.estimation = estimation;
}
public void onClick(ClickEvent event) {
requirement.setVote(estimation);
new VisibleDataChangedEvent().fireInCurrentScope();
}
}
private class RemoveEstimationClickHandler implements ClickHandler {
public void onClick(ClickEvent event) {
requirement.setVote(null);
new VisibleDataChangedEvent().fireInCurrentScope();
}
}
}