/*******************************************************************************
 * Copyright (c) 2004, 2008 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 Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.snippets.internal.editors;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.common.snippets.core.ISnippetItem;
import org.eclipse.wst.common.snippets.core.ISnippetVariable;
import org.eclipse.wst.common.snippets.internal.IHelpContextIds;
import org.eclipse.wst.common.snippets.internal.Logger;
import org.eclipse.wst.common.snippets.internal.SnippetsMessages;
import org.eclipse.wst.common.snippets.internal.palette.SnippetPaletteItem;
import org.eclipse.wst.common.snippets.internal.palette.SnippetVariable;
import org.eclipse.wst.common.snippets.internal.ui.StringPropertyTableViewer;
import org.eclipse.wst.common.snippets.internal.ui.ValueChangedListener;
import org.eclipse.wst.common.snippets.internal.util.Sorter;
import org.eclipse.wst.common.snippets.internal.util.StringUtils;

import com.ibm.icu.text.Collator;

/**
 * A snippet item editor that can define snippet variables
 */
public class VariableItemEditor implements ISnippetEditor {
	private static class CompletionProposalSorter extends Sorter {
		Collator collator = Collator.getInstance();

		public boolean compare(Object elementOne, Object elementTwo) {
			/**
			 * Returns true if elementTwo is 'greater than' elementOne This is
			 * the 'ordering' method of the sort operation. Each subclass
			 * overides this method with the particular implementation of the
			 * 'greater than' concept for the objects being sorted.
			 */
			ICompletionProposal proposal1 = (ICompletionProposal) elementOne;
			ICompletionProposal proposal2 = (ICompletionProposal) elementTwo;
			return (collator.compare(proposal1.getDisplayString(), proposal2.getDisplayString())) < 0;
		}
	}

	private class ItemEditorSourceViewerConfiguration extends SourceViewerConfiguration {
		private IContentAssistProcessor fProcessor = null;

		public ItemEditorSourceViewerConfiguration() {
			super();
			fProcessor = new IContentAssistProcessor() {
				char[] autochars = new char[]{};

				public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
					java.util.List vars = new ArrayList();
					final ITextViewer textViewer = viewer;
					Iterator keys = fTableViewer.getColumnData()[0].keySet().iterator();
					while (keys.hasNext()) {
						Object key = keys.next();
						final String varID = (String) fTableViewer.getColumnData()[0].get(key);
						if (varID != null) {
							ICompletionProposal p = new ICompletionProposal() {
								protected int fReplacementOffset = textViewer.getSelectedRange().x;
								protected String varname = varID;

								public void apply(IDocument document) {
									try {
										document.replace(textViewer.getSelectedRange().x, 0, "${" + getDisplayString() + "}"); //$NON-NLS-1$ //$NON-NLS-2$
									}
									catch (BadLocationException e) {
										Logger.logException(e);
									}
								}

								public String getAdditionalProposalInfo() {
									return null;
								}

								public IContextInformation getContextInformation() {
									return null;
								}

								public String getDisplayString() {
									String display = varname;
									if (display == null)
										display = ""; //$NON-NLS-1$
									return display;
								}

								public Image getImage() {
									return null;
								}

								public Point getSelection(IDocument document) {
									return new Point(fReplacementOffset + 3 + getDisplayString().length(), 0);
								}
							};
							vars.add(p);
						}
					}
					ICompletionProposal[] proposals = new ICompletionProposal[vars.size()];
					vars.toArray(proposals);
					return sortProposals(proposals);
				}

				public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
					return null;
				}

				public char[] getCompletionProposalAutoActivationCharacters() {
					return autochars;
				}

				public char[] getContextInformationAutoActivationCharacters() {
					return null;
				}

				public IContextInformationValidator getContextInformationValidator() {
					return null;
				}

				public String getErrorMessage() {
					return null;
				}

