/*
 * @(#)OptionMainJPanel.java
 *
 * Last Modified: 9/01/02
 */


import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.net.*;



/**
 * OptionMainJPanel for use as the controlling panel for all of the other built panels.
 *
 *
 * <p>
 * @author  Corey Sanders
 * @version 1.8 9/01/02
 * @see TreeJApplet
 * @see TreeJPanel
 */
public class OptionMainJPanel extends OptionJPanel implements ActionListener, MouseListener,MouseMotionListener, OptionListener, TreeMessageListener  {

	/**
	 * Id for the control panel.
	 */
	protected static int id = OptionEvent.MAIN_OPTION_PANEL;

	/**
	 * List of the listeners to the tree messages.
	 */
	private LinkedList treeListeners;

	/**
	 * PopupMenu to hold the menu for the options.
	 */
	private JPopupMenu popup = new JPopupMenu();

	/**
	 * The currently selected drawingTree.
	 */
	private DrawingTree currentNode;

	/**
	 * The currently selected TreeJPanel.
	 */
	private TreeJPanel currentPanel;

	/**
	 * OptionControlsJPanel used in this main panel.
	 */
	private OptionControlsJPanel optionControls;

	/**
	 * TreeJPanel that is the last call to a popup.
	 */
	private TreeJPanel popupPanel;

  /**
	* This constructor makes the Main Option JPanel for usage with <code>TreeJApplet</code>. It keeps
	* the tabbed pane and all of the panels for options.
	*
    * @param codebase URL codebase for the applet, to get the images.
 	*/
   public OptionMainJPanel() {

		super();

		setPreferredSize(new Dimension(400, 80));

		setBackground(Color.white);


		treeListeners = new LinkedList();

		optionControls = new OptionControlsJPanel();

		optionControls.addOptionListener(this);

		this.addTreeMessageListener(optionControls);

		setLayout(new BorderLayout());

        add(optionControls, BorderLayout.CENTER);

    }

	/**
	 * Sets the display of the display Panel in this control bar.
	 */
	 public void setDisplayPanelShow(boolean displayPanelShow) {
		 optionControls.setDisplayPanelShow(displayPanelShow);
	}

	/**
	 * Gets the display of the display Panel in this control bar.
	 */
	 public boolean getDisplayPanelShow() {
		 return optionControls.getDisplayPanelShow();
	}

	/**
	 * Sets the display of the display Panel in this control bar.
	 */
	 public void setMessagePanelShow(boolean messagePanelShow) {
		 optionControls.setMessagePanelShow(messagePanelShow);
	}

	/**
	 * Gets the display of the display Panel in this control bar.
	 */
	 public boolean getMessagePanelShow() {
		 return optionControls.getMessagePanelShow();
	}

	/**
	 * Sets the display of the animation Panel in this control bar.
	 */
	 public void setAnimationPanelShow(boolean animationPanelShow) {
		optionControls.setAnimationPanelShow(animationPanelShow);
	}

	/**
	 * Gets the display of the animation Panel in this control bar.
	 */
	 public boolean getAnimationPanelShow() {
		 return  optionControls.getAnimationPanelShow();
	}

	/**
	 * Redraws  the control panel.
	 */
	public void redrawControlPanel() {
		optionControls.redrawControlPanel();
	}



