/*******************************************************************************
 * Copyright (c) 2012, 2020 Original authors and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Original authors and others - initial API and implementation
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.tree.painter;

import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.decorator.CellPainterDecorator;
import org.eclipse.nebula.widgets.nattable.tree.config.DefaultTreeLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeEnum;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;

/**
 * Implementation of CellPainterWrapper that is used to render tree structures
 * in NatTable. It puts indentation to tree nodes to visualize the tree
 * structure and adds expand/collapse icons corresponding to the state if a tree
 * node has children.
 */
public class IndentedTreeImagePainter extends CellPainterWrapper {
    /**
     * The number of pixels to indent per depth.
     */
    private final int treeIndent;

    private final CellPainterDecorator internalPainter;

    /**
     * Creates an IndentedTreeImagePainter. Will use 10 pixels for indentation
     * per depth and a default TreeImagePainter for rendering the icons in the
     * tree.
     */
    public IndentedTreeImagePainter() {
        this(10, new TreeImagePainter());
    }

    /**
     * Creates an IndentedTreeImagePainter. Will use the given number of pixels
     * for indentation per depth and a default {@link TreeImagePainter} for
     * rendering the icons in the tree.
     *
     * @param treeIndent
     *            The number of pixels to indent per depth.
     */
    public IndentedTreeImagePainter(int treeIndent) {
        this(treeIndent, new TreeImagePainter());
    }

    /**
     * Creates an IndentedTreeImagePainter using the given indentation per depth
     * and {@link ICellPainter} for painting the icons in the tree.
     *
     * @param treeIndent
     *            The number of pixels to indent per depth.
     * @param treeImagePainter
     *            The {@link ICellPainter} that should be used to paint the
     *            images in the tree. When using the
     *            DefaultTreeLayerConfiguration the content painter needs to be
     *            of type of {@link TreeImagePainter} that paints
     *            expand/collapse/leaf icons regarding the node state, because
     *            the ui bindings for expand/collapse are registered against
     *            that type.
     * @since 1.6
     */
    public IndentedTreeImagePainter(int treeIndent, ICellPainter treeImagePainter) {
        this(treeIndent, CellEdgeEnum.LEFT, treeImagePainter);
    }

    /**
     * Creates an IndentedTreeImagePainter using the given indentation per depth
     * and {@link ICellPainter} for painting the icons in the tree to the
     * specified cell edge.
     *
     * @param treeIndent
     *            The number of pixels to indent per depth.
     * @param cellEdge
     *            the edge of the cell on which the tree state indicator
     *            decoration should be applied
     * @param treeImagePainter
     *            The {@link ICellPainter} that should be used to paint the
     *            images in the tree. When using the
     *            DefaultTreeLayerConfiguration the content painter needs to be
     *            of type of {@link TreeImagePainter} that paints
     *            expand/collapse/leaf icons regarding the node state, because
     *            the ui bindings for expand/collapse are registered against
     *            that type.
     * @since 1.6
     */
    public IndentedTreeImagePainter(
            int treeIndent,
            CellEdgeEnum cellEdge,
            ICellPainter treeImagePainter) {

        this.treeIndent = treeIndent;
        this.internalPainter =
                new CellPainterDecorator(null, cellEdge, treeImagePainter);

        setWrappedPainter(this.internalPainter);
    }

    // the following constructors are intended to configure the
    // CellPainterDecorator that is created as
    // the wrapped painter of this IndentedTreeImagePainter

