/*******************************************************************************
 * Copyright (c) 2018, 2020 Dirk Fauth and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation
 *******************************************************************************/
package org.eclipse.nebula.widgets.nattable.examples._600_GlazedLists._604_Tree;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.dataset.car.CarService;
import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.hierarchical.HierarchicalWrapperTreeFormat;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeData;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeRowModel;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hierarchical.HierarchicalHelper;
import org.eclipse.nebula.widgets.nattable.hierarchical.HierarchicalReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.hierarchical.HierarchicalWrapper;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.tree.ITreeRowModel;
import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
import org.eclipse.nebula.widgets.nattable.tree.config.DefaultTreeLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TransformedList;
import ca.odell.glazedlists.TreeList;

/**
 * Example showing the TreeLayer with levels over multiple columns.
 */
public class _6043_HierarchicalTreeExample extends AbstractNatExample {

    public static void main(String[] args) throws Exception {
        StandaloneNatExampleRunner.run(800, 400, new _6043_HierarchicalTreeExample());
    }

    @Override
    public String getDescription() {
        return "This example shows the usage of the TreeLayer with showing nodes in multiple columns.";
    }

    @Override
    public Control createExampleControl(Composite parent) {
        // mapping from property to label, needed for column header labels
        Map<String, String> propertyToLabelMap = new HashMap<>();
        propertyToLabelMap.put("manufacturer", "Manufacturer");
        propertyToLabelMap.put("model", "Model");
        propertyToLabelMap.put("motors.identifier", "Identifier");
        propertyToLabelMap.put("motors.capacity", "Capacity");
        propertyToLabelMap.put("motors.capacityUnit", "Capacity Unit");
        propertyToLabelMap.put("motors.maximumSpeed", "Maximum Speed");
        propertyToLabelMap.put("motors.feedbacks.creationTime", "Creation Time");
        propertyToLabelMap.put("motors.feedbacks.classification", "Classification");
        propertyToLabelMap.put("motors.feedbacks.comment", "Comment");

        BodyLayerStack bodyLayerStack = new BodyLayerStack(
                CarService.getInput(),
                CarService.getPropertyNames(),
                new HierarchicalWrapperTreeFormat(CarService.getPropertyNames()));

        // create the column header layer stack
        IDataProvider columnHeaderDataProvider =
                new DefaultColumnHeaderDataProvider(CarService.getPropertyNames(), propertyToLabelMap);
        ILayer columnHeaderLayer = new ColumnHeaderLayer(
                new DataLayer(columnHeaderDataProvider),
                bodyLayerStack,
                bodyLayerStack.getSelectionLayer());

        // create the row header layer stack
        IDataProvider rowHeaderDataProvider =
                new DefaultRowHeaderDataProvider(bodyLayerStack.getBodyDataProvider());
        ILayer rowHeaderLayer = new RowHeaderLayer(
                new DataLayer(rowHeaderDataProvider, 40, 20),
                bodyLayerStack,
                bodyLayerStack.getSelectionLayer());

        // create the corner layer stack
        ILayer cornerLayer = new CornerLayer(
                new DataLayer(
                        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)),
                rowHeaderLayer,
                columnHeaderLayer);

        // create the grid layer composed with the prior created layer stacks
        GridLayer gridLayer =
                new GridLayer(bodyLayerStack, columnHeaderLayer, rowHeaderLayer, cornerLayer);