				public ICompletionProposal[] sortProposals(ICompletionProposal[] proposals) {
					if (proposals == null || proposals.length == 0)
						return proposals;
					Object sortedProposals[] = new CompletionProposalSorter().sort(proposals);
					List sortedList = new ArrayList();
					for (int i = 0; i < sortedProposals.length; i++)
						sortedList.add(sortedProposals[i]);
					ICompletionProposal[] results = new ICompletionProposal[sortedProposals.length];
					sortedList.toArray(results);
					return results;
				}
			};
		}

		/*
		 * @see SourceViewerConfiguration#getContentAssistant(ISourceViewer)
		 */
		public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
			ContentAssistant assistant = new ContentAssistant();
			assistant.setContentAssistProcessor(fProcessor, IDocument.DEFAULT_CONTENT_TYPE);

			assistant.enableAutoActivation(false);
			assistant.setAutoActivationDelay(500);
			assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
			assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);

			// Color background= something;
			// assistant.setContextInformationPopupBackground(background);
			// assistant.setContextSelectorBackground(background);
			// assistant.setProposalSelectorBackground(background);

			return assistant;
		}
	}

	protected StyledText content = null;
	protected SnippetPaletteItem fItem = null;
	protected StringPropertyTableViewer fTableViewer = null;
	private ModifyListener modifyListener = null;

	protected java.util.List modifyListeners = null;

	public VariableItemEditor() {
		super();
	}

	public void addModifyListener(ModifyListener listener) {
		getListeners().add(listener);
	}

	public Control createContents(Composite parent) {
		// create the contents of the variable editing dialog

		// the container for the variables fTableViewer and new/remove buttons
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IHelpContextIds.DIALOG_EDIT_VARITEM);

		Composite variableComposite = new Composite(parent, SWT.NONE);
		variableComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		((GridData) variableComposite.getLayoutData()).widthHint = parent.getDisplay().getClientArea().width / 3;
		GridLayout sublayout = new GridLayout();
		sublayout.numColumns = 2;
		sublayout.marginWidth = 0;
		sublayout.makeColumnsEqualWidth = false;
		variableComposite.setLayout(sublayout);

		Label nameLabel = new Label(variableComposite, SWT.NONE);
		nameLabel.setText(SnippetsMessages.Variables__4); //$NON-NLS-1$
		GridData doubleData = new GridData(GridData.FILL_HORIZONTAL);
		nameLabel.setLayoutData(doubleData);

		Label throwAway = new Label(variableComposite, SWT.NONE);
		throwAway.setLayoutData(new GridData());

		// saved and made final here to update the template text area below
		final String nameProperty = SnippetsMessages.Name_5; //$NON-NLS-1$
		fTableViewer = new StringPropertyTableViewer();
		fTableViewer.setColumnNames(new String[]{nameProperty, SnippetsMessages.Description_6, SnippetsMessages.Default_Value_7}); //$NON-NLS-1$ //$NON-NLS-2$
		fTableViewer.createContents(variableComposite);

		GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
		data.heightHint = fTableViewer.getTable().getItemHeight() * 6;
		fTableViewer.getControl().setLayoutData(data);

		// For now, each column gets its data from a separate hashtable. In
		// each,
		// the key is the ID of the variable with the values being the name,
		// description, and default value.
		ISnippetVariable[] variables = fItem.getVariables();
		for (int i = 0; i < variables.length; i++) {
			SnippetVariable var = (SnippetVariable) variables[i];
			fTableViewer.getColumnData()[0].put(var.getId(), var.getName());
			if (var.getDescription() != null)
				fTableViewer.getColumnData()[1].put(var.getId(), var.getDescription());
			else
				fTableViewer.getColumnData()[1].put(var.getId(), ""); //$NON-NLS-1$
			if (var.getDefaultValue() != null)
				fTableViewer.getColumnData()[2].put(var.getId(), var.getDefaultValue());
			else
				fTableViewer.getColumnData()[2].put(var.getId(), ""); //$NON-NLS-1$
		}
		fTableViewer.refresh();

		Composite variableButtons = new Composite(variableComposite, SWT.NULL);
		variableButtons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_END));
		variableButtons.setLayout(new GridLayout());

		// Add the New button with a listener to add a new variable without
		// user
		// input.
		// TODO: for usability, throw up a dialog in the middle
		Button addButton = new Button(variableButtons, SWT.PUSH);
		addButton.setText(SnippetsMessages.New_1); //$NON-NLS-1$
		addButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		addButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}

			public void widgetSelected(SelectionEvent e) {
				int i = 1;
				String newId = "name_" + i; //$NON-NLS-1$
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=183699 - check both ID and visible name
				while (fTableViewer.getColumnData()[0].containsKey(newId)||fTableViewer.getColumnData()[0].containsValue(newId)) {
					newId = "name_" + i++; //$NON-NLS-1$
				}
				fTableViewer.getColumnData()[0].put(newId, newId);
				fTableViewer.getColumnData()[1].put(newId, ""); //$NON-NLS-1$
				fTableViewer.getColumnData()[2].put(newId, ""); //$NON-NLS-1$
				fTableViewer.refresh();
			}
		});
		// add the Remove button with a listener to enable it only when a
		// cell is selected and in focus
		final Button removeButton = new Button(variableButtons, SWT.PUSH);
		removeButton.setText(SnippetsMessages.Remove_15); //$NON-NLS-1$
		removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		nameLabel = new Label(parent, SWT.NONE);
		nameLabel.setText(SnippetsMessages.Template_Pattern__16); //$NON-NLS-1$
		nameLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// create a source viewer for to edit the text (makes it easier to
		// hook into content assist)
		final SourceViewer sourceViewer = new SourceViewer(parent, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
		sourceViewer.setEditable(true);
		
		// Update EOLs bug 80231
		String systemEOL = System.getProperty("line.separator"); //$NON-NLS-1$
		String text = StringUtils.replace(fItem.getContentString(), "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
		text = StringUtils.replace(text, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
		if (!"\n".equals(systemEOL) && systemEOL != null) { //$NON-NLS-1$
			text = StringUtils.replace(text, "\n", systemEOL); //$NON-NLS-1$
		}
		sourceViewer.setDocument(new Document(text));
		
		final SourceViewerConfiguration sourceViewerConfiguration = new ItemEditorSourceViewerConfiguration();
		sourceViewer.configure(sourceViewerConfiguration);
		content = sourceViewer.getTextWidget();
		content.addModifyListener(getModifyListener());

		// add a listener to the Remove button to remove the variable
		// corresponding to the selected row
		removeButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}

			public void widgetSelected(SelectionEvent e) {
				Object id = fTableViewer.getSelection();
				if (id == null)
					return;
				// remove from template as well
				Object varKey = fTableViewer.getColumnData()[0].get(id);
				String template = sourceViewer.getDocument().get();
				sourceViewer.getDocument().set(StringUtils.replace(template, "${" + varKey + "}", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				fTableViewer.getColumnData()[0].remove(id);
				fTableViewer.getColumnData()[1].remove(id);
				fTableViewer.getColumnData()[2].remove(id);

				// #222898, clear selection so that SWT errors are avoided
				fTableViewer.getTable().setSelection(new int[0]);

				fTableViewer.refresh();
				removeButton.setEnabled(false);
			}
		});

		GridData contentData = new GridData(GridData.FILL_BOTH);
		contentData.heightHint = parent.getDisplay().getClientArea().height / 5;
		content.setLayoutData(contentData);
		content.setFont(org.eclipse.jface.resource.JFaceResources.getTextFont());
		content.setHorizontalPixel(2);
		// add a verify key listener to trigger the source viewer's undo
		// action
		content.addVerifyKeyListener(new VerifyKeyListener() {
			public void verifyKey(VerifyEvent event) {
				if (!event.doit)
					return;
				boolean doContentAssistOperation = (event.stateMask == SWT.CTRL && event.character == ' ');
				if (doContentAssistOperation) {
					sourceViewer.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
					event.doit = false;
				}
				// CTRL-Z (derived from the JDT template editor's way of
				// assigning the event.character)
				else if (event.stateMask == SWT.CTRL && (event.character == ('z' - 'a' + 1))) {
					sourceViewer.doOperation(ITextOperationTarget.UNDO);
					event.doit = false;
				}
			}
		});
		// add a verify listener to trigger the source viewer's content assist
		// and undo actions
		// TODO: determine if this is duplicated effort
		content.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent event) {
				if (!event.doit || !((event.stateMask & SWT.CTRL) == 1))
					return;
				boolean doContentAssistOperation = (event.stateMask == SWT.CTRL && event.character == ' ');
				// prevent inserting a space character when content assist is
				// invoked
				if (doContentAssistOperation) {
					event.doit = false;
				}
				// CTRL-Z
				else if (event.stateMask == SWT.CTRL && event.character == ('z' - 'a' + 1)) {
					event.doit = false;
				}
			}
		});

		// specifically associate the template pattern label w/ the content
		// styled text so screen reader reads it
		setAccessible(content, SnippetsMessages.Template_Pattern__16); //$NON-NLS-1$

		// add a value change listener to the fTableViewer so that changes to
		// the name property of a variable
		// will rewrite the template text to use the new name immediately
		// TODO: verify with the user that this is OK with them
		fTableViewer.addValueChangedListener(new ValueChangedListener() {
			public void valueChanged(String key, String property, String oldValue, String newValue) {
				if (property.equals(nameProperty)) {
					String newText = StringUtils.replace(content.getText(), "${" + oldValue + "}", "${" + newValue + "}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
					content.setText(newText);
				}
			}
		});

		/*
		 * Add the "Insert Variable Placeholder" button to invoke content
		 * assist like the JDT Template editor.
		 * 
		 * I'm not sure I like this idea as it's mostly a crutch for not
		 * making content assist obviously available in the source viewer.
		 */
		final Button insertVariableButton = new Button(parent, SWT.PUSH);
		insertVariableButton.setText(SnippetsMessages.Insert_Variable_17); //$NON-NLS-1$
		insertVariableButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING));
		insertVariableButton.setEnabled(fTableViewer.getTable().getItemCount() > 0);
		insertVariableButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}

			public void widgetSelected(SelectionEvent e) {
				// JDT template editor invokes Content Assist on a
				// configured Java Source Viewer. Not that simple here.
				sourceViewer.getTextWidget().setFocus();
				sourceViewer.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
			}
		});

		fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				insertVariableButton.setEnabled(fTableViewer.getTable().getItemCount() > 0);
				removeButton.setEnabled(fTableViewer.getControl().isFocusControl() && event.getSelection() != null && (!event.getSelection().isEmpty()));
			}
		});

		addButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				insertVariableButton.setEnabled(true);
			}
		});
		removeButton.addSelectionListener(new SelectionAdapter() {
			public void widgetDefaultSelected(SelectionEvent e) {
				insertVariableButton.setEnabled(fTableViewer.getTable().getItemCount() > 0);
			}

			public void widgetSelected(SelectionEvent e) {
				insertVariableButton.setEnabled(fTableViewer.getTable().getItemCount() > 0);
			}
		});
		// set the initial enabled state
		removeButton.setEnabled(false);

		return parent;
	}

	protected void fireModification(ModifyEvent e) {
		Iterator i = getListeners().iterator();
		updateItem();
		while (i.hasNext())
			((ModifyListener) (i.next())).modifyText(e);
	}

	public ISnippetItem getItem() {
		return fItem;
	}

	private java.util.List getListeners() {
		if (modifyListeners == null)
			modifyListeners = new ArrayList();
		return modifyListeners;
	}

	protected ModifyListener getModifyListener() {
		if (modifyListener == null) {
			modifyListener = new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					fireModification(e);
				}
			};
		}
		return modifyListener;
	}

	public void removeModifyListener(ModifyListener listener) {
		getListeners().remove(listener);
	}

	/**
	 * Specifically set the reporting name of a control for accessibility
	 */
	private void setAccessible(Control control, String name) {
		if (control == null)
			return;
		final String n = name;
		control.getAccessible().addAccessibleListener(new AccessibleAdapter() {
			public void getName(AccessibleEvent e) {
				if (e.childID == ACC.CHILDID_SELF)
					e.result = n;
			}
		});
	}

	public void setItem(SnippetPaletteItem item) {
		fItem = item;
	}

	public void updateItem() {
		String text = content.getText();
		// Update related to bug 80231
		text = StringUtils.replace(text, "\r\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
		text = StringUtils.replace(text, "\r", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
		fItem.setContentString(text);
		
		ISnippetVariable[] variables = fItem.getVariables();
		for (int i = 0; i < variables.length; i++) {
			fItem.removeVariable(variables[i]);
		}
		Iterator ids = fTableViewer.getColumnData()[0].keySet().iterator();
		while (ids.hasNext()) {
			Object key = ids.next();
			SnippetVariable var = new SnippetVariable();
			var.setId((String) key);
			var.setName((String) fTableViewer.getColumnData()[0].get(key));
			var.setDescription((String) fTableViewer.getColumnData()[1].get(key));
			var.setDefaultValue((String) fTableViewer.getColumnData()[2].get(key));
			fItem.addVariable(var);
		}
	}
}
