/*******************************************************************************
 * Copyright (c) 2012, 2020 Original authors 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:
 *     Original authors and others - initial API and implementation
 *     Dirk Fauth <dirk.fauth@googlemail.com> - Bug 453707
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.nebula.widgets.nattable.tree.AbstractTreeRowModel;

import ca.odell.glazedlists.TreeList;

public class GlazedListTreeRowModel<T> extends AbstractTreeRowModel<T> {

    public GlazedListTreeRowModel(GlazedListTreeData<T> treeData) {
        super(treeData);
    }

    /**
     * Note: The check only works for visible elements, therefore a check for an
     * element that is below an collapsed element does not work.
     */
    @Override
    public boolean isCollapsed(int index) {
        if (!this.getTreeData().isValidIndex(index)) {
            return false;
        }

        return !this.getTreeData().getTreeList().isExpanded(index);
    }

    /**
     * Collapse the tree node at the given visible index.
     *
     * @param index
     *            The index of the node in the collection that should be
     *            collapsed.
     *
     * @return Returns an empty list because the list transformation for
     *         expand/collapse is handled by GlazedLists {@link TreeList}.
     */
    @Override
    public List<Integer> collapse(int index) {
        if (this.getTreeData().isValidIndex(index)) {
            this.getTreeData().getTreeList().setExpanded(index, false);
            notifyListeners();
        }

        return new ArrayList<Integer>();
    }

    /**
     * Will check the whole TreeList for its nodes and collapses them if they
     * are expanded. After executing this method, all nodes in the TreeList will
     * be collapsed.
     *
     * @return Returns an empty list because the list transformation for
     *         expand/collapse is handled by GlazedLists {@link TreeList}.
     */
    @Override
    public List<Integer> collapseAll() {
        TreeList<T> treeList = this.getTreeData().getTreeList();
        treeList.getReadWriteLock().writeLock().lock();
        try {
            // iterating directly over the TreeList is a lot faster than
            // checking the nodes
            // which is related that on collapsing we only need to iterate once
            // from bottom to top
            for (int i = (treeList.size() - 1); i >= 0; i--) {
                /*
                 * Checks if the node at the given visible index has children
                 * and is collapsible. If it is it will be collapsed otherwise
                 * skipped. This backwards searching and collapsing mechanism is
                 * necessary to ensure to really get every collapsible node in
                 * the whole tree structure.
                 */
                if (hasChildren(i) && !isCollapsed(i)) {
                    treeList.setExpanded(i, false);
                }
            }
        } finally {
            treeList.getReadWriteLock().writeLock().unlock();
        }

        notifyListeners();
        return new ArrayList<Integer>();
    }

    /**
     * Expand the tree node at the given visible index.
     *
     * @param index
     *            The index of the node in the collection that should be
     *            expanded.
     *
     * @return Returns an empty list because the list transformation for
     *         expand/collapse is handled by GlazedLists {@link TreeList}.
     */
    @Override
    public List<Integer> expand(int index) {
        if (this.getTreeData().isValidIndex(index)) {
            this.getTreeData().getTreeList().setExpanded(index, true);
            notifyListeners();
        }

        return new ArrayList<Integer>();
    }

    @Override
    public List<Integer> expandToLevel(int parentIndex, int level) {
        if (this.getTreeData().isValidIndex(parentIndex)) {
            internalExpandToLevel(parentIndex, level);
            notifyListeners();
        }

        return new ArrayList<Integer>();
    }

    /**
     * Performs the expand operations iteratively without notifying the
     * listeners while processing.
     *
     * @param parentIndex
     *            The index of the node in the collection that should be
     *            expanded.
     * @param level
     *            The level to which the tree nodes should be expanded.
     */
    protected void internalExpandToLevel(int parentIndex, int level) {
        if (this.getTreeData().isValidIndex(parentIndex)
                && depth(parentIndex) <= (level - 1)) {

            this.getTreeData().getTreeList().setExpanded(parentIndex, true);

            List<Integer> directChildren = getDirectChildIndexes(parentIndex);
            // iterate backwards because the indexes are changing on expand
            Collections.sort(directChildren, Collections.reverseOrder());
            for (Integer child : directChildren) {
                if (hasChildren(child) && depth(child) <= (level - 1)) {
                    internalExpandToLevel(child, level);
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     *
     * @return Returns an empty list because the list transformation for
     *         expand/collapse is handled by GlazedLists {@link TreeList}.
     */
    @Override
    public List<Integer> expandAll() {
        internalExpandAll();
        notifyListeners();
        return new ArrayList<Integer>();
    }

    /**
     * Performs the expand operations iteratively without notifying the
     * listeners while processing.
     */
    protected void internalExpandAll() {
        TreeList<T> treeList = this.getTreeData().getTreeList();

        boolean expandPerformed = false;
        treeList.getReadWriteLock().writeLock().lock();
        try {
            // iterating directly over the TreeList is a lot faster than
            // checking the nodes
            for (int i = (treeList.size() - 1); i >= 0; i--) {
                /*
                 * Checks if the node at the given visible index has children
                 * and is expandable. If it is it will be expanded otherwise
                 * skipped. This backwards searching and expanding mechanism is
                 * necessary to ensure to really get every expandable node in
                 * the whole tree structure.
                 */
                if (hasChildren(i) && isCollapsed(i)) {
                    treeList.setExpanded(i, true);
                    expandPerformed = true;
                }
            }
        } finally {
            treeList.getReadWriteLock().writeLock().unlock();
        }

        // if at least one element was expanded we need to perform the step
        // again as we are only able to retrieve the visible nodes
        if (expandPerformed) {
            expandAll();
        }
    }

    /**
     * {@inheritDoc}
     *
     * @return Returns an empty list because the list transformation for
     *         expand/collapse is handled by GlazedLists {@link TreeList}.
     */
    @Override
    public List<Integer> expandToLevel(int level) {
        internalExpandToLevel(level);
        notifyListeners();
        return new ArrayList<Integer>();
    }

    /**
     * Performs the expand operations iteratively without notifying the
     * listeners while processing.
     *
     * @param level
     *            The level to which the tree nodes should be expanded.
     */
    protected void internalExpandToLevel(int level) {
        TreeList<T> treeList = this.getTreeData().getTreeList();

        boolean expandPerformed = false;
        treeList.getReadWriteLock().writeLock().lock();
        try {
            // iterating directly over the TreeList is a lot faster than
            // checking the nodes
            for (int i = (treeList.size() - 1); i >= 0; i--) {
                /*
                 * Checks if the node at the given visible index has children,
                 * is expandable and is on a level below the given level. If it
                 * is it will be expanded otherwise skipped. This backwards
                 * searching and expanding mechanism is necessary to ensure to
                 * really get every expandable node in the whole tree structure.
                 */
                if (hasChildren(i) && isCollapsed(i) && treeList.getTreeNode(i).path().size() <= level) {
                    treeList.setExpanded(i, true);
                    expandPerformed = true;
                }
            }
        } finally {
            treeList.getReadWriteLock().writeLock().unlock();
        }

        // if at least one element was expanded we need to perform the step
        // again as we are only able to retrieve the visible nodes
        if (expandPerformed) {
            expandToLevel(level);
        }
    }

    /**
     * {@inheritDoc}
     *
     * @since 1.6
     */
    @Override
    public GlazedListTreeData<T> getTreeData() {
        return (GlazedListTreeData<T>) super.getTreeData();
    }
}
