/*******************************************************************************
 * Copyright (c) 2004, 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 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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);
		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;
		fTableViewer = new StringPropertyTableViewer();
		fTableViewer.setColumnNames(new String[]{nameProperty, SnippetsMessages.Description_6, SnippetsMessages.Default_Value_7});
		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);
		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);
		removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		nameLabel = new Label(parent, SWT.NONE);
		nameLabel.setText(SnippetsMessages.Template_Pattern__16);
		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);

		// 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);
		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);
		}
	}
}
