package scrum.client.workspace;
import ilarkesto.core.scope.Scope;
import ilarkesto.gwt.client.AGwtEntity;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import scrum.client.ScrumScopeManager;
import scrum.client.admin.User;
import scrum.client.core.ApplicationStartedEvent;
import scrum.client.core.ApplicationStartedHandler;
import scrum.client.project.Project;
import scrum.client.project.ProjectDataReceivedEvent;
import scrum.client.project.SelectProjectServiceCall;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
public class Navigator extends GNavigator implements BlockExpandedHandler, ApplicationStartedHandler {
public static enum Mode {
USER, PROJECT
}
private Mode currentMode;
private String page = "Dashboard";
@Override
public void initialize() {
History.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
evalHistoryToken(event.getValue());
}
});
}
private void evalHistoryToken(String token) {
log.info("evaluating history token:", token);
Map<String, String> tokens = parseHistoryToken(token);
// if (tokens.containsKey("project") && !projectDataReceived) {
// startToken = token;
// return;
// }
onHistoryToken(tokens);
}
private void onHistoryToken(final Map<String, String> tokens) {
if (tokens.containsKey("projectSelector")) {
gotoProjectSelector();
return;
}
String projectId = tokens.get("project");
if (projectId == null) {
gotoProjectSelector();
return;
}
gotoProject(projectId, tokens.get("page"), tokens.get("entity"));
}
@Override
public void onApplicationStarted(ApplicationStartedEvent event) {
String historyToken = History.getToken();
if (historyToken.contains("project=")) {
evalHistoryToken(historyToken);
} else {
gotoUsersStart();
}
}
private void gotoUsersStart() {
User user = auth.getUser();
Project project = user.getCurrentProject();
if (project == null || user.isAdmin()) {
gotoProjectSelector();
} else {
gotoProject(project.getId());
}
}
public void gotoProjectSelector() {
History.newItem("projectSelector", false);
activateUserMode();
}
public void gotoProject(String projectId) {
gotoProject(projectId, null, null);
}
private void gotoProject(String projectId, String page, String entityId) {
Project project = Scope.get().getComponent(Project.class);
if (project != null && !projectId.equals(project.getId())) {
project = null;
}
if (project == null) {
project = dao.getProject(projectId);
if (project == null) throw new RuntimeException("Project does not exist: " + projectId);
acitvateProjectMode(project, page, entityId);
return;
}
if (page != null) {
Scope.get().getComponent(ProjectWorkspaceWidgets.class).showPage(page);
}
if (entityId != null) {
Scope.get().getComponent(ProjectWorkspaceWidgets.class).showEntityById(entityId);
}
String token = "project=" + projectId;
if (page != null) token += "|page=" + page;
if (entityId != null) token += "|entity=" + entityId;
History.newItem(token, false);
}
public void gotoEntity(String entityId) {
Project project = Scope.get().getComponent(Project.class);
gotoEntity(project.getId(), entityId);
}
public void gotoEntity(String projectId, String entityId) {
gotoProject(projectId, null, entityId);
}
public void setPageToken(String page) {
if (page.equals(this.page)) return;
this.page = page;
if (!History.getToken().contains("page=" + page)) {
Project project = Scope.get().getComponent(Project.class);
History.newItem("project=" + project.getId() + "|page=" + page, false);
}
}
private void setToken(AGwtEntity entity) {
Project project = Scope.get().getComponent(Project.class);
if (project == null) return;
History.newItem("project=" + project.getId() + "|page=" + page + "|entity=" + entity.getId(), false);
}
@Override
public void onBlockExpanded(BlockExpandedEvent event) {
Object object = event.getObject();
if (object instanceof AGwtEntity) {
setToken((AGwtEntity) object);
}
}
private Map<String, String> parseHistoryToken(String token) {
if (token == null || token.length() == 0) return Collections.emptyMap();
Map<String, String> map = new HashMap<String, String>();
char separator = '|';
int idx = token.indexOf(separator);
while (idx > 0) {
String subtoken = token.substring(0, idx);
parseHistorySubToken(subtoken, map);
token = token.substring(idx + 1);
idx = token.indexOf(separator);
}
parseHistorySubToken(token, map);
return map;
}
private void parseHistorySubToken(String token, Map<String, String> map) {
int idx = token.indexOf('=');
if (idx < 0) {
map.put(token, token);
return;
}
String key = token.substring(0, idx);
String value = token.substring(idx + 1);
map.put(key, value);
}
private void activateUserMode() {
if (currentMode == Mode.PROJECT) {
ScrumScopeManager.destroyProjectScope();
}
log.info("Activating USER mode");
Scope.get().getComponent(UsersWorkspaceWidgets.class).activate();
currentMode = Mode.USER;
}
private void acitvateProjectMode(final Project project, final String page, final String entityId) {
assert project != null;
if (currentMode == Mode.PROJECT) {
if (project.equals(Scope.get().getComponent(Project.class))) return;
ScrumScopeManager.destroyProjectScope();
}
log.info("Activating PROJECT mode");
Scope.get().getComponent(Ui.class).lock("Loading " + project.getLabel() + "...");
new SelectProjectServiceCall(project.getId()).execute(new Runnable() {
@Override
public void run() {
ScrumScopeManager.createProjectScope(project);
currentMode = Mode.PROJECT;
new ProjectDataReceivedEvent().fireInCurrentScope();
ProjectWorkspaceWidgets projectWorkspaceWidgets = Scope.get().getComponent(
ProjectWorkspaceWidgets.class);
projectWorkspaceWidgets.activate();
if (page != null) {
projectWorkspaceWidgets.showPage(page);
} else {
projectWorkspaceWidgets.showDashboard();
}
if (entityId != null) {
projectWorkspaceWidgets.showEntityById(entityId);
}
}
});
}
}