// Copyright (c) 1995, 1996 Regents of the University of California.
// All rights reserved.
//
// This software was developed by the Arcadia project
// at the University of California, Irvine.
//
// Redistribution and use in source and binary forms are permitted
// provided that the above copyright notice and this paragraph are
// duplicated in all such forms and that any documentation,
// advertising materials, and other materials related to such
// distribution and use acknowledge that the software was developed
// by the University of California, Irvine.  The name of the
// University may not be used to endorse or promote products derived
// from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

// File: EditorMenus.java
// Classes: EditorMenus
// Original Author: ics125b spring 1996
// $Id: EditorMenus.java,v 1.7 1996/11/27 23:12:09 Exp $

// Modified by : Kedar Patankar

package EDU.neu.ccs.demeter.tools.apstudio.graphedit;

import java.util.Vector;
import java.util.Enumeration;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.MenuBar;
import java.awt.MenuShortcut;
import java.awt.Event;
import java.awt.CheckboxMenuItem;

import java.awt.event.KeyEvent;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;

import com.sun.java.swing.tree.DefaultMutableTreeNode;
/*Purpose:  the purpose of this class is to create the menu on the windows
    and to handle all menu events. */

public class EditorMenus implements ActionListener,ItemListener
{
	private Editor _editor;
	private MenuBar menuBar;
	private Vector openDocumentNames;
	private Vector windowMenuItems;
	private int MAX_ITEMS = 5;
	private String defaultString="*****";

	/* File Menu and its components */
	private Menu fileMenu;
	private MenuItem newItem;
	private MenuItem openItem;
	private MenuItem closeItem;
	private MenuItem closeallItem;
	private MenuItem saveItem;
	private MenuItem saveasItem;
	private MenuItem saveallItem;
	private MenuItem printItem;
	private MenuItem reloadItem;
	private MenuItem exitItem;

	/* Edit Menu and its components */
	private Menu editMenu;
	private MenuItem deleteItem;
	private MenuItem findItem;
	private MenuItem selectallItem;
	private MenuItem selectinvertItem;

	/*View Menu and its submenus and components */
	private Menu viewMenu;
	private MenuItem viewcdItem;
	private MenuItem clearItem;
	private MenuItem refreshItem;
	private Menu toolBarMenu;
	private CheckboxMenuItem standardItem;
	private CheckboxMenuItem umlItem;
	private CheckboxMenuItem viewDemItem;
	private CheckboxMenuItem propertyItem;
	private Menu alignMenu;
	private MenuItem alignTopsItem;
	private MenuItem alignBottomsItem;
	private MenuItem alignLeftsItem;
	private MenuItem alignRightsItem;
	
	/* Tools Menu and its submenus and componenets */
	private Menu toolsMenu;
	private MenuItem optionsItem;

	/* Behavior menu and its components */
	private Menu behaviorMenu;
	private MenuItem newBehItem;
	private MenuItem openBehItem;
	private MenuItem saveBehItem;
	private MenuItem closeBehItem;
	private MenuItem closeallBehItem;
	private MenuItem saveasBehItem;
	private MenuItem saveallBehItem;
	private Menu strategyMenu;
	private MenuItem newStratItem,previewStratItem,delStratItem,renStratItem;
	private CheckboxMenuItem simpleItem,advancedItem;
	private Menu strategyEdgeMenu;
	private MenuItem newEdgeItem,deleteEdgeItem;

	/* Window Menu */
	private Menu windowMenu;
	private CheckboxMenuItem firstItem;
	private CheckboxMenuItem secondItem;
	private CheckboxMenuItem thirdItem;
	private CheckboxMenuItem fourthItem;
	private CheckboxMenuItem fifthItem;
	private MenuItem moreItem;

	/* Help Menu and its componenets */
	private Menu helpMenu;
	private MenuItem topicsItem;
	private MenuItem aboutItem;


