/*******************************************************************************
 * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
 *     Soyatec - initial API and implementation
 *******************************************************************************/
package org.eclipse.xwt.ui.editor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.resources.IResource;
import org.eclipse.xwt.IEventConstants;
import org.eclipse.xwt.XWT;
import org.eclipse.xwt.XWTMaps;
import org.eclipse.xwt.internal.utils.UserData;
import org.eclipse.xwt.javabean.metadata.Metaclass;
import org.eclipse.xwt.metadata.IEvent;
import org.eclipse.xwt.metadata.IMetaclass;
import org.eclipse.xwt.metadata.IProperty;
import org.eclipse.xwt.utils.NamedColorsUtil;
import org.eclipse.xwt.utils.ResourceManager;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
import org.eclipse.wst.xml.ui.internal.contentassist.AbstractContentAssistProcessor;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages;
import org.eclipse.wst.xml.ui.internal.preferences.XMLUIPreferenceNames;
import org.eclipse.wst.xml.ui.internal.templates.TemplateContextTypeIdsXML;
import org.eclipse.xwt.ui.utils.ImageManager;
import org.eclipse.xwt.vex.contentassist.SelectionCompletionProposal;
import org.eclipse.xwt.vex.contentassist.VEXTemplateCompletionProcessor;
import org.eclipse.xwt.vex.dom.DomHelper;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XWTContentAssistProcessor extends AbstractContentAssistProcessor
		implements IPropertyChangeListener {
	static final String HANDLER_PREFIX = "on";
	static SelectionCompletionProposal[] booleanProposals;
	static SelectionCompletionProposal[] colorsProposals;
	static SelectionCompletionProposal[] stylesProposals;
	static SelectionCompletionProposal[] acceleratorsProposals;

	protected IPreferenceStore fPreferenceStore = null;
	protected IResource fResource = null;
	private VEXTemplateCompletionProcessor fTemplateProcessor = null;
	private List<String> fTemplateContexts = new ArrayList<String>();

	protected Comparator<ICompletionProposal> comparator = new Comparator<ICompletionProposal>() {

		public int compare(ICompletionProposal o1, ICompletionProposal o2) {
			return o1.getDisplayString().compareTo(o2.getDisplayString());
		}
	};

	static SelectionCompletionProposal[] getBooleanProposals() {
		if (booleanProposals == null) {
			String[] values = new String[] { "True", "False" };
			Image image = ImageManager
					.get(XMLEditorPluginImages.IMG_OBJ_ATTRIBUTE);
			booleanProposals = new SelectionCompletionProposal[values.length];
			for (int j = 0; j < values.length; j++) {
				String pattern = "\"" + values[j] + "\"";
				booleanProposals[j] = new SelectionCompletionProposal(pattern,
						0, 0, 1, values[j].length(), image, values[j], null,
						null);
			}
		}
		return booleanProposals;
	}

	static SelectionCompletionProposal[] getColorsProposals() {
		if (colorsProposals == null) {
			Collection<String> names = XWTMaps.getColorKeys();
			String[] colorNames = NamedColorsUtil.getColorNames();
			colorsProposals = new SelectionCompletionProposal[names.size()
					+ colorNames.length];

			int i = 0;
			for (String colorStr : names) {
				Color color = ResourceManager.resources.getColor(colorStr);
				SelectionCompletionProposal p = createColorProposal(color,
						colorStr);
				if (p != null) {
					colorsProposals[i++] = p;
				}
			}
			for (String colorName : colorNames) {
				Color color = ResourceManager.resources.getColor(colorName);
				SelectionCompletionProposal p = createColorProposal(color,
						colorName);
				if (p != null) {
					colorsProposals[i++] = p;
				}
			}
		}
		return colorsProposals;
	}

	static SelectionCompletionProposal createColorProposal(Color color,
			String colorName) {
		if (color != null) {
			String pattern = "\"" + colorName + "\"";
			Image image = new Image(null, 16, 16);
			GC gc = new GC(image);
			gc.setBackground(color);
			gc.fillRectangle(0, 0, 16, 16);
			gc.dispose();
			return new SelectionCompletionProposal(pattern, 0, 0, 1,
					colorName.length(), image, colorName, null, null);
		}
		return null;

	}

	static SelectionCompletionProposal[] getStylesProposals() {
		if (stylesProposals == null) {
			Collection<String> names = XWTMaps.getStyleKeys();
			stylesProposals = new SelectionCompletionProposal[names.size()];
			int i = 0;
			for (String string : names) {
				String pattern = "\"" + string + "\"";
				stylesProposals[i++] = new SelectionCompletionProposal(pattern,
						0, 0, 1, string.length(), null, string, null, null);
			}
		}
		return stylesProposals;
	}

	static SelectionCompletionProposal[] getAcceleratorsProposals() {
		if (acceleratorsProposals == null) {
			Collection<String> names = XWTMaps.getAcceleratorKeys();
			acceleratorsProposals = new SelectionCompletionProposal[names
					.size()];
			int i = 0;
			for (String string : names) {
				String pattern = "\"" + string + "\"";
				acceleratorsProposals[i++] = new SelectionCompletionProposal(
						pattern, 0, 0, 1, string.length(), null, string, null,
						null);
			}
		}
		return acceleratorsProposals;
	}

	@Override
	protected void addAttributeNameProposals(
			ContentAssistRequest contentAssistRequest) {
		addXAMLPropertyNameProposals(contentAssistRequest);

		addTemplates(contentAssistRequest, TemplateContextTypeIdsXML.ATTRIBUTE);
		super.addAttributeNameProposals(contentAssistRequest);
	}

	private void addXAMLPropertyNameProposals(
			ContentAssistRequest contentAssistRequest) {
		List<ICompletionProposal> proposalCollector = new ArrayList<ICompletionProposal>();
		List<ICompletionProposal> macrosCollector = new ArrayList<ICompletionProposal>();

		//
		Node node = contentAssistRequest.getNode();
		String name = getNodeName(node);

		HashSet<String> existing = new HashSet<String>();
		NamedNodeMap namedNodeMap = node.getAttributes();
		for (int i = 0; i < namedNodeMap.getLength(); i++) {
			Node attributeNode = namedNodeMap.item(i);
			String attributeName = attributeNode.getNodeName();
			existing.add(attributeName);
		}
		boolean useProposalList = !contentAssistRequest.shouldSeparate();
		int offset = contentAssistRequest.getReplacementBeginPosition();
		int replacementLength = contentAssistRequest.getReplacementLength();
		IDocument document = fTextViewer.getDocument();
		String prefixed = null;
		try {
			prefixed = document.get(offset, replacementLength).toLowerCase();
		} catch (BadLocationException e1) {
		}

		IMetaclass metaclass = XWT.getMetaclass(name,
				DomHelper.lookupNamespaceURI(node));
		if (metaclass != null) {
			IProperty[] properties = metaclass.getProperties();
			for (IProperty property : properties) {
				Class<?> propertyType = property.getType();
				if (propertyType != null
						&& Control.class.isAssignableFrom(propertyType)) {
					continue;
				}

				String propertyName = property.getName();
				if (prefixed != null
						&& !propertyName.toLowerCase().startsWith(prefixed)) {
					continue;
				}

				if (!existing.contains(propertyName)) {
					String defaultValueString = "";
					if (propertyName.equalsIgnoreCase("style")) {
						propertyName = "x:style";
						defaultValueString = "SWT.NONE";
					}
					String replacementString = propertyName + "=\""
							+ defaultValueString + "\" ";
					Image image = JavaPluginImages
							.get(JavaPluginImages.IMG_FIELD_PUBLIC);
					SelectionCompletionProposal proposal = new SelectionCompletionProposal(
							replacementString, offset, replacementLength,
							propertyName.length() + 2,
							defaultValueString.length(), image, propertyName,
							null, "Property: " + propertyName);
					if (useProposalList) {
						proposalCollector.add(proposal);
					} else {
						macrosCollector.add(proposal);
					}
				}
			}

			IEvent[] events = metaclass.getEvents();
			for (IEvent event : events) {
				String eventName = event.getName();
				if (prefixed != null
						&& !eventName.toLowerCase().startsWith(prefixed)) {
					continue;
				}

				eventName = Character.toUpperCase(eventName.charAt(0))
						+ eventName.substring(1) + IEventConstants.SUFFIX;
				if (event.getName() != null
						&& (event.getName().equals(IEventConstants.XWT_LOADED) || 
								event.getName().equals(IEventConstants.XWT_LOADED_EVENT))) {
					eventName = IEventConstants.XWT_LOADED_EVENT;
				}

				if (!existing.contains(eventName)) {
					String replacementString = eventName + "=\""
							+ HANDLER_PREFIX + eventName + "\" ";
					Image image = ImageManager.get(ImageManager.IMG_EVENT);
					SelectionCompletionProposal proposal = new SelectionCompletionProposal(
							replacementString, offset, replacementLength,
							eventName.length() + 2, eventName.length()
									+ HANDLER_PREFIX.length(), image,
							eventName, null, "Event: " + eventName);
					if (useProposalList) {
						proposalCollector.add(proposal);
					} else {
						macrosCollector.add(proposal);
					}
				}
			}
		}

		Node parentNode = node.getParentNode();
		String parentName = getNodeName(parentNode);
		try {
			IMetaclass parentMetaclass = XWT.getMetaclass(parentName,
					DomHelper.lookupNamespaceURI(parentNode));
			if (parentMetaclass != null) {
				// Attached property
			}
		} catch (Exception e) {
		}

		Collections.sort(proposalCollector, comparator);
		Collections.sort(macrosCollector, comparator);

		for (ICompletionProposal proposal : proposalCollector) {
			contentAssistRequest.addProposal(proposal);
		}

		for (ICompletionProposal proposal : macrosCollector) {
			contentAssistRequest.addMacro(proposal);
		}
	}

	@Override
	protected void addAttributeValueProposals(
			ContentAssistRequest contentAssistRequest) {
		addXAMLPropertyValueProposals(contentAssistRequest);

		addTemplates(contentAssistRequest,
				TemplateContextTypeIdsXML.ATTRIBUTE_VALUE);
		super.addAttributeValueProposals(contentAssistRequest);
	}

	private void addXAMLPropertyValueProposals(
			ContentAssistRequest contentAssistRequest) {
		List<ICompletionProposal> proposalCollector = new ArrayList<ICompletionProposal>();
		List<ICompletionProposal> macrosCollector = new ArrayList<ICompletionProposal>();

		IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
		String name = getNodeName(node);
		IMetaclass metaclass = XWT.getMetaclass(name,
				DomHelper.lookupNamespaceURI(node));
		StyledText textWidget = fTextViewer.getTextWidget();
		if (metaclass != null) {
			// Find the attribute region and name for which this position should
			// have a value proposed
			IStructuredDocumentRegion open = node
					.getFirstStructuredDocumentRegion();
			ITextRegionList openRegions = open.getRegions();
			int m = openRegions.indexOf(contentAssistRequest.getRegion());
			if (m < 0) {
				return;
			}
			ITextRegion nameRegion = null;
			while (m >= 0) {
				nameRegion = openRegions.get(m--);
				if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
					break;
				}
			}

			// the name region is REQUIRED to do anything useful
			if (nameRegion != null) {
				// Retrieve the declaration
				CMElementDeclaration elementDecl = getCMElementDeclaration(node);

				// String attributeName = nameRegion.getText();
				String attributeName = open.getText(nameRegion);
				IProperty property = metaclass.findProperty(attributeName);
				if (attributeName.equalsIgnoreCase("x:style")
						|| property != null) {
					int offset = contentAssistRequest
							.getReplacementBeginPosition();
					int replacementLength = contentAssistRequest
							.getReplacementLength();
					boolean useProposalList = !contentAssistRequest
							.shouldSeparate();

					String prefixed = null;
					String prefixedQuote = "";
					boolean fullValue = true;
					try {
						int caretIndex = textWidget.getCaretOffset();
						IDocument document = fTextViewer.getDocument();
						prefixed = document.get(offset, caretIndex - offset)
								.toLowerCase();
						if (prefixed.equals("\"\"")) {
							prefixed = null;
						}
					} catch (BadLocationException e1) {
					}
					if (prefixed != null) {
						prefixedQuote = prefixed + "\"";
						fullValue = false;
					}

					// filter accelerators of menu element.
					if (attributeName.equalsIgnoreCase("accelerator")) {
						SelectionCompletionProposal[] proposals = getAcceleratorsProposals();
						for (int j = 0; j < proposals.length; j++) {
							String pattern = proposals[j]
									.getReplacementString();
							if (prefixed != null
									&& ((!pattern.toLowerCase().startsWith(
											prefixed) && !fullValue) || prefixedQuote
											.equalsIgnoreCase(pattern))) {
								continue;
							}

							proposals[j].setReplacementOffset(offset);
							proposals[j]
									.setReplacementLength(replacementLength);
							if (useProposalList) {
								proposalCollector.add(proposals[j]);
							} else {
								macrosCollector.add(proposals[j]);
							}
						}
						Collections.sort(proposalCollector, comparator);
						Collections.sort(macrosCollector, comparator);

						for (ICompletionProposal proposal : proposalCollector) {
							contentAssistRequest.addProposal(proposal);
						}

						for (ICompletionProposal proposal : macrosCollector) {
							contentAssistRequest.addMacro(proposal);
						}
						return;
					}

					// styles TODO: filter styles of each element.
					if (attributeName.equalsIgnoreCase("x:style")) {
						SelectionCompletionProposal[] proposals = getStylesProposals();
						for (int j = 0; j < proposals.length; j++) {
							String pattern = proposals[j]
									.getReplacementString();
							if (prefixed != null
									&& ((!pattern.toLowerCase().startsWith(
											prefixed) && !fullValue) || prefixedQuote
											.equalsIgnoreCase(pattern))) {
								continue;
							}

							proposals[j].setReplacementOffset(offset);
							proposals[j]
									.setReplacementLength(replacementLength);
							if (useProposalList) {
								proposalCollector.add(proposals[j]);
							} else {
								macrosCollector.add(proposals[j]);
							}
						}
						Collections.sort(proposalCollector, comparator);
						Collections.sort(macrosCollector, comparator);

						for (ICompletionProposal proposal : proposalCollector) {
							contentAssistRequest.addProposal(proposal);
						}

						for (ICompletionProposal proposal : macrosCollector) {
							contentAssistRequest.addMacro(proposal);
						}
						return;
					}
					Class<?> javaType = property.getType();
					if (javaType == Boolean.class || javaType == boolean.class) {
						SelectionCompletionProposal[] proposals = getBooleanProposals();
						for (int j = 0; j < proposals.length; j++) {
							String pattern = proposals[j]
									.getReplacementString();
							if (prefixed != null
									&& ((!pattern.toLowerCase().startsWith(
											prefixed) && !fullValue) || prefixedQuote
											.equalsIgnoreCase(pattern))) {
								continue;
							}

							proposals[j].setReplacementOffset(offset);
							proposals[j]
									.setReplacementLength(replacementLength);
							if (useProposalList) {
								proposalCollector.add(proposals[j]);
							} else {
								macrosCollector.add(proposals[j]);
							}
						}
					} else if (javaType != null && javaType.isEnum()) {
						Object[] objects = javaType.getEnumConstants();

						IConverter converter = XWT.findConvertor(javaType,
								String.class);
						for (int j = 0; j < objects.length; j++) {
							String valueString = "";
							if (converter != null) {
								Object stringValue = converter
										.convert(objects[j]);
								if (stringValue != null) {
									valueString = stringValue.toString();
								}
							} else {
								valueString = objects[j].toString();
							}
							String pattern = "\"" + valueString + "\"";
							if (prefixed != null
									&& ((!pattern.toLowerCase().startsWith(
											prefixed) && !fullValue) || prefixedQuote
											.equalsIgnoreCase(pattern))) {
								continue;
							}
							Image image = ImageManager
									.get(XMLEditorPluginImages.IMG_OBJ_ENUM);
							SelectionCompletionProposal proposal = new SelectionCompletionProposal(
									pattern, offset, replacementLength, 1,
									valueString.length(), image, valueString,
									null, null);
							if (useProposalList) {
								proposalCollector.add(proposal);
							} else {
								macrosCollector.add(proposal);
							}
						}
					} else if (javaType.isAssignableFrom(Color.class)) {
						SelectionCompletionProposal[] colorsProposals = getColorsProposals();
						for (SelectionCompletionProposal proposal : colorsProposals) {
							String pattern = proposal.getReplacementString();
							if (prefixed != null
									&& ((!pattern.toLowerCase().startsWith(
											prefixed) && !fullValue) || prefixedQuote
											.equalsIgnoreCase(pattern))) {
								continue;
							}

							proposal.setReplacementOffset(offset);
							proposal.setReplacementLength(replacementLength);
							if (useProposalList) {
								proposalCollector.add(proposal);
							} else {
								macrosCollector.add(proposal);
							}
						}
					}
				} else {
					IEvent[] allEvents = metaclass.getEvents();
					JavaProject javaProject = (JavaProject) textWidget
							.getData("javaProject");
					String className = (String) textWidget.getData("className");
					List<String> javaMethods = getJavaMethods(javaProject,
							className);
					int offset = contentAssistRequest
							.getReplacementBeginPosition();
					int caretIndex = textWidget.getCaretOffset();
					IDocument document = fTextViewer.getDocument();
					String prefixed = null;
					try {
						prefixed = document.get(offset + 1, caretIndex - offset
								- 1);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
					int replacementLength = contentAssistRequest
							.getReplacementLength();
					boolean useProposalList = !contentAssistRequest
							.shouldSeparate();
					for (Iterator<String> iterator = javaMethods.iterator(); iterator
							.hasNext();) {
						String valueString = iterator.next();
						if (valueString.equals(prefixed))
							continue;
						String pattern = "\"" + valueString + "\"";
						SelectionCompletionProposal proposal = new SelectionCompletionProposal(
								pattern, offset, replacementLength, 1,
								valueString.length(), null, valueString, null,
								null);
						if (useProposalList) {
							proposalCollector.add(proposal);
						} else {
							macrosCollector.add(proposal);
						}
					}
				}
			}
		}

		Collections.sort(proposalCollector, comparator);
		Collections.sort(macrosCollector, comparator);

		for (ICompletionProposal proposal : proposalCollector) {
			contentAssistRequest.addProposal(proposal);
		}

		for (ICompletionProposal proposal : macrosCollector) {
			contentAssistRequest.addMacro(proposal);
		}
	}

	@Override
	protected void addEmptyDocumentProposals(
			ContentAssistRequest contentAssistRequest) {
		addTemplates(contentAssistRequest, TemplateContextTypeIdsXML.NEW);
		super.addEmptyDocumentProposals(contentAssistRequest);
	}

	@Override
	protected void addTagInsertionProposals(
			ContentAssistRequest contentAssistRequest, int childPosition) {
		addXAMLElementProposals(contentAssistRequest);
		addTemplates(contentAssistRequest, TemplateContextTypeIdsXML.TAG);
		super.addTagInsertionProposals(contentAssistRequest, childPosition);
	}

	private void addXAMLElementProposals(
			ContentAssistRequest contentAssistRequest) {
		List<ICompletionProposal> proposalCollector = new ArrayList<ICompletionProposal>();
		List<ICompletionProposal> macrosCollector = new ArrayList<ICompletionProposal>();

		List<String> addedTags = new ArrayList<String>();

		boolean useProposalList = !contentAssistRequest.shouldSeparate();
		int offset = contentAssistRequest.getReplacementBeginPosition();
		int replacementLength = contentAssistRequest.getReplacementLength();
		String prefixed = null;
		try {
			IDocument document = fTextViewer.getDocument();
			prefixed = document.get(offset, replacementLength).toLowerCase();
		} catch (BadLocationException e1) {
		}

		Node node = contentAssistRequest.getNode();
		if (node == null) {
			return;
		}
		if (node instanceof IDOMText) {
			IDOMText text = (IDOMText) node;
			offset = text.getStartOffset();
			replacementLength = text.getLength();
			try {
				IDocument document = fTextViewer.getDocument();
				prefixed = document.get(offset, replacementLength).trim()
						.toLowerCase();
			} catch (BadLocationException e1) {
			}
		} else if (node instanceof IDOMNode) {
			IDOMNode domNode = (IDOMNode) node;
			NodeList children = domNode.getChildNodes();
			for (int i = 0; i < children.getLength(); i++) {
				Node child = children.item(i);
				if (child instanceof IDOMText) {
					IDOMText text = (IDOMText) child;
					offset = text.getStartOffset();
					replacementLength = text.getLength();
					try {
						IDocument document = fTextViewer.getDocument();
						prefixed = document.get(offset, replacementLength)
								.trim().toLowerCase();
					} catch (BadLocationException e1) {
					}
					break;
				}
			}
		}

		while (node.getNodeType() != Node.ELEMENT_NODE) {
			node = node.getParentNode();
			if (node == null) {
				return;
			}
		}

		boolean containControls = false;
		String name = getNodeName(node);
		if (name.indexOf(".") != -1) {
			if (name.toLowerCase().endsWith(".control")) {
				name = "Control";// Add controls to TabItem, CoolItem...
				containControls = true;
			} else {
				List<SelectionCompletionProposal> proposals = createPropertyNodeProposals(
						name, offset, replacementLength);
				if (useProposalList) {
					proposalCollector.addAll(proposals);
				} else {
					macrosCollector.addAll(proposals);
				}
				Collections.sort(proposalCollector, comparator);
				Collections.sort(macrosCollector, comparator);

				for (ICompletionProposal proposal : proposalCollector) {
					contentAssistRequest.addProposal(proposal);
				}

				for (ICompletionProposal proposal : macrosCollector) {
					contentAssistRequest.addMacro(proposal);
				}
				return;
			}
		}
		IMetaclass metaclass = XWT.getMetaclass(name,
				DomHelper.lookupNamespaceURI(node));
		String tagName = name + ".Resources";
		if (!addedTags.contains(tagName)
				&& (prefixed == null || tagName.toLowerCase().startsWith(
						prefixed))) {
			addedTags.add(tagName);

			String pattern = "<" + tagName + "></" + tagName + ">";
			Image image = ImageManager.get(ImageManager.IMG_RESOURCES);
			SelectionCompletionProposal proposal = new SelectionCompletionProposal(
					pattern, offset, replacementLength, tagName.length() + 2,
					0, image, tagName, null, "Element resources");
			if (useProposalList) {
				proposalCollector.add(proposal);
			} else {
				macrosCollector.add(proposal);
			}
		}

		// layout
		String layout = name + ".layout";
		if (!addedTags.contains(layout)
				&& (prefixed == null || layout.startsWith(prefixed))) {
			SelectionCompletionProposal layoutProposal = createLayoutProposal(
					metaclass, layout, offset, replacementLength);
			if (layoutProposal != null) {
				if (useProposalList) {
					proposalCollector.add(layoutProposal);
				} else {
					macrosCollector.add(layoutProposal);
				}
			}
		}
		// layoutData
		String layoutData = name + ".layoutData";
		if (!addedTags.contains(layout)
				&& (prefixed == null || layout.startsWith(prefixed))) {
			SelectionCompletionProposal proposal = createLayoutDataProposal(
					metaclass, layoutData, offset, replacementLength);
			if (proposal != null) {
				if (useProposalList) {
					proposalCollector.add(proposal);
				} else {
					macrosCollector.add(proposal);
				}
			}
		}
		if (metaclass != null) {
			if (containControls
					|| Composite.class.isAssignableFrom(metaclass.getType())) {
				IMetaclass[] metaclasses = XWT.getAllMetaclasses();
				for (IMetaclass type : metaclasses) {
					if (Control.class.isAssignableFrom(type.getType())
							&& !type.isAbstract()) {

						String typeName = type.getName();
						if (prefixed != null
								&& !typeName.toLowerCase().startsWith(prefixed)) {
							continue;
						}
						if (addedTags.contains(typeName)) {
							continue;
						} else {
							addedTags.add(typeName);
						}
						String pattern = "<" + typeName + "></" + typeName
								+ ">";
						Image image = ImageManager
								.get(ImageManager.IMG_ELEMENT);
						SelectionCompletionProposal proposal = new SelectionCompletionProposal(
								pattern, offset, replacementLength,
								typeName.length() + 2, 0, image, typeName,
								null, null);
						if (useProposalList) {
							proposalCollector.add(proposal);
						} else {
							macrosCollector.add(proposal);
						}
					}
				}
			}
		}

		Collections.sort(proposalCollector, comparator);
		Collections.sort(macrosCollector, comparator);

		for (ICompletionProposal proposal : proposalCollector) {
			contentAssistRequest.addProposal(proposal);
		}

		for (ICompletionProposal proposal : macrosCollector) {
			contentAssistRequest.addMacro(proposal);
		}
	}

	private List<SelectionCompletionProposal> createPropertyNodeProposals(
			String tagName, int offset, int replacementLength) {
		int index = tagName.indexOf(".");
		if (index == -1) {
			return Collections.emptyList();
		}
		List<SelectionCompletionProposal> proposals = new ArrayList<SelectionCompletionProposal>();
		String property = tagName.substring(index + 1);
		if ("layout".equalsIgnoreCase(property)) {
			String[] layouts = new String[] { "GridLayout", "FillLayout",
					"RowLayout", "StackLayout", "FormLayout" };
			for (int i = 0; i < layouts.length; i++) {
				String pattern = "<" + layouts[i] + "/>";
				Image image = ImageManager.get(ImageManager.IMG_ELEMENT);
				SelectionCompletionProposal p = new SelectionCompletionProposal(
						pattern, offset, replacementLength,
						layouts[i].length() + 2, 0, image, layouts[i], null,
						"Container Layout.");
				proposals.add(p);
			}
		} else if ("layoutData".equalsIgnoreCase(property)) {
			String[] layoutDatas = new String[] { "GridData", "StackData",
					"FormData", "RowData" };
			for (int i = 0; i < layoutDatas.length; i++) {
				String pattern = "<" + layoutDatas[i] + "></" + layoutDatas[i]
						+ ">";
				Image image = ImageManager.get(ImageManager.IMG_ELEMENT);
				SelectionCompletionProposal p = new SelectionCompletionProposal(
						pattern, offset, replacementLength,
						layoutDatas[i].length() + 2, 0, image, layoutDatas[i],
						null, "Container LayoutData.");
				proposals.add(p);
			}
		}
		return proposals;
	}

	private SelectionCompletionProposal createLayoutDataProposal(
			IMetaclass metaclass, String layoutData, int offset,
			int replacementLength) {
		if (!Control.class.isAssignableFrom(metaclass.getType())) {
			return null;
		}
		String pattern = "<" + layoutData + "></" + layoutData + ">";
		Image image = JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC);
		return new SelectionCompletionProposal(pattern, offset,
				replacementLength, layoutData.length() + 2, 0, image,
				layoutData, null, "Control LayoutData.");
	}

	private SelectionCompletionProposal createLayoutProposal(
			IMetaclass metaclass, String tagName, int offset,
			int replacementLength) {
		if (!Composite.class.isAssignableFrom(metaclass.getType())) {
			return null;
		}
		String pattern = "<" + tagName + "></" + tagName + ">";
		Image image = JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC);
		return new SelectionCompletionProposal(pattern, offset,
				replacementLength, tagName.length() + 2, 0, image, tagName,
				null, "Container Layout.");
	}

	private String getNodeName(Node node) {
		String name = node.getNodeName();
		int index = name.indexOf(":");
		if (index != -1) {
			name = name.substring(index + 1);
		}
		return name;
	}

	/**
	 * Adds templates to the list of proposals
	 * 
	 * @param contentAssistRequest
	 * @param context
	 */
	private void addTemplates(ContentAssistRequest contentAssistRequest,
			String context) {
		addTemplates(contentAssistRequest, context,
				contentAssistRequest.getReplacementBeginPosition());
	}

	/**
	 * Adds templates to the list of proposals
	 * 
	 * @param contentAssistRequest
	 * @param context
	 * @param startOffset
	 */
	private void addTemplates(ContentAssistRequest contentAssistRequest,
			String context, int startOffset) {
		if (contentAssistRequest == null) {
			return;
		}

		// if already adding template proposals for a certain context type, do
		// not add again
		if (!fTemplateContexts.contains(context)) {
			fTemplateContexts.add(context);
			boolean useProposalList = !contentAssistRequest.shouldSeparate();

			if (getTemplateCompletionProcessor() != null) {
				getTemplateCompletionProcessor().setContextType(context);
				ICompletionProposal[] proposals = getTemplateCompletionProcessor()
						.computeCompletionProposals(fTextViewer, startOffset);
				for (int i = 0; i < proposals.length; ++i) {
					if (useProposalList) {
						contentAssistRequest.addProposal(proposals[i]);
					} else {
						contentAssistRequest.addMacro(proposals[i]);
					}
				}
			}
		}
	}

	@Override
	protected ContentAssistRequest computeCompletionProposals(
			int documentPosition, String matchString,
			ITextRegion completionRegion, IDOMNode treeNode, IDOMNode xmlnode) {
		ContentAssistRequest request = super.computeCompletionProposals(
				documentPosition, matchString, completionRegion, treeNode,
				xmlnode);
		// bug115927 use original document position for all/any region
		// templates
		addTemplates(request, TemplateContextTypeIdsXML.ALL, documentPosition);
		return request;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.xml.ui.contentassist.AbstractContentAssistProcessor#
	 * computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
	 */
	@Override
	public ICompletionProposal[] computeCompletionProposals(
			ITextViewer textViewer, int documentPosition) {
		fTemplateContexts.clear();
		return super.computeCompletionProposals(textViewer, documentPosition);
	}

	protected IPreferenceStore getPreferenceStore() {
		if (fPreferenceStore == null) {
			fPreferenceStore = XMLUIPlugin.getDefault().getPreferenceStore();
		}
		return fPreferenceStore;
	}

	protected VEXTemplateCompletionProcessor getTemplateCompletionProcessor() {
		if (fTemplateProcessor == null) {
			fTemplateProcessor = new VEXTemplateCompletionProcessor();
		}
		return fTemplateProcessor;
	}

	@Override
	protected void init() {
		getPreferenceStore().addPropertyChangeListener(this);
		reinit();
	}

	public void propertyChange(PropertyChangeEvent event) {
		String property = event.getProperty();

		if ((property.compareTo(XMLUIPreferenceNames.AUTO_PROPOSE) == 0)
				|| (property.compareTo(XMLUIPreferenceNames.AUTO_PROPOSE_CODE) == 0)) {
			reinit();
		}
	}

	protected void reinit() {
		String key = XMLUIPreferenceNames.AUTO_PROPOSE;
		boolean doAuto = getPreferenceStore().getBoolean(key);
		if (doAuto) {
			key = XMLUIPreferenceNames.AUTO_PROPOSE_CODE;
			completionProposalAutoActivationCharacters = getPreferenceStore()
					.getString(key).toCharArray();
		} else {
			completionProposalAutoActivationCharacters = null;
		}
	}

	@Override
	public void release() {
		super.release();
		getPreferenceStore().removePropertyChangeListener(this);
	}

	private List<String> getJavaMethods(JavaProject javaProject,
			String className) {
		List<String> javaMethods = new ArrayList<String>();
		try {
			IType type = javaProject.findType(className);
			IMethod[] methods = type.getMethods();
			for (int i = 0; i < methods.length; i++) {
				IMethod method = methods[i];
				String methodName = method.getElementName();
				javaMethods.add(methodName);
			}
		} catch (JavaModelException e) {
			e.printStackTrace();
		}
		return javaMethods;
	}
}