    /**
     * Creates a {@link IndentedTreeImagePainter} that uses the given
     * {@link ICellPainter} as base {@link ICellPainter}. It will use the
     * {@link TreeImagePainter} as decorator for tree state related decorations
     * at the specified cell edge, which can be configured to render the
     * background or not via method parameter. With the additional parameters,
     * the behaviour of the created {@link CellPainterDecorator} can be
     * configured in terms of rendering.
     *
     * @param treeIndent
     *            The number of pixels to indent per depth.
     * @param interiorPainter
     *            the base {@link ICellPainter} to use
     * @param cellEdge
     *            the edge of the cell on which the tree state indicator
     *            decoration should be applied
     * @param paintBg
     *            flag to configure whether the {@link TreeImagePainter} should
     *            paint the background or not
     * @param spacing
     *            the number of pixels that should be used as spacing between
     *            cell edge and decoration
     * @param paintDecorationDependent
     *            flag to configure if the base {@link ICellPainter} should
     *            render decoration dependent or not. If it is set to
     *            <code>false</code>, the base painter will always paint at the
     *            same coordinates, using the whole cell bounds,
     *            <code>true</code> will cause the bounds of the cell to shrink
     *            for the base painter.
     */
    public IndentedTreeImagePainter(
            int treeIndent,
            ICellPainter interiorPainter,
            CellEdgeEnum cellEdge,
            boolean paintBg,
            int spacing,
            boolean paintDecorationDependent) {

        this.treeIndent = treeIndent;

        ICellPainter painter = new TreeImagePainter(paintBg);
        this.internalPainter =
                new CellPainterDecorator(
                        interiorPainter,
                        cellEdge,
                        spacing,
                        painter,
                        paintDecorationDependent,
                        paintBg);
        setWrappedPainter(this.internalPainter);
    }

    /**
     * Creates a {@link IndentedTreeImagePainter} that uses the given
     * {@link ICellPainter} as base {@link ICellPainter}. It will use the given
     * {@link ICellPainter} as decorator for tree state related decorations at
     * the specified cell edge, which can be configured to render the background
     * or not via method parameter. With the additional parameters, the
     * behaviour of the created {@link CellPainterDecorator} can be configured
     * in terms of rendering.
     *
     * @param treeIndent
     *            The number of pixels to indent per depth.
     * @param interiorPainter
     *            the base {@link ICellPainter} to use
     * @param cellEdge
     *            the edge of the cell on which the tree state indicator
     *            decoration should be applied
     * @param decoratorPainter
     *            the {@link ICellPainter} that should be used to paint the tree
     *            state related decoration
     * @param paintBg
     *            flag to configure whether the {@link CellPainterDecorator}
     *            should paint the background or not
     * @param spacing
     *            the number of pixels that should be used as spacing between
     *            cell edge and decoration
     * @param paintDecorationDependent
     *            flag to configure if the base {@link ICellPainter} should
     *            render decoration dependent or not. If it is set to
     *            <code>false</code>, the base painter will always paint at the
     *            same coordinates, using the whole cell bounds,
     *            <code>true</code> will cause the bounds of the cell to shrink
     *            for the base painter.
     */
    public IndentedTreeImagePainter(
            int treeIndent,
            ICellPainter interiorPainter,
            CellEdgeEnum cellEdge,
            ICellPainter decoratorPainter,
            boolean paintBg,
            int spacing,
            boolean paintDecorationDependent) {

        this.treeIndent = treeIndent;

        this.internalPainter =
                new CellPainterDecorator(
                        interiorPainter,
                        cellEdge,
                        spacing,
                        decoratorPainter,
                        paintDecorationDependent,
                        paintBg);
        setWrappedPainter(this.internalPainter);
    }

    /**
     * Creates a {@link IndentedTreeImagePainter} that uses the given
     * {@link ICellPainter} as base {@link ICellPainter} and decorate it with
     * the {@link TreeImagePainter} on the right edge of the cell. This
     * constructor gives the opportunity to configure the behaviour of the
     * {@link TreeImagePainter} and the {@link CellPainterDecorator} for some
     * attributes. Remains because of downwards compatibility.
     *
     * @param treeIndent
     *            The number of pixels to indent per depth.
     * @param interiorPainter
     *            the base {@link ICellPainter} to use
     * @param paintBg
     *            flag to configure whether the {@link TreeImagePainter} should
     *            paint the background or not
     * @param interiorPainterToSpanFullWidth
     *            flag to configure how the bounds of the base painter should be
     *            calculated
     */
    public IndentedTreeImagePainter(
            int treeIndent,
            ICellPainter interiorPainter,
            boolean paintBg,
            boolean interiorPainterToSpanFullWidth) {

        this.treeIndent = treeIndent;

        ICellPainter painter = new TreeImagePainter(paintBg);
        this.internalPainter =
                new CellPainterDecorator(
                        interiorPainter,
                        CellEdgeEnum.RIGHT,
                        0,
                        painter,
                        !interiorPainterToSpanFullWidth,
                        paintBg);
        setWrappedPainter(this.internalPainter);
    }