	/* Now Construct the Menu Bar for the Editor */
	public EditorMenus(Editor ce)
	{
		menuBar = new MenuBar();
		_editor=ce;

		/* Initialize the file menu */
		menuBar.add(fileMenu = new Menu("File"));

		fileMenu.add(newItem = new MenuItem("New"));
		newItem.setShortcut(new MenuShortcut(KeyEvent.VK_N));

		fileMenu.add(openItem = new MenuItem("Open"));
		openItem.setShortcut(new MenuShortcut(KeyEvent.VK_O));

		fileMenu.add(closeItem = new MenuItem("Close"));
		closeItem.setEnabled(false);
		fileMenu.add(closeallItem = new MenuItem("Close All"));
		closeallItem.setEnabled(false);
		fileMenu.addSeparator();

		fileMenu.add(saveItem = new MenuItem("Save"));
		saveItem.setShortcut(new MenuShortcut(KeyEvent.VK_S));

		saveItem.setEnabled(false);
		fileMenu.add(saveasItem = new MenuItem("Save As"));
		saveasItem.setEnabled(false);
		fileMenu.add(saveallItem = new MenuItem("Save All"));
		saveallItem.setEnabled(false);
		fileMenu.addSeparator();

		fileMenu.add(printItem = new MenuItem("Print"));
		printItem.setShortcut(new MenuShortcut(KeyEvent.VK_P));

		fileMenu.addSeparator();
		fileMenu.add(reloadItem = new MenuItem("Reload"));
		fileMenu.addSeparator();
		fileMenu.add(exitItem = new MenuItem("Exit"));

		newItem.addActionListener(this);
		openItem.addActionListener(this);
		closeItem.addActionListener(this);
		closeallItem.addActionListener(this);
		saveItem.addActionListener(this);
		saveasItem.addActionListener(this);
		saveallItem.addActionListener(this);
		printItem.addActionListener(this);
		reloadItem.addActionListener(this);
		exitItem.addActionListener(this);

		/* Initialize the edit Menu */
		menuBar.add(editMenu = new Menu("Edit"));
		editMenu.add(deleteItem = new MenuItem("Delete"));
		deleteItem.setEnabled(false);
		editMenu.addSeparator();
		editMenu.add(findItem = new MenuItem("Find"));
		findItem.setEnabled(false);
		editMenu.addSeparator();
		editMenu.add(selectallItem = new MenuItem("Select All"));
		selectallItem.setShortcut(new MenuShortcut(KeyEvent.VK_A));

		editMenu.add(selectinvertItem = new MenuItem("Invert Selection"));

		selectallItem.addActionListener(this);
		selectinvertItem.addActionListener(this);
		deleteItem.addActionListener(this);

		/* Initialize the view Menu */
		menuBar.add(viewMenu = new Menu("View"));
		viewMenu.add(viewcdItem = new MenuItem("Class Dictionary"));
		viewMenu.addSeparator();
		viewMenu.add(refreshItem = new MenuItem("Refresh"));
		viewMenu.add(clearItem = new MenuItem("Clear Preview"));
		viewMenu.addSeparator();
		viewMenu.add(toolBarMenu = new Menu("Toolbars"));
		toolBarMenu.add(standardItem= new CheckboxMenuItem("Standard"));
		toolBarMenu.add(umlItem= new CheckboxMenuItem("Class Graph"));
		umlItem.setState(true);
		standardItem.setState(true);

		viewMenu.add(viewDemItem = new CheckboxMenuItem("Strategy Panel"));
		viewDemItem.setState(true);
		viewMenu.add(propertyItem = new CheckboxMenuItem("Properties"));
		propertyItem.setState(true);
		viewMenu.addSeparator();
		viewMenu.add(alignMenu = new Menu("Align"));
		alignMenu.add(alignTopsItem = new MenuItem("Tops"));
		alignMenu.add(alignBottomsItem = new MenuItem("Bottoms"));
		alignMenu.add(alignLeftsItem = new MenuItem("Lefts"));
		alignMenu.add(alignRightsItem = new MenuItem("Rights"));
		alignMenu.setEnabled(false);
		
		viewcdItem.addActionListener(this);
		refreshItem.addActionListener(this);
		clearItem.addActionListener(this);
		alignTopsItem.addActionListener(this);
		alignBottomsItem.addActionListener(this);
		alignLeftsItem.addActionListener(this);
		alignRightsItem.addActionListener(this);

		viewDemItem.addItemListener(this);
		propertyItem.addItemListener(this);
		standardItem.addItemListener(this);
		umlItem.addItemListener(this);

		/* Initialise Tools Menu */
		menuBar.add(toolsMenu = new Menu("Tools"));
		toolsMenu.add(optionsItem = new MenuItem("Options"));
		optionsItem.setEnabled(false);

		/* Initialize the file menu */
		menuBar.add(behaviorMenu = new Menu("Behavior"));

		behaviorMenu.add(newBehItem = new MenuItem("New"));
		behaviorMenu.add(openBehItem = new MenuItem("Open"));
		behaviorMenu.add(closeBehItem = new MenuItem("Close"));
		closeBehItem.setEnabled(false);
		behaviorMenu.add(closeallBehItem = new MenuItem("Close All"));
		closeallBehItem.setEnabled(false);
		behaviorMenu.addSeparator();
		behaviorMenu.add(saveBehItem = new MenuItem("Save"));
		saveBehItem.setEnabled(false);
		behaviorMenu.add(saveasBehItem = new MenuItem("Save As"));
		saveasBehItem.setEnabled(false);
		behaviorMenu.add(saveallBehItem = new MenuItem("Save All"));
		saveallBehItem.setEnabled(false);
		behaviorMenu.addSeparator();
		behaviorMenu.add(strategyMenu = new Menu("Strategy Graph"));
		strategyMenu.setEnabled(false);
		strategyMenu.add(newStratItem = new MenuItem("New"));
		strategyMenu.addSeparator();
		strategyMenu.add(previewStratItem = new MenuItem("Preview"));
		previewStratItem.setEnabled(false);
		strategyMenu.add(delStratItem = new MenuItem("Delete"));
		delStratItem.setEnabled(false);
		strategyMenu.add(renStratItem = new MenuItem("Rename"));
		renStratItem.setEnabled(false);
		strategyMenu.addSeparator();
		strategyMenu.add(simpleItem = new CheckboxMenuItem("Simple"));
		simpleItem.setState(true);
		strategyMenu.add(advancedItem = new CheckboxMenuItem("Advanced"));
		advancedItem.setState(false);advancedItem.setEnabled(false);
		behaviorMenu.addSeparator();
		behaviorMenu.add(strategyEdgeMenu = new Menu("Strategy Edge"));
		strategyEdgeMenu.add(newEdgeItem = new MenuItem("New"));
		strategyEdgeMenu.add(deleteEdgeItem = new MenuItem("Delete"));
		newEdgeItem.setEnabled(false);
		deleteEdgeItem.setEnabled(false);
		strategyEdgeMenu.setEnabled(false);

		newBehItem.addActionListener(this);
		openBehItem.addActionListener(this);
		closeBehItem.addActionListener(this);
		closeallBehItem.addActionListener(this);
		saveBehItem.addActionListener(this);
		saveasBehItem.addActionListener(this);
		saveallBehItem.addActionListener(this);
		newStratItem.addActionListener(this);
		previewStratItem.addActionListener(this);
		delStratItem.addActionListener(this);
		renStratItem.addActionListener(this);
		simpleItem.addItemListener(this);
		advancedItem.addItemListener(this);
		newEdgeItem.addActionListener(this);
		deleteEdgeItem.addActionListener(this);

		/* Initialise Window Menu */
		menuBar.add(windowMenu=new Menu("Window"));
		firstItem=new CheckboxMenuItem(defaultString);
		secondItem=new CheckboxMenuItem(defaultString);
		thirdItem=new CheckboxMenuItem(defaultString);
		fourthItem=new CheckboxMenuItem(defaultString);
		fifthItem=new CheckboxMenuItem(defaultString);
		moreItem=new MenuItem("Windows");
		openDocumentNames=new Vector();
		windowMenuItems=new Vector(MAX_ITEMS);
		windowMenuItems.addElement(firstItem);
		windowMenuItems.addElement(secondItem);
		windowMenuItems.addElement(thirdItem);
		windowMenuItems.addElement(fourthItem);
		windowMenuItems.addElement(fifthItem);
		windowMenu.add(moreItem);
		
		firstItem.addItemListener(this);
		secondItem.addItemListener(this);
		thirdItem.addItemListener(this);
		fourthItem.addItemListener(this);
		fifthItem.addItemListener(this);

		moreItem.addActionListener(this);

		/* Initialize the help menu */
		menuBar.add(helpMenu = new Menu("Help"));
		menuBar.setHelpMenu(helpMenu);
		helpMenu.add(topicsItem = new MenuItem("User's guide ..."));
		helpMenu.addSeparator();
		helpMenu.add(aboutItem = new MenuItem("About"));

		topicsItem.addActionListener(this);
		aboutItem.addActionListener(this);
		
		_editor.setMenuBar(menuBar);
	}/* constructor */