	/**
	 * Option event listener. The result of an optionEvent being performed depends upon the event.
	 * Within the desktop, the events are used or passed on to the trees accordingly. Here the
	 * separating of the events takes place.
	 *
	 * @param e OptionEvent passed with information about the event.
	 */
	public void optionEventPerformed(OptionEvent e) {

		/**********************/
		/* Effects all trees  */
		/**********************/

		if (e.getActionCommand().equals(OptionEvent.MESSAGE_ALL)) {
			optionControls.setMessageMode(OptionControlsJPanel.MESSAGE_ON);
		}
		else if (e.getActionCommand().equals(OptionEvent.MESSAGE_FINAL_ONLY)) {
			optionControls.setMessageMode(OptionControlsJPanel.MESSAGE_FINAL_ONLY);
		}
		else if (e.getActionCommand().equals(OptionEvent.MESSAGE_OFF)) {
			optionControls.setMessageMode(OptionControlsJPanel.MESSAGE_OFF);
		}
		else if (
			(e.getActionCommand().equals(OptionEvent.INSERT))
			|| (e.getActionCommand().equals(OptionEvent.DELETE))
			|| (e.getActionCommand().equals(OptionEvent.SEARCH))
			|| (e.getActionCommand().equals(OptionEvent.SELECT))
			)
		{
			optionAction(e);
		}


		/****************************/
		/* Goes through Desktop     */
		/****************************/
		else if (
				(e.getActionCommand().equals(OptionEvent.WINDOWS))
			||  (e.getActionCommand().equals(OptionEvent.TABBED_PANE))
		   )
		{
			optionAction(e);
		}

		/****************************/
		/* Current Panel Commands   */
		/****************************/

		else if (
				(e.getActionCommand().equals(OptionEvent.CLEAR))
			|| 	(e.getActionCommand().equals(OptionEvent.BALANCE))
			|| 	(e.getActionCommand().equals(OptionEvent.GET_STATUS))
		   ) {
			optionAction(e);
		}

		/****************************/
		/* All Panel Commands       */
		/****************************/
		else if (
				(e.getActionCommand().equals(OptionEvent.CLEAR_ALL))
			|| 	(e.getActionCommand().equals(OptionEvent.BALANCE_ALL))
			|| 	(e.getActionCommand().equals(OptionEvent.GET_STATUS_ALL))
			|| 	(e.getActionCommand().equals(OptionEvent.PROGRAM_INFORMATION))
			||  (e.getActionCommand().equals(OptionEvent.TREE_INFORMATION))
			||  (e.getActionCommand().equals(OptionEvent.INPUT_CHANGE_ALL))
		   ) {
			  optionAction(e);
		}

		/************************/
		/* Animation Commands   */
		/************************/
		else {
			optionAction(e);
		}
	}

	/************************/
	/* Clicks Commands      */
	/************************/

	/**
	 * Select Click command.
	 *
	 * @param node the Tree node to select from.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void selectClickCommand(Tree node, OptionListener optionListener ) {
		optionAction(OptionEvent.SELECT_CLICK, node, optionListener);
	}

	/**
	 * Delete Click command.
	 *
	 * @param node the Tree node to delete from.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void deleteClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.DELETE_CLICK, node, optionListener);
	}

	/**
	 * Balance Click command.
	 *
	 * @param node the Tree node to balance from.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void balanceClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.BALANCE_CLICK, node, optionListener);
	}

	/**
	 * Rotate Click command.
	 *
	 * @param node the Tree node to rotate from.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void rotateClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.ROTATE_CLICK, node, optionListener);
	}

	/**
	 * Rotate to top Click command.
	 *
	 * @param node the Tree node to rotate to the top.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void rotateTopClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.ROTATE_TOP_CLICK, node, optionListener);
	}

	/**
	 * Double rotate Click command.
	 *
	 * @param node the Tree node to double rotate.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void rotateDoubleClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.ROTATE_DOUBLE_CLICK, node, optionListener);
	}

	/**
	 * Splay Click command.
	 *
	 * @param node the Tree node to splay.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void splayClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.SPLAY_CLICK, node, optionListener);
	}

	/**
	 * Partition Click command.
	 *
	 * @param node the Tree node to partition from.
	 * @param optionListener the listener for the optionAction.
	 *
	 */
	protected void partitionClickCommand(Tree node, OptionListener optionListener) {
		optionAction(OptionEvent.PARTITION_CLICK, node, optionListener);
	}


	/**
	 * Adds an TreeMessageListener from the TREE, according to
	 * the TreeMessageListener interface and the <code>TreeMessageEvent</code>.
	 *
	 * @param l the listener added recieves the TreeMessageEvents occuring.
	 */
	public void addTreeMessageListener(TreeMessageListener l) {
		treeListeners.add(l);
	}

	/**
	 * Removes an TreeMessageListener from the TREE, according to
	 * the TreeMessageListener interface and the <code>TreeMessageEvent</code>.
	 *
	 * @param l the listener removed from recieving the TreeMessageEvents occuring.
	 */
	public void removeTreeMessageListener(TreeMessageListener l) {
		treeListeners.remove(l);
	}

	/**
	 * Calls all of the treeListeners of the Tree and passes the tree message information information regarding the
	 * status of the Tree.
	 */
	protected void messageAction(String msg, Object msgObj) {
		TreeMessageEvent messageEvent = new TreeMessageEvent(this, TreeMessageEvent.PANEL, msg, msgObj);
		messageAction(messageEvent);
	}

