// File: Editor.java
// Classes: Editor
// Author: Kedar Patankar

package EDU.neu.ccs.demeter.tools.apstudio.graphedit;

import java.util.Vector;
import java.awt.Frame;
import java.awt.Event;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Color;
import java.awt.MenuItem;
import java.awt.Menu;
import java.awt.Toolkit;
import java.awt.Panel;
import java.awt.Label;
import java.awt.PrintJob;
import java.awt.Graphics;
import java.awt.AWTEvent;
import java.awt.Insets;
import java.awt.Dimension;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

import java.awt.PopupMenu;

import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import com.sun.java.swing.tree.DefaultMutableTreeNode;

/* Purpose : This is the main class of apstudio. This is backbone of the entire application */

public class Editor extends Frame implements ActionListener
{
	// Editor is composed of Menubar _menu, SystemToolBar _toolBar, Panel _mainPanel
	// and Message text at the bottom _statusInfo
	private EditorMenus _menu;
	private PopupMenu popMenu;
	private Menu definitionMenu;
	private MenuItem reorderItem,deleteItem,propertiesItem,fromItem,toItem,bypassingItem,onlythroughItem;

	private SystemToolPanel _toolBar;
//****************************************************//
// Alternate lines for win95 and Solaris
//	private JSplitPane	_mainPanel;
	private Panel _mainPanel;
//****************************************************//
	PopupMenu p; 
	private Label _statusInfo;
	private PropertyWindow _pw;
	// _mainPanel is composed of Panel _demeterPanel, CdPanel _cdPanel
	private CdPanel _cdPanel;
	private StrategyPanel _strategyPanel;

	private String INSTALL_DIR,READ_DIR,WRITE_DIR;

	public final static int DELETENODE=0;
	public final static int ADDNODE=1;
	
	private String _title;
	public void setDefaultMessage()
	{
		if(curDocument()==null)
			setMessage("Open new or available class dictionary to start");
		else
			curDocument().mode().setMessage(this);
	}

// Make menu consistent
	public void setMenuPropertySheetState(boolean status){ _menu.setMenuPropertySheetState(status);}
	public void menuFornoSelection(){_menu.menuFornoSelection();}
	public void menuForsingleSelection(){_menu.menuForsingleSelection();}
	public void menuFormultipleSelection(){_menu.menuFormultipleSelection();}
	public void setCurrentMenuString(String s){_menu.setCurrentMenuString(s);}
// Delegate to property window
	public void showDefaultPropertySheet(Document d){_pw.showDefault(d);}
	public void showVertexPropertySheet(Perspective p){_pw.showVert(p);}
	public void showEdgePropertySheet(ArcPerspective a){_pw.showEdge(a);}
	public void showBlankPropertySheet(){_pw.showBlankPropertySheet();}
	public void showPropertyWindow(boolean status){ _pw.setVisible(status); }
//delegate to the strategyPanel
	public Vector get_Mod_Behaviors(){return _strategyPanel.get_Mod_Behaviors();}
	public void addNewBehavior(){_strategyPanel.addNewBehavior();}
	public DefaultMutableTreeNode addBehavior(String name){return _strategyPanel.addBehavior(name);}
	public DefaultMutableTreeNode addStrategyGraph(DefaultMutableTreeNode node,String name)
	{return _strategyPanel.addStrategyGraph(node,name);}
	public DefaultMutableTreeNode addStrategyEdge(DefaultMutableTreeNode node)
	{return _strategyPanel.addStrategyEdge(node);}
	public void addFrom(DefaultMutableTreeNode node,String name){_strategyPanel.addFrom(node,name);}
	public void addTo(DefaultMutableTreeNode node,String name){_strategyPanel.addTo(node,name);}
	public void addBypassV(DefaultMutableTreeNode node,String name){_strategyPanel.addBypassV(node,name);}
	public void addOnlyThroughV(DefaultMutableTreeNode node,String name){_strategyPanel.addBypassV(node,name);}
	public void addBypassE(DefaultMutableTreeNode node,String from,String name,String to)
	{
		_strategyPanel.addBypassE(node,from,name,to);		
	}
	public void addOnlyThroughE(DefaultMutableTreeNode node,String from,String name,String to)
	{
		_strategyPanel.addOnlyThroughE(node,from,name,to);		
	}
	public boolean isBehaviorAlreadyOpen(String filename){return _strategyPanel.isBehaviorAlreadyOpen(filename);}

