/*******************************************************************************
 * 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;

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

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.JFaceResources;
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.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.common.snippets.core.ISnippetItem;
import org.eclipse.wst.common.snippets.core.ISnippetVariable;
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.StringUtils;

public class VariableInsertionDialog extends Dialog {
	private List disposeListeners = new ArrayList();
	protected StyledText fDescriptionPane = null;
	protected ISnippetItem fItem = null;


	protected String fPreparedText = null;
	protected StyledText fPreviewPane = null;

	protected StringPropertyTableViewer fTableViewer = null;

	/**
	 * Constructor for VariableInsertionDialog.
	 * 
	 * @param parentShell
	 */
	public VariableInsertionDialog(Shell parentShell, boolean clearModality) {
		super(parentShell);
		/**
		 * Required to fix defect 218700, since Dialogs default to
		 * APPLICATION_MODAL.
		 */
		if (clearModality)
			setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MODELESS);
		else
			setShellStyle(SWT.RESIZE | getShellStyle());
	}

	/**
	 * subclasses can override this to add more contents into the dialog
	 */
	protected void addContents(Composite composite) {
		//
	}

	public void addDisposeListener(DisposeListener listener) {
		if (!disposeListeners.contains(listener))
			disposeListeners.add(listener);
	}

	/**
	 * @see org.eclipse.jface.window.Window#create()
	 */
	public void create() {
		super.create();
		for (int i = 0; i < disposeListeners.size(); i++) {
			getShell().addDisposeListener((DisposeListener) disposeListeners.get(i));
		}
		getShell().setActive();
	}

	/**
	 * @see Dialog#createButtonsForButtonBar(Composite)
	 */
	protected void createButtonsForButtonBar(Composite parent) {
		super.createButtonsForButtonBar(parent);
		getButton(IDialogConstants.OK_ID).setText(SnippetsMessages.Insert_14); //$NON-NLS-1$
	}

	/*
	 * @see Dialog#createDialogArea(Composite)
	 */
	protected Control createDialogArea(Composite parent) {
		parent.getShell().setText(getDialogTitle());
		SnippetsPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(parent, IHelpContextIds.DIALOG_INSERT_VARITEM);

		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.makeColumnsEqualWidth = true;
		layout.horizontalSpacing += 2;
		layout.verticalSpacing += 2;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		composite.setFont(parent.getFont());

		GridData doubleWide = new GridData(GridData.FILL_BOTH);
		doubleWide.horizontalSpan = 2;
		Text instructions = new Text(composite, SWT.WRAP | SWT.LEFT);
		instructions.setBackground(composite.getBackground());
		doubleWide.heightHint = instructions.getFont().getFontData()[0].getHeight() * 3;
		instructions.setLayoutData(doubleWide);
		instructions.setText(SnippetsMessages.Edit_Instruction); //$NON-NLS-1$
		instructions.setEditable(false);

		Text tableLabel = new Text(composite, SWT.NONE);
		tableLabel.setBackground(composite.getBackground());
		tableLabel.setText(SnippetsMessages.Variables__4); //$NON-NLS-1$
		tableLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		tableLabel.setEditable(false);

		Text descriptionBoxLabel = new Text(composite, SWT.NONE);
		descriptionBoxLabel.setBackground(composite.getBackground());
		descriptionBoxLabel.setText(SnippetsMessages.Description_of_variable__5); //$NON-NLS-1$
		descriptionBoxLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		descriptionBoxLabel.setEditable(false);

		// pity we can't just use a PropertySheetPage, but the column headers
		// aren't customizable
		fTableViewer = new StringPropertyTableViewer();
		fTableViewer.setColumnNames(new String[]{SnippetsMessages.Variable_Name_6, SnippetsMessages.Value_7}); //$NON-NLS-1$ //$NON-NLS-2$
		fTableViewer.setEditFirstColumn(false);
		fTableViewer.createContents(composite);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.heightHint = fTableViewer.getTable().getItemHeight() * 5;
		fTableViewer.getControl().setLayoutData(data);
		fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				ISnippetVariable variable = null;
				if (fTableViewer.getSelection() != null) {
					variable = getVariable(fTableViewer.getSelection());
				}
				fDescriptionPane.setText(variable != null ? variable.getDescription() : ""); //$NON-NLS-1$
				fDescriptionPane.setHorizontalPixel(2);
				fDescriptionPane.redraw();
			}
		});
		fTableViewer.addValueChangedListener(new ValueChangedListener() {
			public void valueChanged(String key, String property, String oldValue, String newValue) {
				update();
			}
		});

		fDescriptionPane = new StyledText(composite, SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP);
		fDescriptionPane.setLayoutData(new GridData(GridData.FILL_BOTH));
		fDescriptionPane.setEnabled(true);
		fDescriptionPane.setEditable(false);
		fDescriptionPane.addVerifyKeyListener(createVerifyListener(fDescriptionPane));
		fDescriptionPane.setFont(JFaceResources.getDialogFont());
		setAccessible(fDescriptionPane, SnippetsMessages.Description_of_variable__5); //$NON-NLS-1$

		doubleWide = new GridData(GridData.FILL_BOTH);
		doubleWide.horizontalSpan = 2;
		Text previewLabel = new Text(composite, SWT.NULL);
		previewLabel.setBackground(composite.getBackground());
		previewLabel.setText(SnippetsMessages.Preview__9); //$NON-NLS-1$
		previewLabel.setEditable(false);

		doubleWide = new GridData(GridData.FILL_BOTH);
		doubleWide.horizontalSpan = 2;
		doubleWide.heightHint = parent.getDisplay().getClientArea().height / 6;
		doubleWide.widthHint = parent.getDisplay().getClientArea().width / 8;
		fPreviewPane = new StyledText(composite, SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		fPreviewPane.addVerifyKeyListener(createVerifyListener(fPreviewPane));
		fPreviewPane.addLineStyleListener(new LineStyleListener() {
			public void lineGetStyle(LineStyleEvent event) {
				// System.out.println("hilight: " + event.lineOffset);
			}
		});
		fPreviewPane.setEnabled(true);
		fPreviewPane.setEditable(false);
		fPreviewPane.setFont(JFaceResources.getTextFont());
		fPreviewPane.setLayoutData(doubleWide);
		setAccessible(fPreviewPane, SnippetsMessages.Preview__9); //$NON-NLS-1$

		if (fItem != null) {
			fTableViewer.clear();
			populateTableViewer();
			fTableViewer.refresh();
		}

		addContents(composite);

		update();
		fTableViewer.getControl().setFocus();
		return composite;
	}

	private VerifyKeyListener createVerifyListener(Control control) {
		final Control widget = control;
		return new VerifyKeyListener() {
			public void verifyKey(VerifyEvent event) {
				if (event.character == '\t') {
					if ((event.stateMask & SWT.SHIFT) != 0)
						widget.traverse(SWT.TRAVERSE_TAB_PREVIOUS);
					else
						widget.traverse(SWT.TRAVERSE_TAB_NEXT);
				}
			}
		};
	}

	/**
	 * Returns the dialog title to use
	 * 
	 * @return
	 */
	protected String getDialogTitle() {
		String shellLabel = ""; //$NON-NLS-1$
		String itemLabel = getItem().getLabel();
		if (itemLabel != null && itemLabel.length() > 0)
			shellLabel = SnippetsMessages.Insert_Template___1 + " " + itemLabel; //$NON-NLS-1$ //$NON-NLS-2$
		else
			shellLabel = SnippetsMessages.Insert_Template_2; //$NON-NLS-1$

		return shellLabel;
	}

	/**
	 * Gets the item.
	 * 
	 * @return Returns a ISnippetItem
	 */
	public ISnippetItem getItem() {
		return fItem;
	}

	/**
	 * Gets the preparedText.
	 * 
	 * @return Returns a String
	 */
	public String getPreparedText() {
		if (fPreparedText == null)
			prepareText();
		return fPreparedText;
	}

	protected ISnippetVariable getVariable(String id) {
		if (fItem == null)
			return null;
		ISnippetVariable[] variables = fItem.getVariables();
		for (int i = 0; i < variables.length; i++) {
			if (((SnippetVariable) variables[i]).getId().equals(id))
				return variables[i];
		}
		return null;
	}

	/*
	 * @see Dialog#okPressed()
	 */
	protected void okPressed() {
		fTableViewer.finishEditing();
		super.okPressed();
		prepareText();
	}

	protected void populateTableViewer() {
		ISnippetVariable[] variables = fItem.getVariables();
		for (int i = 0; i < variables.length; i++) {
			fTableViewer.getColumnData()[0].put(((SnippetVariable) variables[i]).getId(), ((SnippetVariable) variables[i]).getName());
			fTableViewer.getColumnData()[1].put(((SnippetVariable) variables[i]).getId(), ((SnippetVariable) variables[i]).getDefaultValue());
		}
	}

	protected void prepareText() {
		// this is horribly inefficient
		String text = fItem.getContentString();
		ISnippetVariable[] variables = fItem.getVariables();
		for (int i = 0; i < variables.length; i++) {
			String value = (String) fTableViewer.getColumnData()[1].get(((SnippetVariable) variables[i]).getId());
			text = StringUtils.replace(text, "${" + variables[i].getName() + "}", value); //$NON-NLS-1$ //$NON-NLS-2$
		}

		// remove all cursor markers
		text = StringUtils.replace(text, "${cursor}", ""); //$NON-NLS-1$ //$NON-NLS-2$

		setPreparedText(text);
	}

	public void removeDisposeListener(DisposeListener listener) {
		disposeListeners.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;
			}
		});
	}

	/**
	 * Sets the item.
	 * 
	 * @param item
	 *            The item to set
	 */
	public void setItem(ISnippetItem item) {
		fItem = item;
		if (fTableViewer != null) {
			fTableViewer.clear();
			populateTableViewer();
		}
	}

	/**
	 * Sets the preparedText.
	 * 
	 * @param preparedText
	 *            The preparedText to set
	 */
	protected void setPreparedText(String preparedText) {
		fPreparedText = preparedText;
	}

	protected void update() {
		prepareText();
		if (fPreviewPane != null && !fPreviewPane.isDisposed()) {
			fPreviewPane.setText(getPreparedText());
			fPreviewPane.setHorizontalPixel(2);
			fPreviewPane.redraw();
		}
	}
}