package scrum.client.tasks;
import ilarkesto.gwt.client.Gwt;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import scrum.client.admin.User;
import scrum.client.common.AScrumWidget;
import scrum.client.common.BlockListSelectionManager;
import scrum.client.common.BlockListWidget;
import scrum.client.common.ElementPredicate;
import scrum.client.common.UserGuideWidget;
import scrum.client.context.UserHighlightSupport;
import scrum.client.project.Requirement;
import scrum.client.sprint.Sprint;
import scrum.client.sprint.Task;
import scrum.client.workspace.PagePanel;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
public class WhiteboardWidget extends AScrumWidget implements TaskBlockContainer, UserHighlightSupport {
private Grid grid;
private HTML openLabel;
private HTML ownedLabel;
private HTML doneLabel;
private Map<Requirement, TaskListWidget> openTasks;
private Map<Requirement, TaskListWidget> ownedTasks;
private Map<Requirement, TaskListWidget> closedTasks;
private BlockListSelectionManager selectionManager = new BlockListSelectionManager();
private ElementPredicate<Task> predicate;
private List<Requirement> knownRequirements = Collections.emptyList();
private UserGuideWidget userGuide;
@Override
protected Widget onInitialization() {
predicate = null;
openLabel = new HTML();
openLabel.setStyleName("WhiteboardWidget-columnLabel");
openLabel.addStyleName("WhiteboardWidget-columnLabel-open");
openTasks = new HashMap<Requirement, TaskListWidget>();
ownedLabel = new HTML();
ownedLabel.setStyleName("WhiteboardWidget-columnLabel");
ownedLabel.addStyleName("WhiteboardWidget-columnLabel-owned");
ownedTasks = new HashMap<Requirement, TaskListWidget>();
doneLabel = new HTML();
doneLabel.setStyleName("WhiteboardWidget-columnLabel");
doneLabel.addStyleName("WhiteboardWidget-columnLabel-done");
closedTasks = new HashMap<Requirement, TaskListWidget>();
grid = new Grid();
grid.setWidth("100%");
grid.setCellPadding(0);
grid.setCellSpacing(0);
PagePanel page = new PagePanel();
page.addSection(grid);
userGuide = new UserGuideWidget(getLocalizer().views().whiteboard(), getCurrentProject().getCurrentSprint()
.getRequirements().size() < 3, getCurrentUser().getHideUserGuideWhiteboardModel());
page.addSection(userGuide);
return page;
}
@Override
protected void onUpdate() {
Sprint sprint = getCurrentProject().getCurrentSprint();
openLabel.setHTML("<strong>Free Tasks</strong> (" + hours(sprint.getRemainingWorkInUnclaimedTasks())
+ " to do)");
ownedLabel.setHTML("<strong>Claimed Tasks</strong> (" + hours(sprint.getRemainingWorkInClaimedTasks())
+ " to do, " + hours(sprint.getBurnedWorkInClaimedTasks()) + " done)");
doneLabel.setHTML("<strong>Completed Tasks</strong> (" + hours(sprint.getBurnedWorkInClosedTasks()) + " done)");
List<Requirement> requirements = sprint.getRequirements();
Collections.sort(requirements, sprint.getProject().getRequirementsOrderComparator());
if (requirements.equals(knownRequirements)) {
// quick update without recreating whole gui
for (Requirement requirement : requirements) {
updateTaskLists(requirement);
}
super.onUpdate();
return;
}
knownRequirements = requirements;
selectionManager = new BlockListSelectionManager();
grid.resize((requirements.size() * 2) + 1, 3);
for (Requirement requirement : requirements) {
openTasks.put(requirement, new TaskListWidget(requirement, this, new UnclaimTaskDropAction(requirement)));
ownedTasks.put(requirement, new TaskListWidget(requirement, this, new ClaimTaskDropAction(requirement)));
closedTasks.put(requirement, new TaskListWidget(requirement, this, new CloseTaskDropAction(requirement)));
}
setWidget(0, 0, openLabel, "33%", "WhiteboardWidget-header");
setWidget(0, 1, ownedLabel, "33%", "WhiteboardWidget-header");
setWidget(0, 2, doneLabel, "33%", "WhiteboardWidget-header");
// grid.getColumnFormatter().setWidth(0, "1*");
// grid.getColumnFormatter().setWidth(1, "1*");
// grid.getColumnFormatter().setWidth(2, "1*");
int row = 1;
for (int i = 0; i < requirements.size(); i++) {
Requirement requirement = requirements.get(i);
grid.setWidget(row, 0, createRequirementWidget(requirement));
grid.getCellFormatter().getElement(row, 0).setAttribute("colspan", "3");
row++;
updateTaskLists(requirement);
// grid.setWidget(row, 0, new Label(requirement.getLabel()));
setWidget(row, 0, openTasks.get(requirement), null, "WhiteboardWidget-open");
setWidget(row, 1, ownedTasks.get(requirement), null, "WhiteboardWidget-owned");
setWidget(row, 2, closedTasks.get(requirement), null, "WhiteboardWidget-done");
row++;
}
userGuide.update();
}
private Widget createRequirementWidget(Requirement requirement) {
BlockListWidget<Requirement> list = new BlockListWidget<Requirement>(RequirementInWhiteboardBlock.FACTORY);
list.addAdditionalStyleName("WhiteboardWidget-requirement-list");
list.setDndSorting(false);
list.setObjects(requirement);
return list;
// Label label = new Label(requirement.getReference() + " " + requirement.getLabel());
// label.setStyleName("WhiteboardWidget-requirement-label");
// return label;
}
private void updateTaskLists(Requirement requirement) {
List<Task> openTaskList = new ArrayList<Task>();
List<Task> ownedTaskList = new ArrayList<Task>();
List<Task> closedTaskList = new ArrayList<Task>();
for (Task task : requirement.getTasks()) {
if (task.isClosed()) {
closedTaskList.add(task);
} else if (task.isOwnerSet()) {
ownedTaskList.add(task);
} else {
openTaskList.add(task);
}
}
openTasks.get(requirement).setTasks(openTaskList);
ownedTasks.get(requirement).setTasks(ownedTaskList);
closedTasks.get(requirement).setTasks(closedTaskList);
}
private void updateHighlighting() {
for (Requirement requirement : openTasks.keySet()) {
openTasks.get(requirement).setTaskHighlighting(predicate);
ownedTasks.get(requirement).setTaskHighlighting(predicate);
closedTasks.get(requirement).setTaskHighlighting(predicate);
}
}
public void highlightUser(User user) {
setTaskHighlighting(user == null ? null : new ByUserPredicate(user));
}
public void setTaskHighlighting(ElementPredicate<Task> predicate) {
this.predicate = predicate;
updateHighlighting();
}
public void clearTaskHighlighting() {
this.predicate = null;
updateHighlighting();
}
private void setWidget(int row, int col, Widget widget, String width, String className) {
grid.setWidget(row, col, widget);
if (width != null || className != null) {
Element td = grid.getCellFormatter().getElement(row, col);
if (width != null) td.setAttribute("width", width);
if (className != null) td.setClassName(className);
}
}
public BlockListSelectionManager getSelectionManager() {
return selectionManager;
}
public void selectTask(Task task) {
if (task == null) return;
Requirement requirement = task.getRequirement();
updateTaskLists(requirement);
selectionManager.select(task);
update();
}
public boolean isShowOwner() {
return true;
}
public boolean isShowRequirement() {
return false;
}
public boolean isWideMode() {
return false;
}
private String hours(Integer i) {
return Gwt.formatHours(i);
}
private static class ByUserPredicate implements ElementPredicate<Task> {
private final User user;
public ByUserPredicate(User user) {
this.user = user;
}
public boolean contains(Task element) {
return element.getOwner() != null && element.getOwner().equals(user);
}
}
}