/**
 * <copyright>
 *
 * Copyright (c) 2005,2011 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *   Zeligsoft - Bug 237205
 *   Patrick Könemann - Bug 294200 (history)
 *   E.D.Willink - rework of LPG OCL Console for Xtext
 *
 * </copyright>
 *
 * $Id: OCLConsolePage.java,v 1.9 2011/05/07 17:18:05 ewillink Exp $
 */

package org.eclipse.ocl.examples.xtext.console;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ocl.examples.domain.evaluation.DomainModelManager;
import org.eclipse.ocl.examples.domain.evaluation.InvalidEvaluationException;
import org.eclipse.ocl.examples.domain.evaluation.InvalidValueException;
import org.eclipse.ocl.examples.domain.values.BooleanValue;
import org.eclipse.ocl.examples.domain.values.IntegerValue;
import org.eclipse.ocl.examples.domain.values.RealValue;
import org.eclipse.ocl.examples.domain.values.StringValue;
import org.eclipse.ocl.examples.domain.values.Value;
import org.eclipse.ocl.examples.domain.values.ValueFactory;
import org.eclipse.ocl.examples.domain.values.impl.InvalidValueImpl;
import org.eclipse.ocl.examples.pivot.AssociationClassCallExp;
import org.eclipse.ocl.examples.pivot.CollectionItem;
import org.eclipse.ocl.examples.pivot.Element;
import org.eclipse.ocl.examples.pivot.Environment;
import org.eclipse.ocl.examples.pivot.EnvironmentFactory;
import org.eclipse.ocl.examples.pivot.EvaluationHaltedException;
import org.eclipse.ocl.examples.pivot.ExpressionInOcl;
import org.eclipse.ocl.examples.pivot.IterateExp;
import org.eclipse.ocl.examples.pivot.IteratorExp;
import org.eclipse.ocl.examples.pivot.OperationCallExp;
import org.eclipse.ocl.examples.pivot.ParserException;
import org.eclipse.ocl.examples.pivot.PropertyCallExp;
import org.eclipse.ocl.examples.pivot.TupleLiteralPart;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitorImpl;
import org.eclipse.ocl.examples.pivot.evaluation.PivotEvaluationEnvironment;
import org.eclipse.ocl.examples.pivot.helper.OCLHelper;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManagerResourceSetAdapter;
import org.eclipse.ocl.examples.pivot.util.Pivotable;
import org.eclipse.ocl.examples.pivot.utilities.PivotEnvironment;
import org.eclipse.ocl.examples.pivot.utilities.PivotEnvironmentFactory;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.pivot.values.PivotValueFactory;
import org.eclipse.ocl.examples.xtext.console.actions.CloseAction;
import org.eclipse.ocl.examples.xtext.console.actions.LoadExpressionAction;
import org.eclipse.ocl.examples.xtext.console.actions.LoadResourceAction;
import org.eclipse.ocl.examples.xtext.console.actions.SaveExpressionAction;
import org.eclipse.ocl.examples.xtext.console.actions.ValidateAction;
import org.eclipse.ocl.examples.xtext.console.messages.ConsoleMessages;
import org.eclipse.ocl.examples.xtext.console.xtfo.EmbeddedXtextEditor;
import org.eclipse.ocl.examples.xtext.essentialocl.ui.model.BaseDocument;
import org.eclipse.ocl.examples.xtext.essentialocl.utilities.EssentialOCLCSResource;
import org.eclipse.ocl.examples.xtext.essentialocl.utilities.EssentialOCLPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.actions.ClearOutputAction;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.outline.IOutlineNode;
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode;
import org.eclipse.xtext.ui.editor.outline.impl.EStructuralFeatureNode;
import org.eclipse.xtext.ui.editor.outline.impl.OutlinePage;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
import org.osgi.framework.Bundle;

import com.google.inject.Injector;

/**
 * The page implementing the Interactive OCL console.
 */
public class OCLConsolePage extends Page
{
    private static int BUNDLE_AVAILABLE = Bundle.RESOLVED | Bundle.ACTIVE | Bundle.STARTING;
	
