/*
 * Created on Aug 19, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package APStudio;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;

import APStudio.models.BasicSubpart;
import APStudio.models.Connector;
import edu.neu.ccs.demeter.aplib.cd.ClassGraph;

/**
 * 
 * @author rajags
 *
 * An utility class that helps in creating a Eclipse resources like 
 * files & folders, modifying the file contents ,removing,replacig files
 * 
 */
public class ResourceMgtUtils {
	private static IFolder _newFolder = null;
	public static String  strategy="";
	public static ClassGraph cg = null;
	//All the children in the canvas.
	public static List nodeList = new ArrayList();
	public static HashMap STRATEGIES, NODESETS;
	public static boolean is_nodeset = false;
	//All the connected wires.
	public static Vector connectorList = new Vector();
	public static String TERMINATOR ="}";
	public static String NEWLINE ="\n";

	public static void removeTemporaryFolder(IProject proj){
		try{
		
			IFolder f = proj.getFolder("javaStuff");
			f.delete(IFolder.FORCE,null);
		}
		catch(Exception e){

			ErrorDialog.openError(null,
				"APStudio Plug-in",
				"Some resources in the Folder could not be deleted." +
				"Please physically delete these files from the file system.",
				new Status(Status.ERROR,"APStudio",Status.OK,e.getMessage(),null));
		}
	}
	/**
	 * creates a folder with folderName in the given project
	 * @param project
	 * @param folderName
	 */
	public static void createFolderInProject(IProject project, String folderName){
		_newFolder = project.getFolder(folderName);
		if(!_newFolder.exists()){
			try{
				_newFolder.create(true,true,null);
					
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	
	
	public static ClassGraph getClassGraph(){
		return cg;
	}
	
	public static void setClassGraph(ClassGraph c){
		cg = c;
	}
	
	public static void createClassGraph(){
		setClassGraph(CSU670Helper.createClassGraph(nodeList));
	}
	/**
	 * 
	 * @return A handle to the Folder created to hold java files.
	 */
	public static IFolder getFolder(){
		return _newFolder;
	}
	
	
	public static String HighlightTraversal(){
		return CSU670Helper.highlightTraversal(cg, nodeList, strategy, is_nodeset);
	}
	
	/**
	 * Given a list of names that was traversed by the strategy
	 * this method goes through all the collected nodes and
	 * edges and highlights them if they are contained in the 
	 * list 
	 * @param nameList A vector of names of the nodes and edges that were traversed
	 */
	public static void TempHighlightMethod(Vector nameList){
		for(int j=0;j < nameList.size();j++){
		
			for(int i=0; i < nodeList.size();i++){
				BasicSubpart element = (BasicSubpart)nodeList.get(i);
				String name = element.getName();
				if(((String)nameList.get(j)).equals(name)){
					//i got the node that is involved in the traversal
					// Highlight that node by setting the property of the
					//node	
					nameList.removeElementAt(j);
				}
			}
		}
		
		for(int j=0;j < nameList.size();j++){
		
			for(int i=0; i < connectorList.size();i++){
				Connector con =(Connector) connectorList.get(i);
				String name = con.getName();
				if(((String)nameList.get(j)).equals(name)){
				//i got the node that is involved in the traversal
				// Highlight that node by setting the property of the
				//node	
				con.setValue(true);
				nameList.removeElementAt(j);
			}
		}
	}
	}
	
	/**
	 * need to work on this.  
	 * @param fileName
	 * @param fieldName
	 */
	public static void removeFieldFromFile(String fileName,String fieldName){
	
		String contents = getFileContents(fileName);
		// construct the substring
//		String field = "private " +target + " "+fieldName + ";";
		
	}
	
	/**
	 * uses regex to match strings
	 * @param oldName
	 * @param newName
	 * @param Contents
	 * @return new contents with the string replaced.
	 * returns null if no match found
	 */
	public static String replaceContentString(String oldName,String newName,String Contents){
		String newContents =null;
		Pattern pattern = Pattern.compile(oldName);
		Matcher match = pattern.matcher(Contents);
		if (match.find()) {
			 newContents = match.replaceAll(newName);
		}
		return newContents;	 
	}
	
	/**
	 * When a name of the node is changed we need to change the 
	 * respective java files name .
	 * @param oldName
	 * @param newName
	 */
	public static void renameFile(String oldName ,String newName){
	
		String fullName = oldName + ".java";
		
		//get the oldfiles contents as string
		String oldContents = getFileContents(fullName);
		//replace the className in the contents
		String newContents = replaceContentString(oldName,newName,oldContents);
		if(newContents!=null){
			//remove the file and create a new one 
			
			removeFile(fullName);
			fullName = newName +".java";
			IFile f = createFileInFolder(_newFolder,fullName);
			//and set the contents again.
			setFileContents(f,newContents);
		}
		
		
		
	}
	
	/**
	 * Given a fileName remove the file from the Resource
	 * @param fileName
	 */
	public static void removeFile(String fileName){
		
		IFile file = _newFolder.getFile(fileName);
		
		try{
			if(file.exists()){
				file.delete(true,false,null);
			}
		}catch(Exception e){
			e.printStackTrace();	
		}
	}
	
	/**
		 * 
		 * @param sourcefile
		 * @param target
		 */
	/**
	 * This is a method that takes a source file, a target string
	 * and connector Name,  creates a nonstatic private (target) variable in the source
	 * file.
	 * @param sourcefile
	 * @param target
	 * @param connectorName
	 */
	public static void appendContents(String sourcefile,String target, String connectorName){
	//get the source file contents
	String fullName = sourcefile +".java";
	String contents = getFileContents(fullName);
	//create the variable to be inserted.
	String field = "private " +target + " "+connectorName + ";";
	//Insert before the terminator
	int index = contents.indexOf(TERMINATOR);
	
	StringBuffer newContents = new StringBuffer(NEWLINE);
	
	newContents.append(contents.substring(0,index));
	newContents.append(field);
	newContents.append(TERMINATOR);
	newContents.append(NEWLINE);
	
	//reset the contents.
	setFileContents(getFile(fullName),newContents.toString());
	}
	
	/**
	 *  Creates a specified file in the given folder
	 * @param folder
	 * @param fileName
	 * @return 
	 * A handle to the createdFile
	 */
	public static IFile createFileInFolder(IFolder folder,String fileName){
		IFile newFile = folder.getFile(fileName);
		
		try{
			if(newFile.exists()){
				return newFile;
			}
			else{
				File systemFile = newFile.getLocation().toFile();
				
				if(systemFile.exists()){
					//skip for now. Revisit later
				}
				else{
					newFile.create(getInitialContents(fileName),false,null);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
				
		}
		return newFile;		
	}
	
	/**
	 * 
	 * @param proj
	 * @param fileName
	 * @return
	 */
	public static IFile getFile(IProject proj, String fileName){
	 IFile file = null;
	 //Look under the proj dir,
	 file = proj.getFile(fileName);
	 //if not found go through all the subdirs and look there
	 //For current only look under current proj dir. If not found 
	 //bad luck :)
	 
	 return file;	
	}
	
	/**
	 * 
	 * @param fileName
	 * @return A handle to the specified file if it exists
	 */
	public static IFile getFile(String fileName){
		IFile newFile = _newFolder.getFile(fileName);
		return newFile;
	}
	
	public static void setFileContents(IFile file, String Contents){
		try{
		
			ByteArrayInputStream bais = new ByteArrayInputStream(Contents.getBytes());
			file.setContents(bais,true,false,null);
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @param fileName
	 * @return The contents of the file as String
	 */
	public static String getFileContents(String fileName){
		String fileContents ="";
		try{
			IFile newFile = getFile(fileName);
			//get a handle to the file.
			//String fullName = fileName +".java";
			
			
			InputStream contents = newFile.getContents();
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte[] b = new byte[4096];
			for (int n = contents.read(b); n > 0; n = contents.read(b))
	  			out.write(b, 0, n);
			fileContents = out.toString();
			contents.close();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		
		return fileContents;
	}
	
	/**
	 * 
	 * @return The initial contents of the file as InputStream
	 */
	public static InputStream getInitialContents(String fileName){
		//Remove the extension
		int index = fileName.indexOf('.');
		fileName = fileName.substring(0, index == -1 ? fileName.length() : index);
		StringBuffer sb = new StringBuffer();
		sb.append("package javaStuff;");
		sb.append(NEWLINE); 
		sb.append("public class ");
		sb.append(fileName +" {");
		sb.append(NEWLINE);
		sb.append(TERMINATOR);
		return new ByteArrayInputStream(sb.toString().getBytes());
	}
	
	/**
	 * DeveloperNote:
	 * Try using IResourceVisitor.Should be easier
	 * @param project
	 */
//	public void getAllJavaFiles(IProject project){
//		try{
//		
//			if(project.isOpen()){
//				IResource[] res =project.members();
//				for(int i =0; i < res.length; i++){
//					//Go through each member to find out the files.
//					if(res[i].getType()== IResource.FILE)
//					{
//						//Need to create classGraph for Trv file.
//						String extension = res[i].getFileExtension();
//						String fileName = res[i].getName();
//						if(extension.equalsIgnoreCase("trv")){
//							InputStream trvfile = project.getFile(fileName).getContents();
//							Strategy s = DjLibUtils.createStrategyFromTrv(trvfile);
//							ClassGraph temp = new ClassGraph();
//							DjLibUtils.CreateTraversalGraph(temp,s);
//							
//							
//						}	
//						
//					}
//				}
//			}	
//		}catch(Exception e)
//		{
//			System.out.println("Exception getting members of the project\n");
//		}
//		
//	}
//	
}
