/*
 * Autopsy Forensic Browser
 *
 * Copyright 2011-18 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sleuthkit.autopsy.corecomponentinterfaces;

import java.util.Collection;
import java.util.logging.Level;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.Mode;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
import org.sleuthkit.autopsy.coreutils.Logger;

/**
 * Responsible for opening and closing the core windows when a case is opened
 * and closed.
 *
 */
final public class CoreComponentControl {

    private static final Logger logger = Logger.getLogger(CoreComponentControl.class.getName());
    @NbBundle.Messages("CoreComponentControl.CTL_DirectoryTreeTopComponent=Directory Tree")
    private static final String DIRECTORY_TREE = Bundle.CoreComponentControl_CTL_DirectoryTreeTopComponent();
    @NbBundle.Messages("CoreComponentControl.CTL_FavoritesTopComponent=Favorites")
    private static final String FAVORITES = Bundle.CoreComponentControl_CTL_FavoritesTopComponent();

    private CoreComponentControl() {
    }

    /**
     * Opens all TopComponent windows that are needed
     * ({@link DataExplorer}, {@link DataResult}, and {@link DataContent})
     */
    public static void openCoreWindows() {
        // TODO: there has to be a better way to do this.

        // find the data explorer top components
        Collection<? extends DataExplorer> dataExplorers = Lookup.getDefault().lookupAll(DataExplorer.class);
        for (DataExplorer de : dataExplorers) {
            TopComponent explorerWin = de.getTopComponent();
            Mode explorerMode = WindowManager.getDefault().findMode("explorer"); //NON-NLS
            if (explorerMode == null) {
                logger.log(Level.WARNING, "Could not find explorer mode and dock explorer window"); //NON-NLS
            } else {
                explorerMode.dockInto(explorerWin); // redock into the explorer mode
            }
            explorerWin.open(); // open that top component
        }

        // find the data content top component
        TopComponent contentWin = DataContentTopComponent.findInstance();
        Mode outputMode = WindowManager.getDefault().findMode("output"); //NON-NLS
        if (outputMode == null) {
            logger.log(Level.WARNING, "Could not find output mode and dock content window"); //NON-NLS
        } else {
            outputMode.dockInto(contentWin); // redock into the output mode
        }

        contentWin.open(); // open that top component
    }

    /**
     * Closes all TopComponent windows that needed
     * ({@link DataExplorer}, {@link DataResult}, and {@link DataContent}).
     *
     * Note: The DataContent Top Component must be closed before the Directory
     * Tree and Favorites Top Components. Otherwise a NullPointerException will
     * be thrown from JFXPanel.
     */
    public static void closeCoreWindows() {
        TopComponent directoryTree = null;
        TopComponent favorites = null;
        final WindowManager windowManager = WindowManager.getDefault();
        for (Mode mode : windowManager.getModes()) {
            for (TopComponent tc : windowManager.getOpenedTopComponents(mode)) {
                String tcName = tc.getName();

                if (tcName == null) {
                    logger.log(Level.INFO, "tcName was null"); //NON-NLS
                }
                // switch requires constant strings, so converted to if/else.
                if (DIRECTORY_TREE.equals(tcName)) {
                    directoryTree = tc;
                } else if (FAVORITES.equals(tcName)) {
                    favorites = tc;
                } else {
                    tc.close();
                }
            }
        }

        if (directoryTree != null) {
            directoryTree.close();
        }
        if (favorites != null) {
            favorites.close();
        }
    }
}

@@ -3772,52 +3772,631 @@
     
-for (Mode mode : windowManager.getModes()) %7B
+%0A        // Set the UI selections to null before closing the top components.%0A        // Otherwise it may experience errors trying to load data for the closed case.%0A        for (Mode mode : windowManager.getModes()) %7B%0A            for (TopComponent tc : windowManager.getOpenedTopComponents(mode)) %7B%0A                if(tc instanceof DataContent) %7B%0A                    ((DataContent) tc).setNode(null);%0A                %7D else if(tc instanceof DataResult) %7B%0A                    ((DataResult) tc).setNode(null);%0A                %7D%0A            %7D%0A        %7D%0A        %0A        for (Mode mode : windowManager.getModes()) %7B%0A            
 %0A   
@@ -5002,32 +5002,40 @@
     %7D%0A        %7D%0A
+        
 %0A        if (dir

Set UI selections to null before closing top components.