    /**
     * Queries whether a bundle is available.
     * 
     * @param bundle a bundle
     * @return whether it is active or resolved
     */
    static boolean isAvailable(Bundle bundle) {
        return (bundle.getState() & BUNDLE_AVAILABLE) != 0;
    }
    
/*    private class DropDownAction extends Action implements IMenuCreator {
        private Menu menu;
        private List<IAction> actions = new java.util.ArrayList<IAction>();
        
        private IPropertyChangeListener listener = new IPropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if (IAction.CHECKED.equals(event.getProperty())) {
                    if (Boolean.TRUE.equals(event.getNewValue())) {
                        actionChecked((IAction) event.getSource());
                    }
                }
            }};
        
        DropDownAction() {
            super();
            
            setMenuCreator(this);
        }
        
        public void addAction(IAction action) {
            actions.add(action);
            action.addPropertyChangeListener(listener);
            
            if (action.isChecked()) {
                actionChecked(action);
            }
        }

        private void actionChecked(IAction action) {
            setImageDescriptor(action.getImageDescriptor());
            setText(action.getText());
        }
        
        public Menu getMenu(Control parent) {
            if (menu == null) {
                menu = new Menu(parent);
                
                for (IAction action : actions) {
                    addAction(menu, action);
                }
            }
            
            return menu;
        }
        
        private void addAction(Menu m, IAction action) {
            ActionContributionItem contrib = new ActionContributionItem(action);
            contrib.fill(m, -1);
        }
        
        public void dispose() {
            if (menu != null) {
                menu.dispose();
            }
        }
        
        public Menu getMenu(Menu parent) {
            return null;
        }
    } */

    protected static class CancelableEvaluationVisitor extends EvaluationVisitorImpl
    {
		private final IProgressMonitor monitor;
		
		protected CancelableEvaluationVisitor(IProgressMonitor monitor, Environment env, EvaluationEnvironment evalEnv, DomainModelManager modelManager) {
			super(env, evalEnv, modelManager);
			this.monitor = monitor;
		}

		protected void checkMonitor() {
			if (monitor.isCanceled()) {
				throw new EvaluationHaltedException("Manual termination"); //$NON-NLS-1$
			}
		}
		
		@Override
		public EvaluationVisitor createNestedVisitor() {
			EnvironmentFactory factory = environment.getFactory();
	    	EvaluationEnvironment nestedEvalEnv = factory.createEvaluationEnvironment(evaluationEnvironment);
			return new CancelableEvaluationVisitor(monitor, environment, nestedEvalEnv, modelManager);
		}

		@Override
		public Value visitAssociationClassCallExp(AssociationClassCallExp ae) {
			checkMonitor();
			return super.visitAssociationClassCallExp(ae);
		}
		
		@Override
		public Value visitCollectionItem(CollectionItem item) {
			checkMonitor();
			return super.visitCollectionItem(item);
		}
		
		@Override
		public Value visitIterateExp(IterateExp iterateExp) {
			checkMonitor();
			return super.visitIterateExp(iterateExp);
		}
		
		@Override
		public Value visitIteratorExp(IteratorExp iteratorExp) {
			checkMonitor();
			return super.visitIteratorExp(iteratorExp);
		}
		
		@Override
		public Value visitOperationCallExp(OperationCallExp operationCallExp) {
			checkMonitor();
			return super.visitOperationCallExp(operationCallExp);
		}
		
		@Override
		public Value visitPropertyCallExp(PropertyCallExp propertyCallExp) {
			checkMonitor();
			return super.visitPropertyCallExp(propertyCallExp);
		}
		
		@Override
		public Value visitTupleLiteralPart(TupleLiteralPart tp) {
			checkMonitor();
			return super.visitTupleLiteralPart(tp);
		}
	}
    
    protected static class CancelableMetaModelManager extends MetaModelManager
    {       
		private IProgressMonitor monitor = null;
		private final ValueFactory valueFactory;

		public CancelableMetaModelManager() {
			this.valueFactory = new PivotValueFactory(this)
			{		      	
	        	@Override
				public BooleanValue booleanValueOf(boolean value) {
	        		checkMonitor();
					return super.booleanValueOf(value);
				}

				@Override
				public IntegerValue integerValueOf(BigInteger value) {
	        		checkMonitor();
					return super.integerValueOf(value);
				}

				@Override
	    		public IntegerValue integerValueOf(long value) {
	        		checkMonitor();
	    			return super.integerValueOf(value);
	    		}

				@Override
				public IntegerValue integerValueOf(String aValue) throws InvalidValueException {
	        		checkMonitor();
					return super.integerValueOf(aValue);
				}

				@Override
				public RealValue realValueOf(double value) {
	        		checkMonitor();
					return super.realValueOf(value);
				}

				@Override
				public RealValue realValueOf(BigDecimal value) {
	        		checkMonitor();
					return super.realValueOf(value);
				}

				@Override
				public RealValue realValueOf(IntegerValue integerValue) {
	        		checkMonitor();
					return super.realValueOf(integerValue);
				}

				@Override
				public RealValue realValueOf(String aValue) throws InvalidValueException {
	        		checkMonitor();
					return super.realValueOf(aValue);
				}

				@Override
				public StringValue stringValueOf(String value) {
	        		checkMonitor();
					return super.stringValueOf(value);
				}
			};
		}

		protected void checkMonitor() {
			if ((monitor != null) && monitor.isCanceled()) {
				throw new EvaluationHaltedException(ConsoleMessages.Result_EvaluationTerminated);
			}
		}

		@Override
		public ValueFactory getValueFactory() {
			return valueFactory;
		}