	public void detach(DefaultMutableTreeNode node){_strategyPanel.removeBehavior(node);}
	public DefaultMutableTreeNode getBehaviorRoot(){return _strategyPanel.getBehaviorRoot();}
	public DefaultMutableTreeNode getCurrentBehaviorNode(){return _strategyPanel.getCurrentBehaviorNode();}
	public void justSavedBehavior(String oldname, String newname){_strategyPanel.justSavedBehavior(oldname,newname);}
	public void addStrategyGraph(){_strategyPanel.addStrategyGraph();}
	public void removeStrategyGraph(){_strategyPanel.removeStrategyGraph();}
	public void addStrategyEdge(){_strategyPanel.addStrategyEdge();}
	public void removeStrategyEdge(){_strategyPanel.removeStrategyEdge();}
	public DefaultMutableTreeNode getSelectedTreeNode(){return _strategyPanel.getSelectedNode();}
	public void nodeNameChanged(DefaultMutableTreeNode node){_strategyPanel.nodeNameChanged(node);}

	public void doPreview(){_strategyPanel.doPreview();}
	public boolean shouldTravPopup(){return _strategyPanel.shouldTravPopup();}
	public void addFrom(String name){ _strategyPanel.addFrom(name);}
	public void addTo(String name){_strategyPanel.addTo(name);}
	public void addBypassV(String name){ _strategyPanel.addBypassV(name);}
	public void addOnlyThroughV(String name){ _strategyPanel.addOnlyThroughV(name);}
	public void addBypassE(String from,String name,String to){_strategyPanel.addBypassE(from,name,to);}
	public void addOnlyThroughE(String from,String name,String to){_strategyPanel.addOnlyThroughE(from,name,to);}
// Delegate to cdpanel
	public boolean isPresent(String s){ return _cdPanel.isPresent(s);}
	public void showUmlToolbar(boolean status){_cdPanel.showUmlToolbar(status);}

	public int getNoOfOpenDocuments(){ return _cdPanel.getNoOfOpenDocuments();}
	public Document getDocument(String s){return _cdPanel.getDocument(s);}
	public int nextDocumentNumber(){ return _cdPanel.nextDocumentNumber(); }
	public Document curDocument(){ return _cdPanel.curDocument();}
	public void addInOutstanding(String s)
	{
		_cdPanel.addInOutstanding(s);
		_menu.refresh();
	}
	public void removeFromOutstanding(String s)
	{
		_cdPanel.removeFromOutstanding(s);
		_menu.refresh();  
	}
	public Vector get_outStanding(){return _cdPanel.get_outStanding();}
	public Vector get_openDocnames(){return _cdPanel.get_openDocnames();}

	public void updateDocname(String previousName,String presentName)
	{
		_menu.refresh(previousName);
		removeFromOutstanding(previousName);
		_cdPanel.updateDocname(previousName,presentName);
		
		_menu.refresh(presentName);
		showDocument(presentName);
	}
	public void settitle(String s)
	{
		if(s==null)
			setTitle(_title);
		else
			setTitle(_title+s);
	}
	public void showDocument(String s)
	{
		_cdPanel.showDocument(s);
		if(_cdPanel.get_outStanding().contains(s))
			settitle("- ["+s+" *]");
		else
			settitle("- ["+s+"]");
		setDefaultMessage();
	}

	public void attach(String name,Document d)
	{
		_cdPanel.attach(name,d);
		settitle("- ["+name+"]");
		refresh(name);
		_toolBar.switchon();
	}
	public void detach(String name)
	{	  	 
		Document d = getDocument(name);
		detach(name,d);
	}

