/**
 * Copyright © CENRA (2016)
 *
 * remi.clement@espaces-naturels.fr
 *
 * This software is a multi-platform and portable application based on
 * the scientifical toolbox to monitor wetlands. With this toolbox it’s
 * possible to calculate indicators «RhoMéO» to monitor quality,
 * fonctionalities and urban and agricultural pressures of wetlands.
 * Indicators are calculated using naturalist data entered and/or imported,
 * and geographic data downloaded from a geographic server.
 *
 * This software is governed by the CeCILL license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
*/
package fr.cenra.rhomeo.fx;

import fr.cenra.rhomeo.Rhomeo;
import fr.cenra.rhomeo.api.data.Site;
import fr.cenra.rhomeo.api.process.Indicator;
import fr.cenra.rhomeo.api.result.IndicatorValuesByYearItem;
import fr.cenra.rhomeo.api.ui.DashboardMenuItem;
import fr.cenra.rhomeo.core.RhomeoRuntimeException;
import fr.cenra.rhomeo.core.Session;
import fr.cenra.rhomeo.protocol.p04.I04;
import fr.cenra.rhomeo.protocol.p04.I07;
import fr.cenra.rhomeo.protocol.p08.I12;
import fr.cenra.rhomeo.protocol.p09.I13;
import java.beans.IntrospectionException;
import java.io.IOException;
import java.util.Optional;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *
 * @author Samuel Andrés (Geomatys) <samuel.andres at geomatys.com>
 */
@Component
public class MultiIndicatorsDashboardItem implements DashboardMenuItem {

    @Autowired
    private Session session;

    @Override
    public Optional<MenuItem> createItem(final TableView<IndicatorValuesByYearItem> table) {

        if (!(table instanceof FXDashboardResultsTable))
            return Optional.empty();

        final MenuItem graphItem = new MenuItem("Voir tous les indicateurs");
        graphItem.setOnAction(evt -> {
            try {
                displayStage((FXDashboardResultsTable) table);
            } catch (IOException | IntrospectionException | InstantiationException | IllegalAccessException ex) {
                throw new RhomeoRuntimeException("Unable to display results.", ex);
            }
        });
        graphItem.visibleProperty().bind(Bindings.size(table.getSelectionModel().getSelectedIndices()).isEqualTo(1)
                .and(isValidIndice(table.getSelectionModel().getSelectedCells())));

        return Optional.of(graphItem);
    }

    /**
     * Customized binding to test indicator column.
     *
     * @param op
     * @return
     */
    public static BooleanBinding isValidIndice(final ObservableList<TablePosition> op) {
        if (op == null) {
            throw new NullPointerException("List cannot be null.");
        }

        return new BooleanBinding() {
            {
                super.bind(op);
            }

            @Override
            public void dispose() {
                super.unbind(op);
            }

            @Override
            protected boolean computeValue() {
                if(op.size()!=1) return false;
                final TablePosition cell = op.get(0);
                final TableColumn tableColumn = cell.getTableColumn();
                if(tableColumn instanceof IndicatorSiteColumn && ((IndicatorSiteColumn) tableColumn).getIndicator()!=null){
                    final String ind = ((IndicatorSiteColumn) tableColumn).getIndicator().getName();
                    if (I04.NAME.equals(ind) || I07.NAME.equals(ind) || I12.NAME.equals(ind) || I13.NAME.equals(ind)) {
                        return tableColumn.getCellData(cell.getRow()) != null;
                    }
                }

                return false;
            }

            @Override
            //@ReturnsUnmodifiableCollection
            public ObservableList<?> getDependencies() {
                return FXCollections.singletonObservableList(op);
            }
        };
    }

    /**
     * Display the evolution graph in a modal window.
     */
    private void displayStage(final FXDashboardResultsTable table) throws IOException, IntrospectionException, InstantiationException, IllegalAccessException {

        if (table.getScene() == null
                || table.getScene().getWindow() == null
                || table.getSelectionModel().getSelectedCells()==null
                || table.getSelectionModel().getSelectedCells().size()!=1)
            return;

        final Site site = table.siteProperty().get();
        final TableColumn<IndicatorValuesByYearItem, ?> tableColumn = table.getSelectionModel().getSelectedCells().get(0).getTableColumn();

        if(site!=null && site.getName()!=null && tableColumn!=null && tableColumn instanceof IndicatorSiteColumn){

            final Indicator indicator = ((IndicatorSiteColumn) tableColumn).getIndicator();
            final IndicatorValuesByYearItem selectedItem = table.getSelectionModel().getSelectedItem();

            final Stage chartStage = new Stage(StageStyle.TRANSPARENT);
            chartStage.initModality(Modality.WINDOW_MODAL);
            chartStage.initOwner(table.getScene().getWindow());

            final FXFullSpecificResultPane fullResultPane = session.createPrototype(FXFullSpecificResultPane.class,
                    selectedItem,
                    indicator,
                    site.getName());

            final Label label = new Label(indicator.getName() + " ("+selectedItem.getYear()+")");
            label.setAlignment(Pos.CENTER);
            label.setMaxWidth(Double.MAX_VALUE);
            label.getStyleClass().add("text-bold");

            final BorderPane root = new BorderPane();
            root.setPrefSize(400, Region.USE_COMPUTED_SIZE);
            root.getStyleClass().add("white-box");
            root.setTop(label);
            root.setCenter(fullResultPane);

            final Button closeBtn = new Button("Fermer");
            closeBtn.setCancelButton(true);
            closeBtn.setOnAction(evt -> chartStage.close());
            closeBtn.getStyleClass().add("white-button");
            final HBox hBox = new HBox(closeBtn);
            hBox.setAlignment(Pos.CENTER_RIGHT);
            root.setBottom(hBox);

            final Scene scene = new Scene(root);
            scene.getStylesheets().add(Rhomeo.CSS_THEME_PATH);
            scene.getStylesheets().add("/fr/cenra/rhomeo/fx/FXProtocolReferencesPane.css");

            chartStage.setMaxHeight(400);
            chartStage.setMaxWidth(700);
            chartStage.setScene(scene);
            chartStage.sizeToScene();
            chartStage.show();
        }
    }
}