		public void setMonitor(IProgressMonitor monitor) {
    		this.monitor = monitor;
		}
    }

    protected static class ExceptionValue extends InvalidValueImpl
	{
		private final String message;
    	private final Exception exception;
    	
		protected ExceptionValue(ValueFactory valueFactory, String message, Exception exception) {
			super(valueFactory);
			this.message = message;
			this.exception = exception;
		}
		
		public Exception getException() {
			return exception;
		}
    	
		public String getMessage() {
			return message;
		}

		@Override
		public String toString() {
			StringBuilder s = new StringBuilder();
			if (exception != null) {
//				s.append(" : "); //$NON-NLS-1$
				s.append(exception.getMessage());
			}
			return s.toString();
		}
	}
	
	private class EvaluationRunnable implements IRunnableWithProgress
	{
		private final XtextResource resource;
		private final String expression;
		private Value value = null;
		
		public EvaluationRunnable(XtextResource resource, String expression) {
			this.resource = resource;
			this.expression = expression;
		}

		public Value getValue() {
			return value;
		}

		public void run(final IProgressMonitor monitor) {
			monitor.beginTask(NLS.bind(ConsoleMessages.Progress_Title, expression), 10);
			monitor.subTask(ConsoleMessages.Progress_Synchronising);
			monitor.worked(1);
//			CS2PivotResourceAdapter csAdapter = CS2PivotResourceAdapter.getAdapter((BaseCSResource)resource, metaModelManager);
			ValueFactory valueFactory = metaModelManager.getValueFactory();
//			monitor.subTask(ConsoleMessages.Progress_CST);
//			try {
//				csAdapter.refreshPivotMappings();
//			} catch (Exception e) {
//				value = new ExceptionValue(valueFactory, ConsoleMessages.Result_MappingFailure, e);
//				return;
//			}
//			monitor.worked(2);
//			monitor.subTask(ConsoleMessages.Progress_AST);
			ExpressionInOcl expressionInOcl;
			try {
				PivotUtil.checkResourceErrors(null, resource);
				expressionInOcl = PivotUtil.getExpressionInOcl(resource);
			} catch (ParserException e) {
				value = new ExceptionValue(valueFactory, ConsoleMessages.Result_ParsingFailure, e);
				return;
			}
//			monitor.worked(2);
			monitor.subTask(ConsoleMessages.Progress_Extent);
			PivotEnvironmentFactory envFactory = new PivotEnvironmentFactory(null, metaModelManager);
			PivotEnvironment environment = envFactory.createEnvironment();
			PivotEvaluationEnvironment evaluationEnvironment = envFactory.createEvaluationEnvironment();
			Value contextValue = valueFactory.valueOf(contextObject);
			evaluationEnvironment.add(expressionInOcl.getContextVariable(), contextValue);
//			if (modelManager == null) {
				// let the evaluation environment create one
				modelManager = evaluationEnvironment.createModelManager(contextObject);
//			}
			monitor.worked(2);
			monitor.subTask(ConsoleMessages.Progress_Evaluating);
			try {
				metaModelManager.setMonitor(monitor);
				EvaluationVisitor evaluationVisitor = new CancelableEvaluationVisitor(monitor, environment, evaluationEnvironment, modelManager);
		        value = evaluationVisitor.visitExpressionInOcl(expressionInOcl);
			} catch (EvaluationHaltedException e) {
				value = new ExceptionValue(valueFactory, ConsoleMessages.Result_EvaluationTerminated, null);
			} catch (InvalidEvaluationException e) {
				value = new ExceptionValue(valueFactory, ConsoleMessages.Result_EvaluationFailure, e);
			} finally {
				metaModelManager.setMonitor(null);
			}
			monitor.worked(4);
		}
	}
	
	/**
	 * A key listener that listens for the Enter key to evaluate the OCL
	 * expression.
	 */
	private class InputKeyListener implements KeyListener {
		private boolean evaluationSuccess = false;		
		private List<String> history = new ArrayList<String>();
		private int currentHistoryPointer = 0;
		
		public void keyPressed(KeyEvent e) {
			switch (e.keyCode) {
			case SWT.CR :
			    if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
					String text = getEditorDocument().get();
					evaluationSuccess = evaluate(text.trim());
				}		
				break;
			case SWT.PAGE_UP :
				if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {					
					// history
					if (currentHistoryPointer == 0 && history.size() > 0) {
						if (history.size() > 0 && history.get(0).length() == 0) {
							history.remove(0);
						}
						history.add(0, getEditorDocument().get().trim());
						currentHistoryPointer = 1;
						setTextFromHistory();
					} else if (currentHistoryPointer < history.size() - 1) {
						currentHistoryPointer++;
						setTextFromHistory();
					}
				}			
				break;
			case SWT.PAGE_DOWN :
				if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {					
					// history
					if (currentHistoryPointer > 0) {
						currentHistoryPointer--;
						setTextFromHistory();
					}
				}		
				break;
			}
		}