	public void detach(String name,Document d)
	{
		String s=_cdPanel.detach(name,d);
		if (s!=null)
		{
			if(get_outStanding().contains(s))
				settitle("- ["+s+" *]");
			else
				settitle("- ["+s+"]");
			_toolBar.switchon();
		}
		else
		{
			settitle(null);
			_toolBar.switchoff();
			_menu.menuFornoSelection();
		}
		refresh(name);
		setCurrentMenuString(s);
		setDefaultMessage();
	}

	public void refresh(String name)
	{
		_menu.refresh(name);
		_cdPanel.refresh();
	}

	public EditorMenus getmenu(){return _menu;}
// Constructor
	public Editor(String title, int w, int h) 
	{
		super(title);
//		this.setTitle(title);
		_title=title;

		INSTALL_DIR=System.getProperty("INSTALL_DIR");
		if (INSTALL_DIR==null)
			INSTALL_DIR=".";
		String dir=System.getProperty("IO_DIR");
		if (dir==null)
		{
			READ_DIR=".";
			WRITE_DIR=".";
		}
		else
		{
			READ_DIR=dir;
			WRITE_DIR=dir;
		}
		_toolBar = new SystemToolPanel(this); // SystemToolBar created
		_toolBar.setBackground(Color.gray);

		_strategyPanel=new StrategyPanel(this);
		_cdPanel=new CdPanel(this);
//*****************************************************************************************//
// Change blocks for win95 ans Solaris

//		_mainPanel= new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,_strategyPanel,_cdPanel); // MainPanel created

		_mainPanel=new Panel(); // MainPanel created
		_mainPanel.setLayout(new BorderLayout());
		_mainPanel.add("North",_strategyPanel);
		_mainPanel.add("Center",_cdPanel);
//*****************************************************************************************//

		_statusInfo = new Label();// Message bar created
		String s = "Ready";
		_statusInfo.setText(s);
		Panel statusPanel = new Panel();
		statusPanel.setLayout(new BorderLayout());
		statusPanel.add("Center",_statusInfo);
		statusPanel.setBackground(Color.lightGray);


		_menu = new EditorMenus(this); // MenuBar created

		add("North",_toolBar);
		add("Center",_mainPanel);
		add("South",statusPanel);
// jdk 1.1 type window event handling
		addWindowListener(new EAdapter()); // using inner class for window handling.

/*		try
		{
			FileOutputStream out = new FileOutputStream(WRITE_DIR+"/system.log");
			PrintStream pout=new PrintStream(out,true);
			System.setOut(pout);
			FileOutputStream err = new FileOutputStream(WRITE_DIR+"/error.log");
			PrintStream perr=new PrintStream(err,true);
			System.setErr(perr);
		}catch(IOException ioe){}
*/
		_pw = new PropertyWindow(this);//Propert window created
		Action act = new ActionNew(this);
		act.doIt();
		pack();
		this.setSize(w, h);
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		this.setLocation(screenSize.width/2 - w/2,screenSize.height/2 - h/2);

// Popup menu which pops up on right button click is initialized now
		popMenu = new PopupMenu();
		popMenu.add(reorderItem = new MenuItem("Reorder Parts"));
		popMenu.addSeparator();
		popMenu.add(deleteItem = new MenuItem("Delete"));
		popMenu.add(propertiesItem = new MenuItem("Properties"));
		popMenu.addSeparator();
		popMenu.add(definitionMenu = new Menu("StrategyEdge Definition"));

		definitionMenu.add(fromItem = new MenuItem("From"));
		definitionMenu.add(toItem = new MenuItem("To"));
		definitionMenu.addSeparator();
		definitionMenu.add(bypassingItem = new MenuItem("Bypassing"));
		definitionMenu.add(onlythroughItem = new MenuItem("OnlyThrough"));

		reorderItem.addActionListener(this);
		deleteItem.addActionListener(this);
		propertiesItem.addActionListener(this);
		fromItem.addActionListener(this);
		toItem.addActionListener(this);
		bypassingItem.addActionListener(this);
		onlythroughItem.addActionListener(this);
		add(popMenu);
// Popup menu defined
//		ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);

		setVisible(true);
	}

