/**
 *############################################################################
 * 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) 2006 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.collection;

import java.awt.*;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.*;
import java.io.File;
import java.util.Vector;
import javax.swing.*;
import javax.swing.tree.*;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.file.FileNode;
import org.greenstone.gatherer.file.FileSystemModel;
import org.greenstone.gatherer.gui.tree.DragTree;
import org.greenstone.gatherer.gui.tree.DragTreeCellRenderer;
import org.greenstone.gatherer.util.UnzipTools;
import org.greenstone.gatherer.util.Utility;


public class CollectionTree
    extends FullCollectionTree
    implements MouseListener
{

  
  public CollectionTree(FileSystemModel collection_tree_model, boolean mixed_selection)
    {
	super(collection_tree_model, mixed_selection);
	setCellRenderer(new CollectionTreeCellRenderer());
    }


    public void mouseClicked(MouseEvent event)
    {
	if (SwingUtilities.isRightMouseButton(event)) {
          new CollectionTreeRightClickMenu(this, event).showMenu(event);
	}
    }

    public String toString()
    {
	return "Collection";

    }

    protected class CollectionTreeCellRenderer
	extends DragTreeCellRenderer
    {
	public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus)
	{
	    JLabel tree_cell = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

	    // Mark explodable files and SrcReplaceable files with a different icon (Green file icon)
	    if(value instanceof CollectionTreeNode) {
		if(((CollectionTreeNode) value).isExplodable() || ((CollectionTreeNode) value).isSrcReplaceable()) {
		    tree_cell.setIcon(CollectionTreeNode.GREEN_FILE_ICON);
		}
	    }
	        
	    return tree_cell;
	}
    }


    /** When a user right-clicks within the workspace and collection trees they are presented with a small popup menu of context based options. This class provides such functionality.
        We extend this to add extra functionality
     */
    protected class CollectionTreeRightClickMenu
	extends FullCollectionTreeRightClickMenu
	
    {
        protected JMenuItem explode_metadata_database = null;
	protected JMenuItem replace_srcdoc_with_html = null;
	protected JMenuItem metaaudit = null;


	protected CollectionTreeRightClickMenu(CollectionTree collection_tree, MouseEvent event)
	{
          super(collection_tree, event);
        }
	    
	protected void buildContextMenu(TreePath[] selection_paths)
	{
	    // If nothing is selected, only the new folder/dummy doc options are available...
	    if (selection_paths == null) {
		new_folder = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_Folder"), KeyEvent.VK_N);
		new_folder.addActionListener(this);
		add(new_folder);

		new_file = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_File"));
		new_file.addActionListener(this);
		add(new_file);

                new_dummy_doc = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_Dummy_Doc"));
                
		new_dummy_doc.addActionListener(this);
		add(new_dummy_doc);

		refresh = new JMenuItem(Dictionary.get("CollectionPopupMenu.Refresh"));
		if(Gatherer.isGsdlRemote) {
		    refresh.setEnabled(false);
		}
		refresh.addActionListener(this);
		add(refresh);

		node = (FullCollectionTreeNode) collection_tree.getModel().getRoot();
		return;
	    }

            // something has been selected
            
	    // Meta-audit, delete and unzip options
            metaaudit = new JMenuItem(Dictionary.get("Menu.Metadata_View", collection_tree.getSelectionDetails()), KeyEvent.VK_A);
            metaaudit.addActionListener(this);
            add(metaaudit);
                    
	    delete = new JMenuItem(Dictionary.get("CollectionPopupMenu.Delete"), KeyEvent.VK_D);
	    delete.addActionListener(this);
	    add(delete);

            CollectionTreeNode firstSelectedNode = (CollectionTreeNode)selection_paths[0].getLastPathComponent();
            
 	    // The src doc replaceable (with html file) option is only available when all files selected are of the
	    // same type (same extension). For srcreplaceable files only. Works with replace_srcdoc_with_html.pl
	    
	    if(firstSelectedNode.isSrcReplaceable()) { // test the first selected node
		replace_srcdoc_with_html = new JMenuItem(Dictionary.get("Menu.Replace_SrcDoc_With_HTML"), KeyEvent.VK_H);
		replace_srcdoc_with_html.addActionListener(this);		
		add(replace_srcdoc_with_html);
		
		// Now the menu is there, grey it out if not all the files are of the same type
		if(!selectedFilesOfSameType(selection_paths)) {
		    replace_srcdoc_with_html.setEnabled(false);
		} 
	    }

	    // Unzip menu option is available if not remote GS
	    // and when all selected files are of .zip extension
	    if(!Gatherer.isGsdlRemote && firstSelectedNode.isZipFile()) { // test 1st selected node
		unzip_file = new JMenuItem(Dictionary.get("CollectionPopupMenu.Unzip"), KeyEvent.VK_U);
		unzip_file.addActionListener(this);		
		add(unzip_file);
		
		// Now the menu is there, grey it out if not all the files are of the same type
		if(!selectedFilesOfSameType(selection_paths)) {
		    unzip_file.setEnabled(false);
		} 
	    }
	    
	    // Only meta-audit and delete (and possibly replace_srcdoc and unzip_file)
	    // are available if multiple items are selected...
	    if (selection_paths.length > 1) {
		return;
	    }

	    // Rename option
	    rename = new JMenuItem(Dictionary.get("CollectionPopupMenu.Rename"), KeyEvent.VK_R);
	    rename.addActionListener(this);
	    add(rename);

	    TreePath path = selection_paths[0];
	    node = (FullCollectionTreeNode) path.getLastPathComponent();
            
	    // ---- Options for file nodes ----
	    if (node.isLeaf()) {
		// Explode metadata databases, for explodable files only
              if (((CollectionTreeNode)node).isExplodable()) {
		    explode_metadata_database = new JMenuItem(Dictionary.get("Menu.Explode_Metadata_Database"), KeyEvent.VK_E);
		    explode_metadata_database.addActionListener(this);
		    add(explode_metadata_database);
		}
		// Replace file
		replace = new JMenuItem(Dictionary.get("CollectionPopupMenu.Replace"), KeyEvent.VK_P);
		replace.addActionListener(this);
		add(replace);
		// Open the file in an external program
		open_externally = new JMenuItem(Dictionary.get("Menu.Open_Externally"), KeyEvent.VK_O);
		open_externally.addActionListener(this);
		add(open_externally);

		return;
	    }

	    // ---- Options for folder nodes ----
	    // Collapse or expand, depending on current status
	    if (collection_tree.isExpanded(path)) {
		collapse_folder = new JMenuItem(Dictionary.get("Menu.Collapse"), KeyEvent.VK_C);
		collapse_folder.addActionListener(this);
		add(collapse_folder);
	    }
	    else {
		expand_folder = new JMenuItem(Dictionary.get("Menu.Expand"), KeyEvent.VK_O);
		expand_folder.addActionListener(this);
		add(expand_folder);
	    }

	    // New folder/dummy doc options
	    if (!node.isReadOnly()) {
		new_folder = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_Folder"), KeyEvent.VK_N);
		new_folder.addActionListener(this);
		add(new_folder);

		
		new_file = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_File"));
		new_file.addActionListener(this);
		add(new_file);

                new_dummy_doc = new JMenuItem(Dictionary.get("CollectionPopupMenu.New_Dummy_Doc"));
                
		new_dummy_doc.addActionListener(this);
		add(new_dummy_doc);
	    }
	}


	/** Called whenever one of the menu items is clicked, this method then causes the appropriate effect. */
	public void actionPerformed(ActionEvent event)
	{

	    Object source = event.getSource();

            // we handle all our Gather panel tree specific cases here, then pass to FullCOllectionTree code for the common ones.

	    // Explode metadata database
	    if (source == explode_metadata_database) {
 		Gatherer.f_man.explodeMetadataDatabase(node.getFile());
	    }
	    
	    // Replace source document with generated html (works with replace_srcdoc_with_html.pl)
	    else if (source == replace_srcdoc_with_html) {
		File[] source_files = new File[selection_paths.length];
		for (int i = 0; i < selection_paths.length; i++) {
		    CollectionTreeNode node = (CollectionTreeNode) selection_paths[i].getLastPathComponent(); 
		    source_files[i] = node.getFile();
		}
		Gatherer.f_man.replaceSrcDocWithHtml(source_files); // passing the selected files
	    }

	    // Meta-audit
	    else if (source == metaaudit) {
 		Gatherer.g_man.showMetaAuditBox();
 	    }
	    // New dummy doc - instead of new empty file
	    else if (source == new_dummy_doc) {
              Gatherer.f_man.newDummyDoc(collection_tree, node);
              
            }
            else {
              super.actionPerformed(event);
            }

        }
      
    }
}

