package CSU670_Plugin.actions;


import java.util.Iterator;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.jface.dialogs.MessageDialog;

import edu.neu.ccs.demeter.aplib.EdgeI;
import edu.neu.ccs.demeter.aplib.Traversal;
import CSU670_Plugin.TraversalHighlight;
import CSU670_Plugin.editors.AspectXEditor;
import CSU670_Plugin.gen.Main;

/**
 * Our sample action implements workbench action delegate.
 * The action proxy will be created by the workbench and
 * shown in the UI. When the user tries to use the action,
 * this delegate will be created and execution will be 
 * delegated to it.
 * @see IWorkbenchWindowActionDelegate
 */
public class AspectXSyntaxHighlight implements IWorkbenchWindowActionDelegate {
	public static final Color red = new Color(Display.getCurrent(),255,0,0);
	public static final Color green = new Color(Display.getCurrent(),0,255,0);
	public static final Color blue = new Color(Display.getCurrent(),0,0,255);
	public static final Color cyan = new Color(Display.getCurrent(),0,255,255);
	public static final Color magenta = new Color(Display.getCurrent(),255,0,255);
	public static final Color yellow = new Color(Display.getCurrent(),255,255,0);
	public static final Color black = new Color(Display.getCurrent(),0,0,0);
	public static final Color white = new Color(Display.getCurrent(),255,255,255);
	public static final Color grey = new Color(Display.getCurrent(), 150,150,150);
	public static AspectXSyntaxHighlight instance=new AspectXSyntaxHighlight();
	
	private IWorkbenchWindow window;
	/**
	 * The constructor.
	 */
	public AspectXSyntaxHighlight() {
		super();
	}

	/**
	 * The action has been activated. The argument of the
	 * method represents the 'real' action sitting
	 * in the workbench UI.
	 * @see IWorkbenchWindowActionDelegate#run
	 */
	public void run(IAction action) {
		String msg="";
		IDocument doc;
		FindReplaceDocumentAdapter f;
		
		do { // so we can "break" out
			try {
				
				if(AspectXEditor.editorCount!=1){
					msg += "Error! Must have exactly one (1) xaj editor\n";
					break;
				}
				if(AspectXEditor.current==null){
					msg += "Error! Only start one editor xaj per session\n";
					break;
				}
				if(Main.userCg==null){
					msg += "Error! Must check syntax first";
					break;
				}
				
				
				doc = AspectXEditor.current.getDocument();
				f = new FindReplaceDocumentAdapter(doc);
				
				String strategy = AspectXEditor.current.currentStrategy();
				
				if(strategy=="") break;
				
				if(!Main.traversals.containsKey(strategy)){
					msg+="Unkown strategy " + strategy;
					break;					
				}
				
				TraversalHighlight t = (TraversalHighlight)Main.traversals.get(strategy);
				
				for(Iterator i=t.nodes().iterator(); i.hasNext();)
					AspectXEditor.current.highlightNode(green,(String)i.next());
				
				
				for(Iterator i=t.edges().iterator(); i.hasNext();)
					AspectXEditor.current.highlightEdge(cyan,(EdgeI)i.next());
				
				
			} catch (Exception e) {
				msg+="Exception!!!";
				e.printStackTrace();
				System.out.println(e.getMessage());
			}		
		} while (false);
		
		if(msg!=""){
			Main.hadERROR=true;
			MessageDialog.openInformation(
				window.getShell(),
				"AspectX Highlight",
				msg);
		}
	}
	
	private static final String keywordregexp 
		= "[(){}.=;:!,]|\\b(class|dictionary|chosen|selector|aspect|ClassDictionary|Traversal|declare|node|set|strategy|nodes|regexp|and|or|from|to|via|stop|through|bypassing|->)\\b";
	
	private static final String commentregexp 
		= "//[^\\n]*|/\\*([^*]|\\*[^/])*\\*/";
	
	public void highlightKeywords(){
		IDocument doc;
		FindReplaceDocumentAdapter f;
		doc = AspectXEditor.current.getDocument();
		f = new FindReplaceDocumentAdapter(doc);
		
		
		try {
			IRegion r;
			for(int i = 0;
				 i<f.length() && null!=(r=f.find(i,keywordregexp,true,true,false,true));
				i=r.getOffset()+1){
					AspectXEditor.current.highlight(blue,r);
			}
			for(int i = 0;
			   i<f.length() && null!=(r=f.find(i,commentregexp,true,true,false,true));
				i=r.getOffset()+1){
					AspectXEditor.current.highlight(grey,r);
			}
		} catch (BadLocationException e) {
			//unreachable???
			e.printStackTrace();
		}
		
	}

	/**
	 * Selection in the workbench has been changed. We 
	 * can change the state of the 'real' action here
	 * if we want, but this can only happen after 
	 * the delegate has been created.
	 * @see IWorkbenchWindowActionDelegate#selectionChanged
	 */
	public void selectionChanged(IAction action, ISelection selection) {
	}

	/**
	 * We can use this method to dispose of any system
	 * resources we previously allocated.
	 * @see IWorkbenchWindowActionDelegate#dispose
	 */
	public void dispose() {
	}

	/**
	 * We will cache window object in order to
	 * be able to provide parent shell for the message dialog.
	 * @see IWorkbenchWindowActionDelegate#init
	 */
	public void init(IWorkbenchWindow window) {
		this.window = window;
	}
}