    /**
     * @return The ICellPainter that is used to paint the images in the tree.
     *         Usually it is some type of TreeImagePainter that paints
     *         expand/collapse/leaf icons regarding the node state.
     */
    public ICellPainter getTreeImagePainter() {
        return this.internalPainter.getDecoratorCellPainter();
    }

    /**
     * @param cellPainter
     *            The {@link ICellPainter} that should be used to paint the
     *            images in the tree. Usually it is some type of
     *            {@link TreeImagePainter} that paints expand/collapse/leaf
     *            icons regarding the node state.
     */
    public void setTreeImagePainter(ICellPainter cellPainter) {
        this.internalPainter.setDecoratorCellPainter(cellPainter);
    }

    /**
     * @param cellPainter
     *            The base {@link ICellPainter} that should be used to render
     *            the cell content.
     */
    public void setBaseCellPainter(ICellPainter cellPainter) {
        this.internalPainter.setBaseCellPainter(cellPainter);
    }

    /**
     *
     * @return The {@link CellPainterDecorator} that is wrapped by this
     *         {@link IndentedTreeImagePainter}. Can be used to perform specific
     *         decoration configurations, e.g. set the decoration dependent
     *         rendering option.
     * @since 1.6
     */
    public CellPainterDecorator getInternalPainter() {
        return this.internalPainter;
    }

    @Override
    public Rectangle getWrappedPainterBounds(
            ILayerCell cell, GC gc, Rectangle bounds, IConfigRegistry configRegistry) {
        int depth = getDepth(cell);
        int indent = getIndent(depth, configRegistry);

        return new Rectangle(
                bounds.x + indent,
                bounds.y,
                bounds.width - indent,
                bounds.height);
    }

    @Override
    public void paintCell(ILayerCell cell, GC gc, Rectangle bounds, IConfigRegistry configRegistry) {
        super.paintCell(
                cell,
                gc,
                getWrappedPainterBounds(cell, gc, bounds, configRegistry),
                configRegistry);
    }

    @Override
    public int getPreferredWidth(ILayerCell cell, GC gc, IConfigRegistry configRegistry) {
        int depth = getDepth(cell);
        int indent = getIndent(depth, configRegistry);
        return indent + super.getPreferredWidth(cell, gc, configRegistry);
    }

    /**
     * @param depth
     *            The depth/level in the tree structure for which the indent is
     *            requested.
     * @param configRegistry
     *            The {@link IConfigRegistry} needed for accessing the dpi
     *            converter.
     * @return The number of pixels the content should be indented.
     * @since 2.0
     */
    protected int getIndent(int depth, IConfigRegistry configRegistry) {
        return GUIHelper.convertHorizontalPixelToDpi(this.treeIndent * depth, configRegistry);
    }

    /**
     * @param cell
     *            The cell for which the depth/level in the tree structure is
     *            requested.
     * @return The depth/level in the tree structure the given cell is located.
     *
     * @since 1.4
     */
    protected int getDepth(ILayerCell cell) {
        int depth = 0;

        for (String configLabel : cell.getConfigLabels()) {
            if (configLabel.startsWith(DefaultTreeLayerConfiguration.TREE_DEPTH_CONFIG_TYPE)) {
                String[] tokens = configLabel.split("_"); //$NON-NLS-1$
                depth = Integer.valueOf(tokens[tokens.length - 1]).intValue();
            }
        }

        return depth;
    }

}
