/**
 *############################################################################
 * A component of the Greenstone Librarian Interface, part of the Greenstone
 * digital library suite from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
 *
 * Copyright (C) 2004 New Zealand Digital Library Project
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *############################################################################
 */

package org.greenstone.gatherer.file;

import java.io.*;
import java.util.*;
import javax.swing.tree.TreePath;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.DebugStream;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.util.SynchronizedTreeModelTools;
import org.greenstone.gatherer.util.Utility;

public class WorkspaceTreeModel
    extends FileSystemModel
{
  //private WorkspaceTreeModel workspace_tree_model = null;
    private WorkspaceTreeNode workspace_tree_root = null;
    private WorkspaceTreeNode greenstone_collections_node = null;
    private WorkspaceTreeNode local_filespace_node = null;
    private WorkspaceTreeNode downloaded_files_node = null;
    private WorkspaceTreeNode[] folder_shortcuts = null;

    public WorkspaceTreeModel(WorkspaceTreeNode root_node)
    {
	super(root_node);
    }


    // Beware: gets non-live WorkspaceTreeNodes representing folder shortcuts based off
    // contents of config.xml, not the WorkspaceTreeNodes showing in the workspacetree
    static public WorkspaceTreeNode[] getFolderShortcuts()
    {
	// Return any predefined special directories
	HashMap mappings = Configuration.getDirectoryMappings();
	WorkspaceTreeNode[] mapping_nodes = new WorkspaceTreeNode[mappings.size()];
	Iterator mappings_iterator = mappings.keySet().iterator();
	for (int i = 0; mappings_iterator.hasNext(); i++) {
	    String mapping_name = (String) mappings_iterator.next();
	    File mapping_file = (File) mappings.get(mapping_name);
	    mapping_nodes[i] = new WorkspaceTreeNode(mapping_file, mapping_name);
	}
	return mapping_nodes;
    }


    static public WorkspaceTreeModel getWorkspaceTreeModel(int mode)
    {
	// Create a root node to contain the various nodes in the workspace tree
 	WorkspaceTreeNode ws_tree_root = new WorkspaceTreeNode(null, "ABS_ROOT");
	WorkspaceTreeModel ws_tree_model = new WorkspaceTreeModel(ws_tree_root);
        ws_tree_model.workspace_tree_root = ws_tree_root;
	// Add the "Documents in Greenstone Collections" node
        if (mode == Utility.IMPORT_MODE) {
          ws_tree_model.greenstone_collections_node = new WorkspaceTreeNode(null, Dictionary.get("Tree.World"), mode);
        } else {
          ws_tree_model.greenstone_collections_node = new WorkspaceTreeNode(null, Dictionary.get("Tree.CollFiles"), mode);
        }
	ws_tree_root.add(ws_tree_model.greenstone_collections_node);

	// Add the "Local Filespace" node
	if (!Gatherer.isWebswing) {
	    // if we are webswing, then we don't want access to these
	    ws_tree_model.local_filespace_node = FileSystem.getLocalFilespaceNode(ws_tree_model);
	    ws_tree_root.add(ws_tree_model.local_filespace_node);
	    
	    // Add the "Home Folder" node
	    ws_tree_root.add(FileSystem.getHomeFolderNode());
	}
	// Add the "Downloaded Files" node, if the Download pane is enabled
	if (Gatherer.g_man.download_pane != null) {
	    ws_tree_model.downloaded_files_node = FileSystem.getDownloadedFilesNode();
	    ws_tree_root.add(ws_tree_model.downloaded_files_node);
	}

	// Add any folder shortcuts the user has created
	ws_tree_model.refreshFolderShortcuts();

 	return ws_tree_model;
    }


    public void refreshGreenstoneCollectionsNode()
    {
	greenstone_collections_node.refresh();
    }


    public void refreshDownloadedFilesNode()
    {
	downloaded_files_node.refresh();
    }


    public void refreshFolderShortcuts()
    {
	// Check for new/deleted folder shortcuts
	WorkspaceTreeNode[] old_folder_shortcuts = folder_shortcuts;
	folder_shortcuts = getFolderShortcuts();

	// Remove any deleted shortcuts from the tree
	if (old_folder_shortcuts != null) {
	    for (int i = 0; i < old_folder_shortcuts.length; i++) {
		if (!doesArrayContain(folder_shortcuts, old_folder_shortcuts[i])) {
		    DebugStream.println("Deleted shortcut: " + old_folder_shortcuts[i]);
		    //SynchronizedTreeModelTools.removeNodeFromParent(this, old_folder_shortcuts[i]);
		    // SynchronizedTreeModelTools.removeNodeFromParent() only works for
		    // the most recent shortcut added during a GLI session. It doesn't work
		    // to remove previous shortcuts, because getFolderShortcuts()
		    // returns temporary WorkspaceTreeNodes, not the actual ones in the tree.
		    // Only the shortcut names match, the actual objects are different.
		    // That is, they're equivalents but not the same and removeNodeFromParent
		    // removes the actual given node.
		    // removeShortcutFromRoot() will remove the node in the tree (off the root)
		    // that's *equivalent* to the temp node old_folder_shortcuts[i] passed in.
		    SynchronizedTreeModelTools.removeShortcutFromRoot(this, workspace_tree_root, old_folder_shortcuts[i]);
		}
	    }
	}

	// Add any new shortcuts to the tree
	if (folder_shortcuts != null) {
	    for (int i = 0; i < folder_shortcuts.length; i++) {
		if (!doesArrayContain(old_folder_shortcuts, folder_shortcuts[i])) {
		    DebugStream.println("Added shortcut: " + folder_shortcuts[i]);
		    SynchronizedTreeModelTools.insertNodeInto(this, workspace_tree_root, folder_shortcuts[i], false);
		}
	    }
	}
    }


    // -- This code is necessary to support the workspace tree file filter --
    public void refresh(TreePath path)
    {
	// If we're not refreshing the whole tree just refresh a certain path
	if (path != null) {
	    super.refresh(path);
	    return;
	}

	// Refresh each of the nodes in the workspace tree
	for (int i = 0; i < workspace_tree_root.getChildCount(); i++) {
	    WorkspaceTreeNode child_node = (WorkspaceTreeNode) workspace_tree_root.getChildAt(i);
	    super.refresh(new TreePath(child_node.getPath()));
	}
    }


    static private boolean doesArrayContain(Object[] array, Object item)
    {
	if (array == null) {
	    return false;
	}

	for (int i = 0; i < array.length; i++) {
	    if (item.toString().equals(array[i].toString())) {
		return true;
	    }
	}

	return false;
    }
}
