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

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

import java.util.Vector;
import java.util.Enumeration;
import edu.neu.ccs.demeter.Ident;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.awt.Point;
import java.awt.Rectangle;

public class ActionReload extends Action
{
	private int _idd=0;

	public ActionReload(Editor e,Document d) { super(e,d);}
	public String name() { return "Reload File"; }

	public void doIt() 
	{
		if(_document.firstTime())
			return;

		String title="Confirm File Reload";
		String message1="You will loose all the changes made to CD and placement";
		String message2="Are you sure, you want to reload the file";
		String buttonString="YN";
		AlarmDialog ad = new AlarmDialog(_editor,title,message1,message2,buttonString,"N");
		ad.setVisible(true);

		if(ad.getChoice().equals("NO") || ad.getChoice().equals("CANCEL"))
			return;

		String fileName = _document.getDocName();

		FileInputStream in=null;
		try {in = new FileInputStream(fileName);} 
		catch (FileNotFoundException de){return;}

		Program p;
		try 
		{
			p = Program.parse(in);
			in.close();
		}catch (Exception fe)
		{
			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);

		UGraph _graph=null;
		try{_graph = p.print_edges();}
		catch(Exception e)
		{
			_editor.setMessage("Error occured during building class graph");
			e.printStackTrace();
			return;
		}
		
		_editor.setMessage("Finished building class graph.");

		_editor.detach(_document.getDocName(),_document);

		_document=new Document(_editor);
		_document.setDocName(fileName);
		_editor.attach(fileName,_document); // This causes the scroll panel to be laid
		_editor.setCurrentMenuString(fileName);

/* Traverse trough the graph and read all the infromation required for
   drawing the vertices on the screen*/

		VertexContainer vc = _graph.GetAllVertices();
//		System.out.println("Finished traversing the vertex list");
		if(!addConstructionVertices(vc)){_editor.detach(fileName,_document);return;}
		if(!addAlternationVertices(vc)){_editor.detach(fileName,_document);return;}

/* Traverse trough the graph and read all the infromation required for
   drawing the edges on the screen */

		EdgeContainer ec = _graph.GetAllEdges();
		if(!addConstructionEdges(ec)){_editor.detach(fileName,_document);return;}
		if(!addAlternationEdges(ec)){_editor.detach(fileName,_document);return;}
// Add the preamble and package stuff
		_document.set_preamble(_graph.get_preamble());
		_document.set_pkg(_graph.get_pkg());

/* After adding all the elements to view and the net list draw them */
		_document.cdNeedsSaving(false);
		_document.setId(_idd);
		
	}

	private boolean addConstructionVertices(VertexContainer VC)
	{							 
		Vector construction_vertices = VC.get_construction();
		return buildAndaddVertices(construction_vertices,"edu.neu.ccs.demeter.tools.apstudio.graphedit.UConstVertex");
	}

	private boolean addAlternationVertices(VertexContainer VC)
	{
		Vector alternation_vertices = VC.get_alternation();
		return buildAndaddVertices(alternation_vertices,"edu.neu.ccs.demeter.tools.apstudio.graphedit.UAltVertex");
	}
	
	private boolean buildAndaddVertices(Vector v,String className)
	{
		UVertex newNode;
		Class _nodeClass;
		String _nodeClassName=className;
		Enumeration elm = v.elements();
		try { _nodeClass = Class.forName(_nodeClassName); }
		catch (java.lang.ClassNotFoundException ignore) 
		{
			System.out.println("Class " + _nodeClassName + " could not be found!");
			return false; 
		}
		while (elm.hasMoreElements())
		{
			try { newNode = (UVertex) _nodeClass.newInstance();	}
			catch (java.lang.IllegalAccessException ignore) { return false; }
			catch (java.lang.InstantiationException ignore) { return false; }
			
			VertexInfo vf=(VertexInfo)elm .nextElement();
			int id=vf.get_id().get_id().intValue();
			_idd=Math.max(_idd,id);
			newNode.initialize(vf,_document,vf.get_id());
			newNode.set_vertexname(new UVertexName(new Ident(vf.get_name())));
			if(newNode instanceof UConstVertex)
			{
				String before = vf.get_before();
				String after = vf.get_after();
				((UConstVertex)newNode).set_beforeSyntax(before);
				((UConstVertex)newNode).set_afterSyntax(after);
			}
			((UConstOrAltVertex)newNode).set_parse(new YaParse()); 
			// Always parse method generated ScopeIdentifierList is null meaning package level by default
			_document.add(newNode.get_Perspective());
		}
		return true;
	}
	
	private boolean addConstructionEdges(EdgeContainer EC)
	{
		Vector construction_edges = EC.get_construction();
		return buildAndaddEdges(construction_edges);
	}
	private boolean addAlternationEdges(EdgeContainer EC)
	{
		Vector alternation_edges = EC.get_alternation();
		return buildAndaddEdges(alternation_edges);
	}
	private boolean buildAndaddEdges(Vector v)
	{
		Enumeration elm=v.elements();

		while (elm.hasMoreElements())
		{
			EdgeInfo edgeinfo= (EdgeInfo)elm.nextElement();

	  /** Extracting the information from EdgeInfo */

	  
			int id=edgeinfo.get_id().get_id().intValue();
			_idd=Math.max(_idd,id);
			UID from=edgeinfo.get_from();
			UID to=edgeinfo.get_to();
			String edge_name= edgeinfo.get_name();
			String cardinality = edgeinfo.get_card();


	  /** Get the source and destination vertices so that their height and width can
	  be obtained */
	  
			Perspective sourcePerspective= (Perspective)_document.pick(from);
			Perspective destPerspective= (Perspective)_document.pick(to);
	  
			if(sourcePerspective==null) { System.out.println("sors null");return false;}
			if(destPerspective==null) { System.out.println("dest null");return false;}

			UVertex startNode= (UVertex)sourcePerspective.owner();
			UVertex destNode= (UVertex)destPerspective.owner();
			
			if(startNode==null){ System.out.println("start Node is null");return false;}
			if(destNode==null){ System.out.println("dst Node is null"); return false;}

			UEdge newArc;
			ArcPerspective ap;

			if(edge_name==null && cardinality==null)
			{
				newArc=new UAltEdge();
				newArc.set_eid(edgeinfo.get_id());
				newArc.connect(startNode, destNode);
				Point p = edgeinfo.get_bendpoint();
				if(p==null)
					ap= new ArcPerspective(newArc,_document);
				else
					ap= new ArcPerspective(newArc,_document,p);
			}
			else
			{
				newArc=new UConstEdge();
				newArc.set_eid(edgeinfo.get_id());
				newArc.connect(startNode, destNode);
				if(edge_name==null)
					((UConstEdge)newArc).set_edgename(null);
				else
					((UConstEdge)newArc).set_edgename(new UEdgeName(new Ident(edge_name)));
				String before = edgeinfo.get_beforeSyntax();
				((UConstEdge)newArc).set_beforeSyntax(before);
				String after = edgeinfo.get_afterSyntax();
				((UConstEdge)newArc).set_afterSyntax(after);
				Point p = edgeinfo.get_bendpoint();
				if(p==null)
					ap= new ArcPerspective(newArc,edge_name,cardinality,_document);
				else
					ap= new ArcPerspective(newArc,edge_name,cardinality,_document,p);
			}
	  
			_document.add(ap);
		}
		return true;
	}
	public void undoIt() { }

} /* end class ActionReload */