	/**
	 * Calls all of the treeListeners of the Tree and passes the tree message information information regarding the
	 * status of the Tree.
	 */
	protected void messageAction(TreeMessageEvent treeMessageEvent) {
		ListIterator list = treeListeners.listIterator(0);
		while (list.hasNext()) {
			((TreeMessageListener)list.next()).treeMessageEventPerformed(treeMessageEvent);
		}
	}


	/**
	 * If an action is performed through one of the buttons.
	 *
	 * @param e ActionEvent that contains information about the action performed.
	 */
	public void actionPerformed(ActionEvent e) {
		// Command of action
		String command = e.getActionCommand();

		/************************/
		/* Clicks               */
		/************************/

		if (command.equals(OptionEvent.SELECT_CLICK)) {
			selectClickCommand(currentNode, currentPanel);
		}

		if (command.equals(OptionEvent.DELETE_CLICK)) {
			deleteClickCommand(currentNode, currentPanel);
		}
		if (command.equals(OptionEvent.BALANCE_CLICK)) {
			balanceClickCommand(currentNode, currentPanel);
		}
		if (command.equals(OptionEvent.ROTATE_CLICK)) {
			rotateClickCommand(currentNode, currentPanel);
		}
		if (command.equals(OptionEvent.ROTATE_TOP_CLICK)) {
			rotateTopClickCommand(currentNode, currentPanel);
		}
		if (command.equals(OptionEvent.ROTATE_DOUBLE_CLICK)) {
			rotateDoubleClickCommand(currentNode, currentPanel);
		}
		if (command.equals(OptionEvent.SPLAY_CLICK)) {
			splayClickCommand(currentNode, currentPanel);
		}
		if (command.equals(OptionEvent.PARTITION_CLICK)) {
			partitionClickCommand(currentNode, currentPanel);
		}

	}

	/**
	 * mouseClicked command. No action.
	 */
	public void mouseClicked(MouseEvent e) {}

	/**
	 * mouseEntered command. No action.
	 */
	public void mouseEntered(MouseEvent e) {}

	/**
	 * mouseExited command. No action.
	 */
	public void mouseExited(MouseEvent e) {}




	/**
	 * MousePressed command.
	 *
	 * @param e The mouseEvent for the pressing of the mouse.
	 */
	public void mousePressed(MouseEvent e) {



		TreeJPanel tempPanel = ((TreeJPanel)e.getSource());

		DrawingTree tempNode = tempPanel.getTree().findNode(e.getX(), e.getY());

		if(tempNode != null) {
			currentNode = tempNode;
			currentPanel = tempPanel;

			if (currentPanel != popupPanel) {
				popupPanel = currentPanel;
				popup = popupPanel.makeJPopupMenu(this);
		 		popup.setBackground(Color.white);
			}

    		popup.show(e.getComponent(), e.getX(), e.getY());

		}

	}


	/**
	 * MouseReleased command. No action.
	 */
	public void mouseReleased(MouseEvent e) {}
	/**
	 * MouseDragged command. No action.
	 */
	public void mouseDragged(MouseEvent e) {}

	/**
	 * MouseMoved command.
	 *
	 * @param e The mouseEvent for the moving of the mouse.
	 */
	public void mouseMoved(MouseEvent e) {
		DrawingTree tempNode = ((TreeJPanel)e.getSource()).getTree().findNode(e.getX(), e.getY());

		if (tempNode != currentNode && !popup.isVisible()) {

			currentPanel = ((TreeJPanel)e.getSource());
			currentNode = tempNode;

			optionControls.setDiplayPanelDrawNode(tempNode);
			optionControls.setDisplayPanelBackground(currentPanel.getBackground());

			if (tempNode != null) {
				optionControls.setDisplayPanelBorder("("+(int)currentNode.getCurrentTransform().getTranslateX()+","+(int)currentNode.getCurrentTransform().getTranslateY()+")");
			}
			else {
				optionControls.setDisplayPanelBorder("No Node");
			}

		}


	}

	/**
	 * Tree Message Event performed.
	 *
	 * @param e TreeMessageEvent.
	 */
	public void treeMessageEventPerformed(TreeMessageEvent e) {
		messageAction(e);

	}


}


