/*******************************************************************************
 * Copyright (c) 2004 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 com.ibm.icu.text.Collator;
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;

/**
 * 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$
				while (fTableViewer.getColumnData()[0].keySet().contains(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);
		sourceViewer.setDocument(new Document(fItem.getContentString()));
		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() {
		fItem.setContentString(content.getText());
		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);
		}
	}
}