package de.renew.navigator.gui;

import javax.swing.event.TreeExpansionEvent;

import de.renew.navigator.events.DirectoryOpeningEvent;
import de.renew.navigator.models.Directory;
import de.renew.navigator.models.NavigatorFileTree;
import de.renew.navigator.models.TreeElement;


/**
 * {@link javax.swing.event.TreeExpansionListener} to handle collapsing and expansion of tree nodes.
 *
 * @author Eva Mueller (3emuelle)
 * @version Jan, 2014
 */
class TreeExpansionListener implements javax.swing.event.TreeExpansionListener {
    private static boolean _active = true;
    private final NavigatorFileTree _model;

    TreeExpansionListener(NavigatorFileTree navigatorFileTree) {
        this._model = navigatorFileTree;
    }

    public static void setActive(boolean setActivated) {
        TreeExpansionListener._active = setActivated;
    }

    @Override
    public void treeCollapsed(TreeExpansionEvent event) {
        if (!_active) {
            return;
        }

        final FileTreeNode node = extractFileTreeNode(event);
        extractDirectory(node).setOpened(false);

        _model.notifyObservers(new DirectoryOpeningEvent(false, node));
    }

    @Override
    public void treeExpanded(TreeExpansionEvent event) {
        if (!_active) {
            return;
        }

        final FileTreeNode node = extractFileTreeNode(event);
        extractDirectory(node).setOpened(true);

        _model.notifyObservers(new DirectoryOpeningEvent(true, node));
    }

    private FileTreeNode extractFileTreeNode(TreeExpansionEvent event) {
        final Object lastPathComponent = event.getPath().getLastPathComponent();

        if (!(lastPathComponent instanceof FileTreeNode)) {
            throw new IllegalArgumentException("Last path component has to be a FileTreeNode");
        }

        return (FileTreeNode) lastPathComponent;
    }

    private Directory extractDirectory(FileTreeNode node) {
        final TreeElement treeElement = node.getModel();

        if (treeElement instanceof Directory) {
            return (Directory) treeElement;
        }

        return (Directory) treeElement.getParent();
    }
}