package j3deditor.bin.hierarchy.view;


import j3deditor.bin.InnerFrame;

import j3deditor.bin.hierarchy.HierarchyNode;
import j3deditor.bin.hierarchy.util.Copyable;
import j3deditor.bin.hierarchy.util.Cuttable;
import j3deditor.bin.hierarchy.util.Deletable;
import j3deditor.bin.hierarchy.util.Pasteable;

import j3deditor.bin.util.Utilities;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JDesktopPane;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;


/**
 * Hierarchy Manager window.
 *
 * @author Risto Seene
 */
public class HierarchyFrame extends InnerFrame implements ActionListener, TreeSelectionListener{

	/** tool that shows root node and its descendants in <code>JTree</code> */
	private HierarchyViewer hierarchy;


	/** <code>JMenuItem</code> for updating the tree */
	private JMenuItem update;

	/** <code>JMenuItem</code> for cutting selected nodes */
	private JMenuItem cut;

	/** <code>JMenuItem</code> for copying selected nodes */
	private JMenuItem copy;

	/** <code>JMenuItem</code> for pasting selected nodes */
	private JMenuItem paste;

	/** <code>JMenuItem</code> for deleting selected nodes */
	private JMenuItem delete;


	/**
	 * Creates an instance of <code>HierarchyFrame</code>
	 * using the reference to the central
	 * <code>Utilities</code> object,
	 * <code>JDesktopPane</code> it will be attached to
	 * and <code>HierarchyNode</code> as the root node for its
	 * <code>HierarchyViewer</code>.
	 *
	 * @param parent
	 *	<code>JDesktopPane</code> this frame will be attached to
	 */
	public HierarchyFrame(JDesktopPane parent){
		setTitle(Utilities.translator.translate(getClass(), "title"));
		setFrameIcon(Utilities.image.getImageIcon("icons/hierarchy.png"));
		setSize(300, parent.getHeight());

		initMenu();
		initContent();

		showWindow(parent);
		hierarchy.setSelection();
	}


	/**
	 * Initializes the menubar and all its items
	 */
	private void initMenu(){
		JMenuBar menubar = new JMenuBar();

		JMenu hmenu = new JMenu(Utilities.translator.translate(getClass(), "hmenu"));
		update = new JMenuItem(Utilities.translator.translate(getClass(), "update"));
		cut = new JMenuItem(Utilities.translator.translate(getClass(), "cut"));
		copy = new JMenuItem(Utilities.translator.translate(getClass(), "copy"));
		paste = new JMenuItem(Utilities.translator.translate(getClass(), "paste"));
		delete = new JMenuItem(Utilities.translator.translate(getClass(), "delete"));

		setJMenuBar(menubar);

		menubar.add(hmenu);
		hmenu.add(update);
		hmenu.addSeparator();
		hmenu.add(cut);
		hmenu.add(copy);
		hmenu.add(paste);
		hmenu.add(delete);
		hmenu.addSeparator();

		update.addActionListener(this);
		cut.addActionListener(this);
		copy.addActionListener(this);
		paste.addActionListener(this);
		delete.addActionListener(this);
	}


	/**
	 * Initializes the content of this frame
	 */
	private void initContent(){
		hierarchy = new HierarchyViewer(Utilities.hierarchy);
		add(hierarchy);
		hierarchy.setSelectionListener(this);
		valueChanged(null);
	}


	/**
	 * Listens to tree selection events performed on
	 * <code>HierarchyViewer</code> attached to this frame.
	 * Enables and disables the menu items according to selected
	 * nodes
	 *
	 * @param e
	 *	<code>TreeSelectionEvent</code> by <code>HierarchyViewer</code>
	 */
	public void valueChanged(TreeSelectionEvent e){
		HierarchyNode[] nodes = Utilities.hierarchy.getSelectedObjects();
		boolean cuttable = false;
		boolean copyable = false;
		boolean pasteable = false;
		boolean deletable = false;

		try{
			for(int i = 0; i < nodes.length; i++){
				if(nodes[i] instanceof Cuttable){
					cuttable = true;
				}
				if(nodes[i] instanceof Copyable){
					copyable = true;
				}
				if(nodes[i] instanceof Pasteable && Utilities.hierarchy.hasCopiedObjects()){
					pasteable = true;
				}
				if(nodes[i] instanceof Deletable){
					deletable = true;
				}
			}
		} catch(Throwable t){
		}

		cut.setEnabled(cuttable);
		copy.setEnabled(copyable);
		paste.setEnabled(pasteable);
		delete.setEnabled(deletable);
	}


	/**
	 * Listens actions performed on
	 * menubar items.
	 *
	 * @param e
	 *	<code>ActionEvent</code> sent by a menubar item
	 */
	public void actionPerformed(ActionEvent e){
		if(e.getSource() == update){
			hierarchy.setSelection();
		} else if(e.getSource() == cut){
			Utilities.hierarchy.cutFromScenes();
			hierarchy.setSelection();
		} else if(e.getSource() == copy){
			Utilities.hierarchy.copyFromScenes();
			hierarchy.setSelection();
		} else if(e.getSource() == paste){
			Utilities.hierarchy.pasteToScenes();
			hierarchy.setSelection();
		} else if(e.getSource() == delete){
			Utilities.hierarchy.deleteFromScenes();
			hierarchy.setSelection();
		}
	}


	/**
	 * Removes all components from this frame.
	 */
	@Override
	public void cleanUp(){
		this.hierarchy = null;
		super.cleanUp();
	}
}