		public void keyReleased(KeyEvent e) {
			switch (e.keyCode) {
			case SWT.CR :
				if ((e.stateMask & SWT.CTRL) == 0) {
					if (evaluationSuccess) {
						getEditorDocument().set(""); //$NON-NLS-1$
						// history
						if (history.size() > 0 && history.get(0).trim().length() == 0) {
							history.remove(0);
						}
						if (history.size() == 0 || !history.get(0).equals(lastOCLExpression.trim())) {
							history.add(0, lastOCLExpression.trim());
						}
						currentHistoryPointer = 0;
					}					
					evaluationSuccess = false;
				}				
				break;
//			case ' ':
//			    if ((e.stateMask & SWT.CTRL) == SWT.CTRL) {
//			        input.getContentAssistant().showPossibleCompletions();
//			    }
			}
		}

		protected void setTextFromHistory() {
			String newText = history.get(currentHistoryPointer);
			getEditorDocument().set(newText);
			input.setSelectedRange(newText.length(), 0);
		}
	}
    
	private final OCLConsole console;
	private Composite page;
	private ModelingLevel modelingLevel = ModelingLevel.M2;

	private ITextViewer output;
	private ColorManager colorManager;

	private SourceViewer input;
	private EmbeddedXtextEditor editor;
	private String lastOCLExpression;
	
	private ISelectionService selectionService;
	private ISelectionListener selectionListener;
	private EObject contextObject;
	private EClassifier contextClassifier;
	
	private final CancelableMetaModelManager metaModelManager;
	private DomainModelManager modelManager = null;
	
	private ValidateAction validateAction = null;
	
//	private Map<TargetMetamodel, IAction> metamodelActions =
//	    new java.util.HashMap<TargetMetamodel, IAction>();
	
//	private static final AdapterFactory reflectiveAdapterFactory =
//		new ReflectiveItemProviderAdapterFactory();

//	private static final AdapterFactory defaultAdapterFactory =
//		new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);