	public void setMenuPropertySheetState(boolean status){ propertyItem.setState(status);}

	public void menuFornoSelection()
	{
		deleteItem.setEnabled(false);
		alignMenu.setEnabled(false);
	}
	
	public void menuForsingleSelection()
	{
		deleteItem.setEnabled(true);
		alignMenu.setEnabled(false);
	}

	public void menuFormultipleSelection()
	{
		deleteItem.setEnabled(true);
		alignMenu.setEnabled(true);
	}

	public void refresh(){flushWindowTable();}
	
	public void refresh(String s)
	{
		if(openDocumentNames.contains(s))
		{
			openDocumentNames.removeElement(s);
			revampWindowTable();
			flushMenuItems();
		}
		else
		{
			openDocumentNames.addElement(s);
			revampWindowTable();
			flushMenuItems();
			setCurrentMenuString(s);
		}
		
		if(openDocumentNames.size()<=0)
		{
			saveItem.setEnabled(false);
			saveasItem.setEnabled(false);
			saveallItem.setEnabled(false);
			closeItem.setEnabled(false);
			closeallItem.setEnabled(false);
			printItem.setEnabled(false);
			refreshItem.setEnabled(false);
			clearItem.setEnabled(false);
			selectallItem.setEnabled(false);
			selectinvertItem.setEnabled(false);
			reloadItem.setEnabled(false);
		}
		else
		{
			saveItem.setEnabled(true);
			saveasItem.setEnabled(true);
			saveallItem.setEnabled(true);
			closeItem.setEnabled(true);
			closeallItem.setEnabled(true);
			printItem.setEnabled(true);
			refreshItem.setEnabled(true);
			clearItem.setEnabled(true);
			selectallItem.setEnabled(true);
			selectinvertItem.setEnabled(true);
			reloadItem.setEnabled(true);
		}
	}

