// File: ActionOpenBeh.java
// Classes: ActionOpenBeh
// Author: Kedar Patankar

package edu.neu.ccs.demeter.tools.apstudio.graphedit;

import edu.neu.ccs.demeter.Ident;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.awt.FileDialog;
import java.util.Vector;
import java.util.Enumeration;
import javax.swing.tree.DefaultMutableTreeNode;

/**
 * Action to open a file and reading the object description it holds, creating
 * the correponding strategy graph structutre. */

public class ActionOpenBeh extends Action
{
	private String _folderName,_fileName;
	public ActionOpenBeh(Editor editor) {super(editor);}
	public String name() { return "Open behavior file"; }
	public void doIt()
	{
		FileDialog fd = new FileDialog(_editor, "Select Behavior File", FileDialog.LOAD);
		fd.setDirectory(_editor.getReadDir());
		fd.setFile("*.str");
		fd.setVisible(true);
		_fileName = fd.getFile();
		if (_fileName == null) {return;}
		_folderName = fd.getDirectory();
		_editor.setReadDir(_folderName);
		String filename = _folderName + _fileName;

		FileInputStream in=null;
		ProgramBehavior program=null;

		try {in = new FileInputStream(filename);} 
		catch (FileNotFoundException de)
		{
			String title = "Error";
			String message = "Could not open file " + filename;
			ActionShowMessage asm= new ActionShowMessage(_editor,title,message);
			asm.doIt();
			return;
		}

		if(_editor.isBehaviorAlreadyOpen(filename))
		{
			String title = "Error";
			String message = "The behavior file is already open.";
			ActionShowMessage asm= new ActionShowMessage(_editor,title,message);
			asm.doIt();
			return;
		}
		try 
		{
			program = ProgramBehavior.parse(in);
			in.close();
		}catch (Exception fe)
		{
			String title = "File format error";
			String message = "The file could be corrupt or outdated. Please check version";
			ActionShowMessage asm= new ActionShowMessage(_editor,title,message);
			asm.doIt();
			return;
		}
		_editor.setMessage("Finished reading file "+filename);
// Now you have the program behavior object ready.

// lets check if the programbehavior object has object of type AnyClass and AnyPart
// if it does display warning and return.

		try{program.check_star();}catch(UnsupportedSyntaxException se)
		{
			String title = "Unsupported syntax";
			String message = se.getMessage();
			ActionShowMessage asm= new ActionShowMessage(_editor,title,message);
			asm.doIt();
			return;
		}

// Now go on building behaviors and add them to the strategy panel
		DefaultMutableTreeNode behaviorNode = _editor.addBehavior(filename);
		((BehaviorNode)behaviorNode.getUserObject()).isFirstTime(false);

		SGraphCollector sgc = program.go_get_graphs();
		int noOfGraphs = sgc.get_names().size();
		if(noOfGraphs==0)
			return;
		for(int i=0;i<noOfGraphs;i++) // add all the graphs
		{
			StrategyGraph sg = (StrategyGraph) sgc.get_graphs().elementAt(i);
			String graphname = (String) sgc.get_names().elementAt(i);
			DefaultMutableTreeNode graphNode = _editor.addStrategyGraph(behaviorNode,graphname);

			Enumeration edgelist = sg.get_edges().elements();
			while(edgelist.hasMoreElements()) // add all the edges
			{
				SGEdge edge = (SGEdge) edgelist.nextElement();
				DefaultMutableTreeNode edgeNode = _editor.addStrategyEdge(graphNode);

				VecVisitor vv = edge.go_get_source(); // add all the sources
				Vector v = vv.get_names();
				for(int k=0;k<v.size();k++)
					_editor.addFrom(edgeNode,(String)v.elementAt(k));

				vv = edge.go_get_destination();// add all the targets
				v = vv.get_names();				
				for(int k=0;k<v.size();k++) 
					_editor.addTo(edgeNode,(String)v.elementAt(k));
				
				if (edge.get_constraint()==null) //There are no constraints
					continue;

				if(edge.get_constraint() instanceof Bypassing)
				{
					vv = edge.go_get_bypassV();// add all the bypassing vertices
					v = vv.get_names();
					for(int k=0;k<v.size();k++) 
						_editor.addBypassV(edgeNode,(String)v.elementAt(k));
					vv = edge.go_get_part_globs();// collect part globs
					v = vv.get_names();
					for(int k=0;k<v.size();k++)
					{
						PartGlob pg = (PartGlob)v.elementAt(k);
						_editor.addBypassE(edgeNode,pg.go_get_sourcename(),pg.go_get_partname(),pg.go_get_destname());
					}
					vv = edge.go_get_subclass_globs(); // collect sublcass edge globs
					v = vv.get_names();
					for(int k=0;k<v.size();k++)
					{
						SubclassGlob scg = (SubclassGlob)v.elementAt(k);
						_editor.addBypassE(edgeNode,scg.go_get_sourcename(),null,scg.go_get_destname());
					}
				}
				else
				{
					vv = edge.go_get_onlythruV();// add all the only thru vertices
					v = vv.get_names();
					for(int k=0;k<v.size();k++) 
						_editor.addOnlyThroughV(edgeNode,(String)v.elementAt(k));
					vv = edge.go_get_part_globs();// collect part globs
					v = vv.get_names();
					for(int k=0;k<v.size();k++)
					{
						PartGlob pg = (PartGlob)v.elementAt(k);
						_editor.addOnlyThroughE(edgeNode,pg.go_get_sourcename(),pg.go_get_partname(),pg.go_get_destname());
					}
					vv = edge.go_get_subclass_globs(); // collect sublcass edge globs
					v = vv.get_names();
					for(int k=0;k<v.size();k++)
					{
						SubclassGlob scg = (SubclassGlob)v.elementAt(k);
						_editor.addOnlyThroughE(edgeNode,scg.go_get_sourcename(),null,scg.go_get_destname());
					}
				}
			}
		}
	}

	public void undoIt() {}

} /* end class ActionOpenBeh */