	public void showDemeterPanel(boolean status)
	{
		if(status)
		{
			_mainPanel.add("North",_strategyPanel);
//			_mainPanel.setTopComponent(_strategyPanel);
			validate();
		}
		else
		{
			_mainPanel.remove(_strategyPanel);
			validate();
		}
	}
	public void showSystemToolbar(boolean status)
	{
		if(status)
		{
			add("North",_toolBar);
			validate();
		}
		else
		{
			remove(_toolBar);
			validate();
		}
	}

/*	public void hideDemeterPanel()
	{
		_mainPanel.remove(_strategyPanel);
		_split = false;
		validate();
	}
	public void showDemeterPanel()
	{

//********************************************************/
// Alternate line for win95 and solaris
//		_mainPanel.setTopComponent(_strategyPanel);
//		_mainPanel.add("North",_strategyPanel);
//*******************************************************/
/*		_split = true;
		validate();
	}
*/

	public void setMessage(String message)
	{
		_statusInfo.setText(message);
		invalidate();
	}

	public String getInstallDir(){ return INSTALL_DIR;}
	public String getReadDir(){return READ_DIR;}
	public String getWriteDir(){return WRITE_DIR;}
	public void setWriteDir(String s){WRITE_DIR = s;}
	public void setReadDir(String s){READ_DIR = s;}




  /** The editor acts as a shell for Actions. This method executes the
   * given action in response to the given event (some Action's look
   * at the Event's that invoke them, even though this is
   * discouraged). The Editor executes the Action in a safe
   * environment so that buggy actions cannot crash the whole
   * Editor. <p>
   * Needs-more-work: Action debugging facilities are needed.
   * Needs-more-work: support for fynamic loading of actions... here?
   * @see Action
   */
	public void executeAction(Action act, AWTEvent e) 
	{
		if (act == null) return;
		try { act.doIt(); }
		catch (java.lang.Throwable ex) 
		{
			System.out.println("While executing " + act.toString() + " on event " + e.toString() +
				" the following error occured:");
			ex.printStackTrace();
		}
	}

  /** close this editor window */
	public void close() 
	{
		_pw.setVisible(false);
		_pw.dispose();
		setVisible(false);
		dispose();
	}
	private void doExit()
	{
		Action act=new ActionQuit(this);
		act.doIt();
	}

// inner class VDAdapter
	class EAdapter extends WindowAdapter
	{
		public void windowClosing(WindowEvent event)
		{
			doExit();
		}
		public void windowActivated(WindowEvent event)
		{
			if(curDocument()==null)
				return;
			curDocument().requestFocus();
		}
	}
// Popup menu show up
    public void showTraversalPopup(int x, int y,UEdge ue, boolean strategyEdge)
	{
		reorderItem.setEnabled(false);
		fromItem.setEnabled(false);
		toItem.setEnabled(false);
		definitionMenu.setEnabled(strategyEdge);
		popMenu.show(curDocument(),x,y);
	}
    public void showTraversalPopup(int x, int y,UVertex uv, boolean strategyEdge)
	{
		reorderItem.setEnabled(true);
		fromItem.setEnabled(true);
		toItem.setEnabled(true);
		definitionMenu.setEnabled(strategyEdge);
		popMenu.show(curDocument(),x,y);
	}

// Popup menu event handling
	public void actionPerformed(ActionEvent event)
	{
		Document document = curDocument();
		Action act=null;
		Object source = event.getSource();

		if (source == deleteItem)
			act = new ActionDispose(this,document);
		else
		if (source==propertiesItem)
			showPropertyWindow(true);
		else
		if (source==fromItem || source==toItem || source==bypassingItem || source==onlythroughItem)
			document.setSelectionString(event.getActionCommand());
		else
		if(source==reorderItem)
			act= new ActionReorderParts(this,document.getSelectedVertex());
		executeAction(act, event);
	}

}/* end class Editor */

