/*
* Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see http://www.gnu.org/licenses/
*/
package org.esa.snap.timeseries.ui.assistant;
import com.bc.ceres.core.ProgressMonitor;
import com.bc.ceres.core.SubProgressMonitor;
import com.bc.ceres.swing.progress.ProgressMonitorSwingWorker;
import org.esa.snap.core.datamodel.Product;
import org.esa.snap.core.ui.assistant.AssistantPage;
import org.esa.snap.timeseries.core.timeseries.datamodel.ProductLocation;
import org.esa.snap.timeseries.ui.ProductLocationsPane;
import org.esa.snap.timeseries.ui.ProductLocationsPaneModel;
import org.esa.snap.timeseries.ui.Variable;
import java.awt.Component;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
class TimeSeriesAssistantPage_SourceProducts extends AbstractTimeSeriesAssistantPage {
TimeSeriesAssistantPage_SourceProducts(TimeSeriesAssistantModel model) {
super("Define Time Series Sources", model);
}
@Override
protected Component createPageComponent() {
final ProductLocationsPaneModel locationsModel = getAssistantModel().getProductLocationsModel();
return new ProductLocationsPane(locationsModel);
}
@Override
public boolean validatePage() {
if (super.validatePage()) {
final ProductLocationsPaneModel locationsModel = getAssistantModel().getProductLocationsModel();
if (locationsModel.getSize() > 0) {
return true;
}
}
return false;
}
@Override
public boolean hasNextPage() {
return true;
}
@Override
public AssistantPage getNextPage() {
removeModeListener();
final TimeSeriesAssistantModel model = getAssistantModel();
final ProgressMonitorSwingWorker worker = new MyProgressMonitorSwingWorker(model);
worker.executeWithBlocking();
if (allProductsOnSameGrid()) {
return new TimeSeriesAssistantPage_VariableSelection(model);
} else {
return new TimeSeriesAssistantPage_ReprojectingSources(model);
}
}
@SuppressWarnings({"MethodWithMoreThanThreeNegations"})
private boolean allProductsOnSameGrid() {
Product refProduct = null;
final List<ProductLocation> productLocations = getAssistantModel().getProductLocationsModel().getProductLocations();
for (ProductLocation productLocation : productLocations) {
for (Product product : productLocation.getProducts(ProgressMonitor.NULL).values()) {
if (refProduct != null) {
if (product != null && !refProduct.isCompatibleProduct(product, 0.1E-4f)) {
return false;
}
} else {
if (product != null) {
refProduct = product;
}
}
}
}
return true;
}
@Override
public boolean canFinish() {
return false;
}
private class MyProgressMonitorSwingWorker extends ProgressMonitorSwingWorker<Variable[], Object> {
private final TimeSeriesAssistantModel model;
private MyProgressMonitorSwingWorker(TimeSeriesAssistantModel model) {
super(TimeSeriesAssistantPage_SourceProducts.this.getContext().getCurrentPage().getPageComponent(),
"Scanning for products");
this.model = model;
}
@Override
protected Variable[] doInBackground(ProgressMonitor pm) throws Exception {
return getVariables(getAssistantModel().getProductLocationsModel(), pm);
}
@Override
protected void done() {
try {
model.getVariableSelectionModel().set(get());
} catch (InterruptedException ignored) {
} catch (ExecutionException e) {
getContext().showErrorDialog("Failed to scan for products: \n" + e.getMessage());
e.printStackTrace();
}
}
private Variable[] getVariables(ProductLocationsPaneModel locationsModel, ProgressMonitor pm) {
try {
pm.beginTask("Scanning product locations...", locationsModel.getSize());
for (int i = 0; i < locationsModel.getSize(); i++) {
final ProductLocation location = locationsModel.getElementAt(i);
location.loadProducts(new SubProgressMonitor(pm, 1));
final Collection<Product> products = location.getProducts(ProgressMonitor.NULL).values();
if (!products.isEmpty()) {
final Product product = products.iterator().next();
final String[] bandNames = product.getBandNames();
final Variable[] variables = new Variable[bandNames.length];
for (int j = 0; j < bandNames.length; j++) {
variables[j] = new Variable(bandNames[j]);
}
location.closeProducts();
// @todo se - ?? return variables ?? - really a shortcut after the first product?
// in this case only the variables of the first product are returned.
return variables;
} else {
location.closeProducts();
}
}
} finally {
pm.done();
}
return new Variable[0];
}
}
}