	public void setCurrentMenuString(String s)
	{
		boolean set=false;
		Vector v=_editor.get_outStanding();
		
		for(Enumeration items=windowMenuItems.elements();items.hasMoreElements();)
		{
			CheckboxMenuItem m=(CheckboxMenuItem)items.nextElement();
			m.setState(false);
			if(m.getLabel().equals(s+" *")||m.getLabel().equals(s))
			{
				m.setState(true);
				set=true;
			}
		}
		
		if(!set)
		{
			if (v.contains(s))
				s+=" *";
			fifthItem.setLabel(s);
			fifthItem.setState(true);
		}
	}

	private void flushWindowTable()
	{
		revampWindowTable();
		flushMenuItems();
	}

	private void revampWindowTable()
	{
		Enumeration items=windowMenuItems.elements();
		for(int i=0;i<MAX_ITEMS;i++)
			((CheckboxMenuItem)items.nextElement()).setLabel(defaultString);
		
		int loopCount=Math.min(openDocumentNames.size(),windowMenuItems.size());
		Enumeration names=openDocumentNames.elements();
		items=windowMenuItems.elements();
		Vector v=_editor.get_outStanding();
		for(int i=0;i<loopCount;i++)
		{
			String s=(String)names.nextElement();
			if (v.contains(s))
				s+=" *";
			((CheckboxMenuItem)items.nextElement()).setLabel(s);
		}
	}