        NatTable natTable = new NatTable(parent, gridLayer);
        return natTable;
    }

    /**
     * Always encapsulate the body layer stack in an AbstractLayerTransform to
     * ensure that the index transformations are performed in later commands.
     */
    class BodyLayerStack extends AbstractLayerTransform {

        private final TreeList<HierarchicalWrapper> treeList;

        private final IRowDataProvider<HierarchicalWrapper> bodyDataProvider;

        private final SelectionLayer selectionLayer;

        private final TreeLayer treeLayer;

        @SuppressWarnings("unchecked")
        public BodyLayerStack(List<?> values,
                String[] propertyNames,
                TreeList.Format<HierarchicalWrapper> treeFormat) {

            // de-normalize with parent structure objects
            List<HierarchicalWrapper> data = HierarchicalHelper.deNormalize(values, true, propertyNames);

            EventList<HierarchicalWrapper> eventList = GlazedLists.eventList(data);
            TransformedList<HierarchicalWrapper, HierarchicalWrapper> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);

            // use the SortedList constructor with 'null' for the Comparator
            // because the Comparator will be set by configuration
            SortedList<HierarchicalWrapper> sortedList = new SortedList<>(rowObjectsGlazedList, null);
            // wrap the SortedList with the TreeList
            this.treeList = new TreeList<HierarchicalWrapper>(sortedList, treeFormat, TreeList.NODES_START_EXPANDED);

            HierarchicalReflectiveColumnPropertyAccessor columnPropertyAccessor =
                    new HierarchicalReflectiveColumnPropertyAccessor(propertyNames);

            this.bodyDataProvider = new ListDataProvider<>(this.treeList, columnPropertyAccessor);

            DataLayer bodyDataLayer = new DataLayer(this.bodyDataProvider);

            // simply apply labels for every column by index
            bodyDataLayer.setConfigLabelAccumulator(new ColumnLabelAccumulator());

            // layer for event handling of GlazedLists and PropertyChanges
            GlazedListsEventLayer<HierarchicalWrapper> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer, this.treeList);

            GlazedListTreeData<HierarchicalWrapper> treeData = new GlazedListTreeData<>(this.treeList);
            ITreeRowModel<HierarchicalWrapper> treeRowModel = new GlazedListTreeRowModel<>(treeData);

            this.selectionLayer = new SelectionLayer(glazedListsEventLayer);

            this.treeLayer = new TreeLayer(this.selectionLayer, treeRowModel) {
                @Override
                protected boolean isTreeColumn(int columnPosition) {
                    // for this example we know where we show a tree node, for a
                    // more dynamic implementation check the
                    // HierarchicalTreeLayer
                    return columnPosition == 0 || columnPosition == 2;
                }

                @Override
                public Object getDataValueByPosition(int columnPosition, int rowPosition) {
                    int columnIndex = getColumnIndexByPosition(columnPosition);
                    int rowIndex = getRowIndexByPosition(rowPosition);

                    HierarchicalWrapper rowObject = BodyLayerStack.this.bodyDataProvider.getRowObject(rowIndex);
                    String columnProperty = columnPropertyAccessor.getColumnProperty(columnIndex);

                    // inspect the level of the property
                    int nextLevel = columnProperty.split("\\.").length;
                    // get level object of the next level in the object
                    if ((nextLevel < rowObject.getLevels() && rowObject.getObject(nextLevel) == null) || nextLevel == rowObject.getLevels()) {
                        return super.getDataValueByPosition(columnPosition, rowPosition);
                    }
                    return null;
                }

                @Override
                public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
                    LabelStack configLabels = super.getConfigLabelsByPosition(columnPosition, rowPosition);
                    // remove the labels that might be added by the super
                    // implementation
                    configLabels.removeLabel(TREE_COLUMN_CELL);
                    configLabels.removeLabel(DefaultTreeLayerConfiguration.TREE_LEAF_CONFIG_TYPE);
                    configLabels.removeLabel(DefaultTreeLayerConfiguration.TREE_COLLAPSED_CONFIG_TYPE);
                    configLabels.removeLabel(DefaultTreeLayerConfiguration.TREE_EXPANDED_CONFIG_TYPE);

                    // now add the labels from this layer
                    if (isTreeColumn(columnPosition) && getDataValueByPosition(columnPosition, rowPosition) != null) {
                        configLabels.addLabelOnTop(TREE_COLUMN_CELL);

                        int rowIndex = getRowIndexByPosition(rowPosition);
                        configLabels.addLabelOnTop(
                                DefaultTreeLayerConfiguration.TREE_DEPTH_CONFIG_TYPE + getModel().depth(rowIndex));
                        if (!getModel().hasChildren(rowIndex)) {
                            configLabels.addLabelOnTop(DefaultTreeLayerConfiguration.TREE_LEAF_CONFIG_TYPE);
                        } else {
                            if (getModel().isCollapsed(rowIndex)) {
                                configLabels.addLabelOnTop(DefaultTreeLayerConfiguration.TREE_COLLAPSED_CONFIG_TYPE);
                            } else {
                                configLabels.addLabelOnTop(DefaultTreeLayerConfiguration.TREE_EXPANDED_CONFIG_TYPE);
                            }
                        }
                    }
                    return configLabels;
                }

            };
            ViewportLayer viewportLayer = new ViewportLayer(this.treeLayer);

            setUnderlyingLayer(viewportLayer);
        }

        public SelectionLayer getSelectionLayer() {
            return this.selectionLayer;
        }

        public TreeLayer getTreeLayer() {
            return this.treeLayer;
        }

        public TreeList<HierarchicalWrapper> getTreeList() {
            return this.treeList;
        }

        public IDataProvider getBodyDataProvider() {
            return this.bodyDataProvider;
        }
    }
}
