/*
* Copyright 2010 kk-electronic a/s.
*
* This file is part of KKPortal.
*
* KKPortal is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KKPortal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with KKPortal. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kk_electronic.kkportal.core.tabs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.kk_electronic.kkportal.core.event.TabSelectedEvent;
import com.kk_electronic.kkportal.core.services.ModuleService;
import com.kk_electronic.kkportal.core.services.ModuleService.ModuleInfo;
import com.kk_electronic.kkportal.core.util.Sink;
/**
* This class is responsible for running the modules on the current page, and stop them
* when the user navigates away.
* @author albatros
*
*/
public class CanvasModel implements TabSelectedEvent.Handler {
HashMap<Integer, ModuleInfo> map = new HashMap<Integer, ModuleInfo>();
List<Sink<List<List<ModuleInfo>>>> displays = new LinkedList<Sink<List<List<ModuleInfo>>>>();
private final ModuleService moduleService;
private AsyncCallback<List<ModuleInfo>> infoCallback = new AsyncCallback<List<ModuleInfo>>(){
@Override
public void onFailure(Throwable caught) {
GWT.log("ModuleRunner could not get info for requested types",caught);
}
@Override
public void onSuccess(List<ModuleInfo> result) {
for(ModuleInfo moduleInfo:result){
if(missing.remove(moduleInfo.getId())){
map.put(moduleInfo.getId(), moduleInfo);
} else {
assert false:"Server returned a nonrequested moduleInfo";
}
}
if(missing.isEmpty()){
missing = null;
updateFromSelection();
}
}
};
private final TabsModel tabsModel;
@Inject
public CanvasModel(TabsModel tabsModel,ModuleService moduleService) {
this.tabsModel = tabsModel;
this.moduleService = moduleService;
tabsModel.addTabSelectedHandler(this);
updateFromSelection();
}
public void addCurrentCanvasDisplay(Sink<List<List<ModuleInfo>>> sink) {
displays.add(sink);
}
private void updateFromSelection() {
TabInfo tabInfo = tabsModel.getSelectedTab();
if(tabInfo == null){
updateDisplays(new ArrayList<List<ModuleInfo>>());
return;
}
addMissing(tabInfo.getModuleIds());
if(missing != null){
requestMissing();
return;
}
updateDisplays(getModuleIds(tabInfo.getModuleIds()));
}
private List<List<ModuleInfo>> getModuleIds(List<List<Integer>> moduleIds) {
List<List<ModuleInfo>> ret = new ArrayList<List<ModuleInfo>>();
if (moduleIds != null) {
for(List<Integer> column:moduleIds){
List<ModuleInfo> columnModule = new ArrayList<ModuleInfo>();
for(int id : column){
columnModule.add(map.get(id));
}
ret.add(columnModule);
}
}
return ret;
}
private void requestMissing() {
ArrayList<Integer> list = new ArrayList<Integer>(missing);
moduleService.getModuleInfo(list, infoCallback );
GWT.log("CANVASMODEL-Need module info on " + missing);
}
private void updateDisplays(List<List<ModuleInfo>> newvalue) {
for(Sink<List<List<ModuleInfo>>> sink:displays){
sink.setSinkValue(newvalue);
}
}
private void addMissing(List<List<Integer>> moduleIds)
{
if(moduleIds == null){
return;
}
for(List<Integer> column:moduleIds){
for(Integer id:column){
if(! map.containsKey(id)) addRequest(id);
}
}
}
HashSet<Integer> missing;
private void addRequest(int i){
if(missing == null) missing = new HashSet<Integer>();
missing.add(i);
}
@Override
public void onTabSelected(TabSelectedEvent event) {
updateFromSelection();
}
}