	private void flushMenuItems()
	{
		while(windowMenu.getItemCount()>0)
			windowMenu.remove(0);

		Enumeration items=windowMenuItems.elements();
		while(items.hasMoreElements())
		{
			CheckboxMenuItem m=(CheckboxMenuItem)items.nextElement();
			if(m.getLabel().equals(defaultString))
				break;
			else
				windowMenu.add(m);
		}
/* It seems there is a bug in windows NT j++. countItems() doesn't provide correct
information. It doesn't count separators */

	  windowMenu.addSeparator();
		windowMenu.add(moreItem);
	}
	
	public void setMenuforBehavior()
	{
		closeBehItem.setEnabled(true);
		closeallBehItem.setEnabled(true);
		saveBehItem.setEnabled(true);
		saveasBehItem.setEnabled(true);
		saveallBehItem.setEnabled(true);
		strategyMenu.setEnabled(true);
		newStratItem.setEnabled(true);
		delStratItem.setEnabled(false);
		renStratItem.setEnabled(false);
		previewStratItem.setEnabled(false);
		strategyEdgeMenu.setEnabled(false);
	}
	public void setMenuforSGraph()
	{
		closeBehItem.setEnabled(false);
		closeallBehItem.setEnabled(false);
		saveBehItem.setEnabled(false);
		saveasBehItem.setEnabled(false);
		saveallBehItem.setEnabled(false);
		strategyMenu.setEnabled(true);
		newStratItem.setEnabled(false);
		delStratItem.setEnabled(true);
		renStratItem.setEnabled(true);
		previewStratItem.setEnabled(true);
		strategyEdgeMenu.setEnabled(true);
		newEdgeItem.setEnabled(true);
		deleteEdgeItem.setEnabled(false);
	}
	public void setMenuforSEdge()
	{
		closeBehItem.setEnabled(false);
		closeallBehItem.setEnabled(false);
		saveBehItem.setEnabled(false);
		saveasBehItem.setEnabled(false);
		saveallBehItem.setEnabled(false);
		strategyMenu.setEnabled(false);
		strategyEdgeMenu.setEnabled(true);
		newEdgeItem.setEnabled(false);
		deleteEdgeItem.setEnabled(true);
	}
	public void setMenuforNoBeh()
	{
		closeBehItem.setEnabled(false);
		closeallBehItem.setEnabled(false);
		saveBehItem.setEnabled(false);
		saveasBehItem.setEnabled(false);
		saveallBehItem.setEnabled(false);
		strategyMenu.setEnabled(false);
		strategyEdgeMenu.setEnabled(false);
	}

  /**
   *  Method	:  handleMenuEvent
   *  Purpose	:  To handle all menu events
   *  Note		:  This function is called from sampleEditorWindows
   *		:  handleMenuEvent
   **/