/*	public IItemLabelProvider tupleTypeLabelProvider = new IItemLabelProvider() {
	
		public Object getImage(Object object) {
			return null;
		}
	
		public String getText(Object object) {
		    @SuppressWarnings("unchecked")
            TupleValue tuple = (TupleValue) object;
			TupleType tupleType = tuple.getTupleType();
			
			StringBuilder result = new StringBuilder();
			result.append("Tuple{");//$NON-NLS-1$
			
			for (Iterator<?> iter = tupleType.oclProperties().iterator();
					iter.hasNext();) {
				
				Object next = iter.next();
				
				result.append(oclFactory.getName(next));
				result.append(" = "); //$NON-NLS-1$
				result.append(OCLConsolePage.this.toString(tuple.getValue(next)));
				
				if (iter.hasNext()) {
					result.append(", "); //$NON-NLS-1$
				}
			}
			
			result.append('}');
			
			return result.toString();
		}}; */
	
	/**
	 * Initializes me.
	 * @param oclConsole 
	 */
	OCLConsolePage(OCLConsole console) {
		super();
		this.metaModelManager = new CancelableMetaModelManager();
		this.console = console;
	}

	/**
     * Adds actions for the available target metamodels to the action bars.
     * 
     * @param metamodelMenu the console's drop-down action bar menu
     * @param metamodelAction the console's drop-down tool bar button
     *
    private void addMetamodelActions(IMenuManager metamodelMenu,
            DropDownAction metamodelAction) {
        IAction ecore = new EcoreMetamodelAction();
		ecore.setChecked(true);
		ImageDescriptor img = getImage(EcoreFactory.eINSTANCE.getEPackage());
		if (img != null) {
		    ecore.setImageDescriptor(img);
		}
		
		metamodelMenu.add(ecore);
		metamodelAction.addAction(ecore);
        metamodelActions.put(TargetMetamodel.Ecore, ecore);
        
        Bundle umlBundle = Platform.getBundle("org.eclipse.uml2.uml"); //$NON-NLS-1$
        if ((umlBundle != null) && isAvailable(umlBundle)) {
    		IAction uml = new UMLMetamodelAction();
            img = getImage(UMLFactory.eINSTANCE.createModel());
            if (img != null) {
                uml.setImageDescriptor(img);
            }
            
    		metamodelMenu.add(uml);
            metamodelAction.addAction(uml);
            metamodelActions.put(TargetMetamodel.UML, uml);
        }
    } */
	
	/**
	 * Appends the specified text to the output viewer.
	 * 
	 * @param text the text to append
	 * @param color the color to print the text with
	 * @param bold whether to print the text bold
	 */
	private void append(String text, Color color, boolean bold) {
		
		IDocument doc = getDocument();
		try {
			int offset = doc.getLength();
			int length = text.length();
			
			text = text + '\n';
			
			if (offset > 0) {
				doc.replace(offset, 0, text);
			} else {
				doc.set(text);
			}
			
			StyleRange style = new StyleRange();
			style.start = offset;
			style.length = length;
			style.foreground = color;
			
			if (bold) {
				style.fontStyle = SWT.BOLD;
			}
			
			output.getTextWidget().setStyleRange(style);
		} catch (BadLocationException e) {
			IStatus status = new Status(
				IStatus.ERROR,
				XtextConsolePlugin.getPluginId(),
				1,
				ConsoleMessages.Output_Exception,
				e);
			
			XtextConsolePlugin.getInstance().getLog().log(status);
		}
	}
	
	@Override
    public void createControl(Composite parent) {
		// force left-to-right text direction in the console, because it
		//    works with OCL text and the OCL language is based on English
		page = new SashForm(parent, SWT.VERTICAL | SWT.LEFT_TO_RIGHT);
		
		output = new TextViewer(page, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
		output.getTextWidget().setLayoutData(new GridData(GridData.FILL_BOTH));
		output.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
		output.setEditable(false);
		output.setDocument(new Document());

		colorManager = new ColorManager();
//		document.setOCLFactory(oclFactory);
//		document.setModelingLevel(modelingLevel);
		
		createEditor(page);
		input = editor.getViewer();
		input.getTextWidget().addKeyListener(new InputKeyListener());
		input.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
		
		selectionListener = new ISelectionListener() {
            public void selectionChanged(IWorkbenchPart part, final ISelection selection) {
//				System.out.println("selectionChanged: ");
            	if (part instanceof IConsoleView) {
            		IConsole console = ((IConsoleView)part).getConsole();
                	if (console instanceof OCLConsole) {
                		return;
                	}
            	}
            	if (part instanceof ContentOutline) {
            		ContentOutline contentOutline = (ContentOutline)part;
            		IPage currentPage = contentOutline.getCurrentPage();
                	if (currentPage instanceof OutlinePage) {
                		OutlinePage outlinePage = (OutlinePage)currentPage;
                		IXtextDocument xtextDocument = outlinePage.getXtextDocument();
                		Element pivotElement = xtextDocument.readOnly(new IUnitOfWork<Element, XtextResource>()
                		{
							public Element exec(XtextResource state) throws Exception {
								if (selection instanceof IStructuredSelection) {
									IStructuredSelection structuredSelection = (IStructuredSelection) selection;
									if (structuredSelection.size() == 1) {
										Object selectedObject = structuredSelection.getFirstElement();
										if (selectedObject instanceof EObjectNode) {
											EObjectNode eObjectNode = (EObjectNode)selectedObject;
											URI uri = eObjectNode.getEObjectURI();
											EObject csObject = state.getEObject(uri.fragment());
											if (csObject instanceof Pivotable) {
												Element pivotObject = ((Pivotable)csObject).getPivot();
												if (pivotObject != null) {
									                return pivotObject;													
												}
											}
										}
									}
								}		
								return null;
							}
						});
                		if (pivotElement != null) {
                            OCLConsolePage.this.selectionChanged(new StructuredSelection(pivotElement));
                            return;
                		}
                	}
            	}
                OCLConsolePage.this.selectionChanged(selection);
            }};
		selectionService = getSite().getWorkbenchWindow().getSelectionService();
		selectionService.addPostSelectionListener(selectionListener);
		
		// get current selection
//		ISelection selection = selectionService.getSelection();			// Doesn't have a value preceding console start
		ISelection selection = getActiveSelection();
		selectionChanged(selection);
		
		((SashForm) page).setWeights(new int[] {2, 1});
		
		ClearOutputAction clear = new ClearOutputAction(output);
		CloseAction close = new CloseAction();
		SaveExpressionAction saveExpression = new SaveExpressionAction(this);
		LoadExpressionAction loadExpression = new LoadExpressionAction(this);
		Action loadResource = new LoadResourceAction(this);		
		validateAction = new ValidateAction(this);		
		
		IMenuManager menu = getSite().getActionBars().getMenuManager();
		menu.add(loadResource);
		menu.add(validateAction);
		menu.add(loadExpression);
		menu.add(saveExpression);
		menu.add(clear);
		menu.add(close);
	    
//		IMenuManager metamodelMenu = new MenuManager(
//		    OCLInterpreterMessages.console_metamodelMenu,
//		    "org.eclipse.ocl.examples.xtext.console.metamodel"); //$NON-NLS-1$
//		menu.add(metamodelMenu);
//		DropDownAction metamodelAction = new DropDownAction();
//		metamodelAction.setToolTipText(OCLInterpreterMessages.console_metamodelTip);
//		addMetamodelActions(metamodelMenu, metamodelAction);
		
//		IMenuManager levelMenu = new MenuManager(OCLInterpreterMessages.console_modelingLevel);
//		menu.add(levelMenu);
//        DropDownAction levelAction = new DropDownAction();
//        levelAction.setToolTipText(OCLInterpreterMessages.console_modelingLevelTip);
//		IAction m2 = new ModelingLevelAction(ModelingLevel.M2);
//		m2.setChecked(true);
//		levelMenu.add(m2);
//		levelAction.addAction(m2);
//		IAction m1 = new ModelingLevelAction(ModelingLevel.M1);
//		levelMenu.add(m1);
//		levelAction.addAction(m1);

//		ActionContributionItem metamodelItem = new ActionContributionItem(
//		    metamodelAction);
//		metamodelItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
		
		IToolBarManager toolbar = getSite().getActionBars().getToolBarManager();
//        toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, metamodelItem);
//        toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, levelAction);
		toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, loadResource);
		toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, validateAction);
		toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, loadExpression);
		toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, saveExpression);
		toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, clear);
		toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, close);
	}

	private int convertHeightInCharsToPixels(int i) {
		// Create a GC to calculate font's dimensions
	    GC gc = new GC(Display.getDefault());
	    gc.setFont(editor.getViewer().getTextWidget().getFont());

	    // Determine string's dimensions
	    FontMetrics fontMetrics = gc.getFontMetrics();

	    int ret = (fontMetrics.getHeight() + fontMetrics.getAscent() + fontMetrics.getDescent() + fontMetrics.getLeading()) * i;
	    
	    // Dispose that gc
	    gc.dispose();
		
	    return ret;
	}

    private void createEditor(Composite s1) {
		
		Composite client = s1; //new Composite(s1, SWT.NULL);
		Injector injector = XtextConsolePlugin.getInstance().getInjector(EssentialOCLPlugin.LANGUAGE_ID);
		Composite editorComposite = client; //new Composite(client, SWT.NULL);
		editor = new EmbeddedXtextEditor(editorComposite, injector, /*SWT.BORDER |*/ SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
		MetaModelManagerResourceSetAdapter.getAdapter(editor.getResourceSet(), metaModelManager);

/*		editor.getViewer().getTextWidget().addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = editor.getViewer().getTextWidget().getText();
				System.out.println("modifyText: " + text);
//				if (!text.equals(getEditedEObject().getAsString())) {
//					getEditor().setDirty(true);
//					getEditor().firePropertyChange(IEditorPart.PROP_DIRTY);
//				} else {
//					getEditor().setDirty(false);
//					getEditor().firePropertyChange(IEditorPart.PROP_DIRTY);
//				} 
			}
		}); */
/*		editor.getDocument().addModelListener(new IXtextModelListener() {
			public void modelChanged(XtextResource resource) {
				System.out.println("modelChanged: " + resource);
//				reconcileChangedModel();
			}
		}); */
		
		editor.getViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {
			public void verifyKey(VerifyEvent e) {
//				System.out.println("verifyKey: " + e.keyCode);
				if (e.keyCode == SWT.KEYPAD_CR || e.keyCode == SWT.CR) {
					e.doit = false;
				}
			}
		});
		
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.heightHint= convertHeightInCharsToPixels(1);
		editorComposite.setLayoutData(data);
	}
	
	/**
	 * Extends the inherited method to dispose of additional colour resources.
	 */
	@Override
    public void dispose() {
	    colorManager.dispose();
	    selectionService.removePostSelectionListener(selectionListener);
	    
		super.dispose();
	}
	
	/**
	 * Prints an error message to the output viewer, in red text.
	 * 
	 * @param message the error message to print
	 */
	private void error(String message) {
		append(message, colorManager.getColor(ColorManager.OUTPUT_ERROR), false);
		scrollText();
	}
	
	/**
	 * Evaluates an OCL expression using the OCL Interpreter's {@link OCLHelper}
	 * API.
	 * 
	 * @param expression an OCL expression
	 * 
	 * @return <code>true</code> on successful evaluation; <code>false</code>
	 *    if the expression failed to parse or evaluate
	 */
	boolean evaluate(final String expression) {        
//		if (contextObject == null) {
//			error(OCLInterpreterMessages.console_noContext);
//			return false;
//		} 
		if ((expression == null) || (expression.trim().length() <= 0)) {
			error(ConsoleMessages.Result_NoExpression);
			return false;
		} 
//		editorDocument.getResource();
		// create an OCL helper to do our parsing and evaluating
//      ocl = oclFactory.createOCL(modelingLevel);
//      OCLHelper helper = ocl.createOCLHelper();
		boolean result = true;			
		try {
				// set our helper's context classifier to parse against it
//	        ConstraintKind kind = modelingLevel.setContext(helper, context, oclFactory);
				
			IDocument doc = getDocument();
			Color defaultColor = colorManager.getColor(ColorManager.DEFAULT);
            Color resultsColor = colorManager.getColor(ColorManager.OUTPUT_RESULTS);
            Color errorColor = colorManager.getColor(ColorManager.OUTPUT_ERROR);
				
            if (doc.getLength() > 0) {
				// separate previous output by a blank line
				append("", defaultColor, false); //$NON-NLS-1$
			}
			
			append(ConsoleMessages.Heading_Evaluating, defaultColor, true);
			append(expression, defaultColor, false);
			append(ConsoleMessages.Heading_Results, defaultColor, true);
            
            switch (modelingLevel) {
                case M2:
        			final BaseDocument editorDocument = getEditorDocument();
        			Value value = null;
        			try {
        				value = editorDocument.readOnly(new IUnitOfWork<Value, XtextResource>() {
 
						public Value exec(XtextResource state) throws Exception {
							IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
							EvaluationRunnable runnable = new EvaluationRunnable(state, expression);
							progressService.busyCursorWhile(runnable);
			       			return runnable.getValue();
						}});
           			}
        			catch (Exception e) {
        				append(e.getMessage(), errorColor, false);
        			}
        			if (value instanceof ExceptionValue) {
        				append(((ExceptionValue)value).getMessage(), errorColor, true);
        				append(String.valueOf(value), errorColor, false);
        			}
        			else if ((value != null) && (value.isCollectionValue() != null)) {
        				for (Value elementValue : value.isCollectionValue()) {
        					append(String.valueOf(elementValue), resultsColor, false);
        				}
        			}
        			else if (value != null) {
        				append(String.valueOf(value), resultsColor, false);
        			}
        			else {
        				append(String.valueOf(value), errorColor, false);
        			}
                	scrollText();
                    break;
                case M1:
//                    helper.createConstraint(kind, expression);
                    
                    // just report a successful parse
                	append(ConsoleMessages.Result_Parsed, resultsColor, false);
                	scrollText();
                    break;
            }
            
			// store the successfully parsed expression
			lastOCLExpression = expression;
		} catch (Exception e) {
			result = false;
			error((e.getLocalizedMessage() == null) ? e.getClass().getName()
					: e.getLocalizedMessage());
		}
		
		return result;
	}

	protected ISelection getActiveSelection() {
		try {
			IPageSite site = getSite();
			if (site == null) {
				return null;
			}
			IWorkbenchWindow workbenchWindow = site.getWorkbenchWindow();
			if (workbenchWindow == null) {
				return null;
			}
			IWorkbenchPage activePage = workbenchWindow.getActivePage();
			if (activePage == null) {
				return null;
			}
			IEditorPart activeEditor = activePage.getActiveEditor();
			if (activeEditor == null) {
				return null;
			}
			IEditorSite editorSite = activeEditor.getEditorSite();
			if (editorSite == null) {
				return null;
			}
			ISelectionProvider selectionProvider = editorSite.getSelectionProvider();
			if (selectionProvider == null) {
				return null;
			}
			return selectionProvider.getSelection();
		}
		catch (Exception e) {
			return  null;
		}
	}
    
	@Override
    public Control getControl() {
		return page;
	}
	
	/**
	 * Obtains the document in the output viewer.
	 * 
	 * @return the output document
	 */
	private IDocument getDocument() {
		return output.getDocument();
	}

	public IXtextDocument getDocument(URI trimFragment) {
		return getEditorDocument();
	}
	
	public BaseDocument getEditorDocument() {
		return (BaseDocument) editor.getDocument();
	}
    
    /**
     * Gets the editor image for the specified element.
     * 
     * @param element a model element
     * 
     * @return the corresponding image
     *
    private ImageDescriptor getImage(EObject element) {
        ImageDescriptor result = null;
        
        IItemLabelProvider provider = (IItemLabelProvider) new ComposedAdapterFactory(
            ComposedAdapterFactory.Descriptor.Registry.INSTANCE).adapt(
                element, IItemLabelProvider.class);
        if (provider != null) {
            Object image = provider.getImage(element);
            if (image != null) {
                result = ExtendedImageRegistry.INSTANCE.getImageDescriptor(image);
            }
        }
        
        return result;
    } */
	
	public String getLastOCLExpression() {
		return lastOCLExpression;
	}
	
	/**
	 * Prints the specified <code>object</code> to the output viewer.  The
	 * object is converted to a string using the best matching EMF label
	 * provider adapter if it is an {@link EObject}; otherwise, just use
	 * {@link String#valueOf(java.lang.Object)} on it.  If the
	 * <code>object</code> is a collection or an array, then we print each
	 * element on a separate line.
	 * 
	 * @param object the object or collection to print
	 * @param color the color to print the <code>object</code> with
	 * @param bold whether to display it in bold text
	 *
	private void print(Value value, Color color, boolean bold) {
		CollectionValue collectionValue = value.isCollectionValue();
		if (collectionValue != null) {
			for (Value elementValue : collectionValue) {
				append(String.valueOf(elementValue), color, bold);
			}
		}
		else {
			append(String.valueOf(value), color, bold);
		}
/*		Collection<?> toPrint;
		
		if (object == null) {
			toPrint = Collections.EMPTY_SET;
		} else if (object instanceof Collection) {
			toPrint = (Collection<?>) object;
		} else if (object.getClass().isArray()) {
			toPrint = Arrays.asList((Object[]) object);
		} else {
			toPrint = Collections.singleton(object);
		}
		
		for (Iterator<?> iter = toPrint.iterator(); iter.hasNext();) {
			append(toString(iter.next()), color, bold);
		} * /
//		append(String.valueOf(object), color, bold);
		
		scrollText();
	} */

	protected void refreshSelection(final Object selected) {
		final BaseDocument editorDocument = getEditorDocument();
		editorDocument.modify(new IUnitOfWork<Object, XtextResource>()
		{
			public Value exec(XtextResource resource) throws Exception {
				Object selectedObject = selected;
			    if (selectedObject instanceof IOutlineNode) {
		    	    if (selectedObject instanceof EObjectNode) {
		                EObjectNode selectedObjectNode = (EObjectNode) selectedObject;
		                URI eObjectURI = selectedObjectNode.getEObjectURI();
		        		contextObject = metaModelManager.loadResource(eObjectURI, null, null);
		        		contextClassifier = selectedObjectNode.getEClass();
		    	    }
		    	    else if (selectedObject instanceof EStructuralFeatureNode) {
		            	contextObject = null;
		    	    	contextClassifier = ((EStructuralFeatureNode) selectedObject).getEStructuralFeature().getEContainingClass();
		    	    }
		    	    else {
		            	contextObject = null;
		    	    	contextClassifier = null;
		    	    }
			    }
			    else {
			    	if (selectedObject instanceof IAdaptable) {
			    		selectedObject = ((IAdaptable) selectedObject).getAdapter(EObject.class);
		            }
		            if (selectedObject instanceof EObject) {
		            	contextObject = (EObject) selectedObject;
		            	contextClassifier = contextObject.eClass();
		            }
		            else {
		            	contextObject = null;
		            	contextClassifier = null;
		            }
			    }	        
		        editorDocument.setContext((EssentialOCLCSResource) resource, contextClassifier, null);
		        console.setSelection(contextClassifier, contextObject);
		        if (validateAction != null) {
		        	validateAction.setSelection(contextObject);
		        }
		        return null;
			}
		});
	}
	
	/**
	 * Ensures that the last text printed to the output viewer is shown.
	 */
	private void scrollText() {
		output.revealRange(getDocument().getLength(), 0);
	}
	
	private void selectionChanged(ISelection sel) {
		Object selectedObject = null;
	    if (sel instanceof IStructuredSelection) {
            IStructuredSelection ssel = (IStructuredSelection) sel;
            
            if (!ssel.isEmpty()) {
                selectedObject = ssel.getFirstElement();
            }
	    }
        refreshSelection(selectedObject);
	}

	@Override
    public void setFocus() {
		input.getTextWidget().setFocus();
	}
	
	/**
	 * Programmatically sets my target metamodel.
	 * 
	 * @param metamodel the target metamodel
	 *
	public void setTargetMetamodel(TargetMetamodel metamodel) {
	    IAction action = metamodelActions.get(metamodel);

	    if (action != null) {
	        // deselect the old one
	        metamodelActions.get(oclFactory.getTargetMetamodel()).setChecked(false);
	        
    	    action.run();
    	    action.setChecked(true);
	    }
	} */
	
	/**
	 * Converts a single object to a string, according to the rules described
	 * for the {@link #print(Object, Color, boolean)} method.
	 * 
	 * @param object the object to print (not a collection type)
	 * @return the string form of the <code>object</code>
	 * 
	 * @see #print(Object, Color, boolean)
	 *
	String toString(Object object) {
		if (ocl.isInvalid(object)) {
			return "OclInvalid"; //$NON-NLS-1$
		} else if (object instanceof String) {
			return "'" + object + "'";  //$NON-NLS-1$//$NON-NLS-2$
		} else if (object instanceof TupleValue) {
			return tupleTypeLabelProvider.getText(object);
		} else if (object instanceof EObject) {
			EObject eObject = (EObject) object;
			
			IItemLabelProvider labeler =
				(IItemLabelProvider) defaultAdapterFactory.adapt(
					eObject,
					IItemLabelProvider.class);
			
			if (labeler == null) {
				labeler = (IItemLabelProvider) reflectiveAdapterFactory.adapt(
					eObject,
					IItemLabelProvider.class);
			}
			
			if (labeler != null) {
				return labeler.getText(object);
			}
		}
		
		return String.valueOf(object);
	} */
}
