package org.openlca.app.results.regionalized;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.openlca.app.App;
import org.openlca.app.components.ResultTypeSelection;
import org.openlca.app.db.Cache;
import org.openlca.app.rcp.html.HtmlView;
import org.openlca.app.rcp.html.WebPage;
import org.openlca.app.util.UI;
import org.openlca.core.model.descriptors.FlowDescriptor;
import org.openlca.geo.RegionalizedResultProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import javafx.scene.web.WebEngine;
class KmlResultView extends FormPage implements WebPage {
private Logger log = LoggerFactory.getLogger(getClass());
private RegionalizedResultProvider result;
private WebEngine webkit;
private ResultTypeSelection flowImpactSelection;
private boolean incompleteData = false;
private boolean loaded;
public KmlResultView(FormEditor editor, RegionalizedResultProvider result) {
super(editor, "KmlResultView", "Result map");
this.result = result;
}
@Override
public String getUrl() {
return HtmlView.KML_RESULT_VIEW.getUrl();
}
@Override
public void onLoaded(WebEngine webkit) {
this.webkit = webkit;
loaded = true;
Set<FlowDescriptor> flowDescriptors = result.result.getFlowDescriptors();
if (flowDescriptors.isEmpty())
return;
FlowDescriptor flow = flowDescriptors.iterator().next();
flowImpactSelection.selectWithEvent(flow);
}
@Override
protected void createFormContent(IManagedForm managedForm) {
ScrolledForm form = UI.formHeader(managedForm, "Result map");
FormToolkit toolkit = managedForm.getToolkit();
Composite body = UI.formBody(form, toolkit);
Composite composite = toolkit.createComposite(body);
UI.gridLayout(composite, 2);
flowImpactSelection = ResultTypeSelection
.on(result.result, Cache.getEntityCache())
.withEventHandler(new KmlSelectionHandler(result))
.create(composite, toolkit);
Control browser = UI.createWebView(body, this);
UI.gridData(browser, true, true);
form.reflow(true);
}
@Override
public void setActive(boolean active) {
super.setActive(active);
if (incompleteData && webkit != null) {
// reset browser data
try {
webkit.executeScript("initData()");
} catch (Exception e) {
log.error("failed to evaluate initData()", e);
}
}
}
private class KmlSelectionHandler extends SelectionHandler {
private List<Job> delayedJobs = new ArrayList<>();
private KmlSelectionHandler(RegionalizedResultProvider result) {
super(result);
}
@Override
protected void processResultData(List<LocationResult> results) {
if (!loaded)
return;
delayedJobs.clear();
incompleteData = false;
double maximum = getMaximum(results);
evaluate("initData(" + maximum + ")");
for (LocationResult result : results)
sendToView(result);
}
private double getMaximum(List<LocationResult> results) {
Double maximum = null;
for (LocationResult result : results)
if (maximum == null)
maximum = result.amount;
else
maximum = Math.max(maximum, result.amount);
if (maximum == null)
return 0;
return maximum;
}
private void sendToView(LocationResult result) {
if (result == null)
return;
if (result.amount == 0d)
return;
Map<String, Object> item = new HashMap<String, Object>();
item.put("kml", result.kmlFeature.kml);
item.put("amount", result.amount);
delayedJobs.add(App.runInUI("Setting item", () -> evaluate(item)));
}
private void evaluate(Object value) {
if (!isActive()) {
incompleteData = true;
cancelDelayedJobs();
return;
}
if (webkit == null)
return;
String command = null;
if (value instanceof String)
command = value.toString();
else {
Gson gson = new Gson();
String json = gson.toJson(value);
command = "addFeature(" + json + ")";
}
try {
webkit.executeScript(command);
} catch (Exception e) {
log.error("failed to evaluate " + value, e);
}
}
private void cancelDelayedJobs() {
for (Job job : delayedJobs)
job.cancel();
}
}
}