	public void actionPerformed(ActionEvent event)
	{
		Document document = _editor.curDocument();
		Action act=null;
		Object source = event.getSource();

		if (source==newItem)
			act=new ActionNew(_editor);
		else if (source == openItem)
			act = new ActionOpen(_editor);
		else if(source==closeItem)
			act=new ActionClose(_editor,document);
		else if(source==closeallItem)
			act=new ActionCloseall(_editor);
		else if (source == saveItem)
			{
				if(!document.gcdNeedsSaving()&&(!document.firstTime())) return;
				act = new ActionSave(_editor,document);
			}
		else if (source == saveasItem)
			act = new ActionSaveAs(_editor,document);
		else if (source ==saveallItem)
			act = new ActionSaveall(_editor);
		else if (source == printItem)
			act = new ActionPrint(_editor);
		else if (source == exitItem)
			act = new ActionQuit(_editor);

		else if (source == reloadItem)
			act = new ActionReload(_editor,document);
		else if (source == deleteItem)
			act = new ActionDispose(_editor,document);
		else if (source == selectallItem)
			act = new ActionSelectAll(document);
		else if (source == selectinvertItem)
			act = new ActionSelectInvert(document);

		
		else if (source==viewcdItem)
			act = new ActionDisplayCd(_editor,document);
		else if (source==clearItem)
			act = new ActionClearPreview(document);
		else if (source==refreshItem)
			act = new ActionRefresh(document);

		else if (source == alignTopsItem)
			act = new ActionAlign(ActionAlign.ALIGN_TOPS,document);
		else if (source == alignBottomsItem)
			act = new ActionAlign(ActionAlign.ALIGN_BOTTOMS,document);
		else if (source == alignLeftsItem)
			act = new ActionAlign(ActionAlign.ALIGN_LEFTS,document);
		else if (source == alignRightsItem)
			act = new ActionAlign(ActionAlign.ALIGN_RIGHTS,document);

		else if (source == newBehItem)
			act = new ActionNewBehavior(_editor);
		else if (source == openBehItem)
			act = new ActionOpenBeh(_editor);
		else if (source == closeBehItem)
			{
				DefaultMutableTreeNode node = _editor.getCurrentBehaviorNode();
				if(node==null) return;
				act = new ActionCloseBeh(_editor,node);
			}
		else if (source == closeallBehItem)
			{
				DefaultMutableTreeNode node = _editor.getBehaviorRoot();
				act = new ActionCloseallBeh(_editor,node);
			}
		else if (source == saveBehItem)
			{
				DefaultMutableTreeNode node = _editor.getCurrentBehaviorNode();
				if(node==null) return;
				BehaviorNode behavior = (BehaviorNode) node.getUserObject();
				if(!behavior.needsSaving()&&(!behavior.isFirstTime())) return;
				act = new ActionSaveBeh(_editor,node);
			}
		else if (source == saveasBehItem)
			{
				DefaultMutableTreeNode node = _editor.getCurrentBehaviorNode();
				if(node==null) return;
				act = new ActionSaveAsBeh(_editor,node);
			}
		else if (source == saveallBehItem)
			{
				DefaultMutableTreeNode node = _editor.getBehaviorRoot();
				act = new ActionSaveallBeh(_editor,node);
			}

		else if (source == newStratItem)
			act = new ActionNewSGraph(_editor);
		else if (source == newEdgeItem)
			act = new ActionNewSEdge(_editor);
		else if (source == previewStratItem)
			act = new ActionDoPreview(_editor);
		else if (source == deleteEdgeItem)
			act = new ActionRemoveSEdge(_editor);
		else if (source == delStratItem)
			act= new ActionRemoveGraph(_editor);
		else if (source == renStratItem)
			act= new ActionRenSGraph(_editor);

		else if (source == aboutItem)
			act = new ActionShowAbout(_editor);
		else if (source == topicsItem)
			act = new ActionShowContent(_editor);
		else if (source == moreItem)
			act = new ActionShowDocuments(_editor,openDocumentNames);

		_editor.executeAction(act, event);
	}
	
	public void itemStateChanged(ItemEvent event)
	{
		Object source = event.getSource();

		if (source==viewDemItem)
			_editor.showDemeterPanel(viewDemItem.getState());
		else
		if (source==propertyItem)
			_editor.showPropertyWindow(propertyItem.getState());
		else
		if (source==simpleItem)
			simpleItem.setState(true);
		else
		if (source == standardItem)
			_editor.showSystemToolbar(standardItem.getState());
		else
		if (source == umlItem)
			_editor.showUmlToolbar(umlItem.getState());
		else
			checkWindowMenu(_editor,source);
	}

	private void checkWindowMenu(Editor editor,Object source)
	{
		for(Enumeration items=windowMenuItems.elements();items.hasMoreElements();)
			((CheckboxMenuItem)items.nextElement()).setState(false);

		Enumeration items=windowMenuItems.elements();
		for (int i=0;i<MAX_ITEMS;i++)
		{
			CheckboxMenuItem m=(CheckboxMenuItem)items.nextElement();
			m.setState(false);
			if (source==m)
			{
				String s=m.getLabel();
				int a = s.lastIndexOf(" *");
				if (a>0)
					s = s.substring(0,a);
				editor.showDocument(s);
				m.setState(true);
				return;
			}
		}
	}

} /* end class EditorMenus */

