/*******************************************************************************
 * Copyright (c) 2000, 2015 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.jdt.internal.debug.ui.propertypages;

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

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.internal.debug.ui.ExceptionHandler;
import org.eclipse.jdt.internal.debug.ui.Filter;
import org.eclipse.jdt.internal.debug.ui.FilterLabelProvider;
import org.eclipse.jdt.internal.debug.ui.FilterViewerComparator;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.dialogs.SelectionDialog;


public class ExceptionFilterEditor {

	protected static final String DEFAULT_PACKAGE = "(default package)"; //$NON-NLS-1$
	private IJavaExceptionBreakpoint fBreakpoint;
	private Button fAddFilterButton;
	private Button fAddPackageButton;
	private Button fAddTypeButton;
	private Button fRemoveFilterButton;
	private Text fEditorText;
	private String fInvalidEditorText = null;
	private TableEditor fTableEditor;
	private TableItem fNewTableItem;
	private Filter fNewFilter;
	private CheckboxTableViewer fFilterViewer;
	private Table fFilterTable;
	private FilterContentProvider fFilterContentProvider;

	private SelectionListener fSelectionListener= new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent e) {
			Object source = e.getSource();
			if (source == fAddTypeButton) {
				addType();
			} else if (source == fAddPackageButton) {
				addPackage();
			} else if (source == fAddFilterButton) {
				editFilter();
			} else if (source == fRemoveFilterButton) {
				removeFilters();
			}
		}
	};

	public ExceptionFilterEditor(Composite parent, JavaExceptionBreakpointAdvancedPage page) {
		fBreakpoint = (IJavaExceptionBreakpoint) page.getBreakpoint();
		// top level container
		Composite outer = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight = 0;
		layout.marginWidth = 0;

		outer.setLayout(layout);
		GridData gd = new GridData(GridData.FILL_BOTH);
		outer.setLayoutData(gd);
		outer.setFont(parent.getFont());
		// filter table
		Label label= new Label(outer, SWT.NONE);
		label.setText(PropertyPageMessages.ExceptionFilterEditor_5);
		label.setFont(parent.getFont());
		gd= new GridData();
		gd.horizontalSpan= 2;
		label.setLayoutData(gd);

		fFilterTable = new Table(outer, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);

		TableLayout tableLayout = new TableLayout();
		ColumnLayoutData[] columnLayoutData = new ColumnLayoutData[1];
		columnLayoutData[0] = new ColumnWeightData(100);
		tableLayout.addColumnData(columnLayoutData[0]);
		fFilterTable.setLayout(tableLayout);
		fFilterTable.setFont(parent.getFont());
		new TableColumn(fFilterTable, SWT.NONE);

		fFilterViewer = new CheckboxTableViewer(fFilterTable);
		fTableEditor = new TableEditor(fFilterTable);
		fFilterViewer.setLabelProvider(new FilterLabelProvider());
		fFilterViewer.setComparator(new FilterViewerComparator());
		fFilterContentProvider = new FilterContentProvider(fFilterViewer);
		fFilterViewer.setContentProvider(fFilterContentProvider);
		// input just needs to be non-null
		fFilterViewer.setInput(this);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
		gd.widthHint = 100;
		gd.heightHint = 100;
		fFilterViewer.getTable().setLayoutData(gd);
		fFilterViewer.addCheckStateListener(new ICheckStateListener() {
			@Override
			public void checkStateChanged(CheckStateChangedEvent event) {
				Filter filter = (Filter) event.getElement();
				fFilterContentProvider.toggleFilter(filter);
			}
		});
		fFilterViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				ISelection selection = event.getSelection();
				if (selection.isEmpty()) {
					fRemoveFilterButton.setEnabled(false);
				} else {
					fRemoveFilterButton.setEnabled(true);
				}
			}
		});
		fFilterViewer.getTable().addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent event) {
				if (event.character == SWT.DEL && event.stateMask == 0) {
					removeFilters();
				}
			}
		});

		createFilterButtons(outer);
	}

	protected void doStore() {
		Object[] filters = fFilterContentProvider.getElements(null);
		List<String> inclusionFilters = new ArrayList<>(filters.length);
		List<String> exclusionFilters = new ArrayList<>(filters.length);
		for (int i = 0; i < filters.length; i++) {
			Filter filter = (Filter) filters[i];
			String name = filter.getName();
			if (name.equals(DEFAULT_PACKAGE)) {
				name = ""; //$NON-NLS-1$
			}
			if (filter.isChecked()) {
				inclusionFilters.add(name);
			} else {
				exclusionFilters.add(name);
			}
		}
		try {
			fBreakpoint.setInclusionFilters(inclusionFilters.toArray(new String[inclusionFilters.size()]));
			fBreakpoint.setExclusionFilters(exclusionFilters.toArray(new String[exclusionFilters.size()]));
		} catch (CoreException ce) {
			JDIDebugUIPlugin.log(ce);
		}

	}

	private void createFilterButtons(Composite container) {
		// button container
		Font font= container.getFont();
		Composite buttonContainer = new Composite(container, SWT.NONE);
		buttonContainer.setFont(font);
		GridData gd = new GridData(GridData.FILL_VERTICAL);
		buttonContainer.setLayoutData(gd);
		GridLayout buttonLayout = new GridLayout();
		buttonLayout.numColumns = 1;
		buttonLayout.marginHeight = 0;
		buttonLayout.marginWidth = 0;
		buttonContainer.setLayout(buttonLayout);

		fAddFilterButton = createPushButton(buttonContainer,
				PropertyPageMessages.ExceptionFilterEditor_6,
				PropertyPageMessages.ExceptionFilterEditor_7);
		fAddTypeButton = createPushButton(buttonContainer,
				PropertyPageMessages.ExceptionFilterEditor_8,
				PropertyPageMessages.ExceptionFilterEditor_9);
		fAddPackageButton = createPushButton(buttonContainer,
				PropertyPageMessages.ExceptionFilterEditor_10,
				PropertyPageMessages.ExceptionFilterEditor_11);
		fRemoveFilterButton = createPushButton(buttonContainer,
				PropertyPageMessages.ExceptionFilterEditor_12,
				PropertyPageMessages.ExceptionFilterEditor_13);
		fRemoveFilterButton.setEnabled(false);
	}

	/**
	 * Creates a fully configured push button with the given label and tooltip.
	 */
	private Button createPushButton(Composite parent, String text, String tooltipText) {
		Button button = new Button(parent, SWT.PUSH);
		button.setFont(parent.getFont());
		button.setText(text);
		button.setToolTipText(tooltipText);
		GridData gd = getButtonGridData(button);
		button.setLayoutData(gd);
		button.addSelectionListener(fSelectionListener);
		return button;
	}

	private static GridData getButtonGridData(Button button) {
		GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
		GC gc = new GC(button);
		gc.setFont(button.getFont());
		FontMetrics fontMetrics = gc.getFontMetrics();
		gc.dispose();
		int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_WIDTH);
		gd.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
		return gd;
	}

	/**
	 * Create a new filter in the table (with the default 'new filter' value),
	 * then open up an in-place editor on it.
	 */
	private void editFilter() {
		// if a previous edit is still in progress, finish it
		if (fEditorText != null) {
			validateChangeAndCleanup();
		}

		fNewFilter = fFilterContentProvider.addFilter(""); //$NON-NLS-1$
		fNewTableItem = fFilterTable.getItem(0);

		// create & configure Text widget for editor
		// Fix for bug 1766.  Border behavior on for text fields varies per platform.
		// On Motif, you always get a border, on other platforms,
		// you don't.  Specifying a border on Motif results in the characters
		// getting pushed down so that only there very tops are visible.  Thus,
		// we have to specify different style constants for the different platforms.
		int textStyles = SWT.SINGLE | SWT.LEFT;
		if (!SWT.getPlatform().equals("motif")) { //$NON-NLS-1$
			textStyles |= SWT.BORDER;
		}
		fEditorText = new Text(fFilterTable, textStyles);
		GridData gd = new GridData(GridData.FILL_BOTH);
		fEditorText.setLayoutData(gd);

		// set the editor
		fTableEditor.horizontalAlignment = SWT.LEFT;
		fTableEditor.grabHorizontal = true;
		fTableEditor.setEditor(fEditorText, fNewTableItem, 0);

		// get the editor ready to use
		fEditorText.setText(fNewFilter.getName());
		fEditorText.selectAll();
		setEditorListeners(fEditorText);
		fEditorText.setFocus();
	}

	private void setEditorListeners(Text text) {
		// CR means commit the changes, ESC means abort and don't commit
		text.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent event) {
				if (event.character == SWT.CR) {
					if (fInvalidEditorText != null) {
						fEditorText.setText(fInvalidEditorText);
						fInvalidEditorText = null;
					} else {
						validateChangeAndCleanup();
					}
				} else if (event.character == SWT.ESC) {
					removeNewFilter();
					cleanupEditor();
				}
			}
		});
		// Consider loss of focus on the editor to mean the same as CR
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent event) {
				if (fInvalidEditorText != null) {
					fEditorText.setText(fInvalidEditorText);
					fInvalidEditorText = null;
				} else {
					validateChangeAndCleanup();
				}
			}
		});
		// Consume traversal events from the text widget so that CR doesn't
		// traverse away to dialog's default button.  Without this, hitting
		// CR in the text field closes the entire dialog.
		text.addListener(SWT.Traverse, new Listener() {
			@Override
			public void handleEvent(Event event) {
				event.doit = false;
			}
		});
	}

	private void validateChangeAndCleanup() {
		String trimmedValue = fEditorText.getText().trim();
		// if the new value is blank, remove the filter
		if (trimmedValue.length() < 1) {
			removeNewFilter();
		}
		// if it's invalid, beep and leave sitting in the editor
		else if (!validateEditorInput(trimmedValue)) {
			fInvalidEditorText = trimmedValue;
			fEditorText.setText(PropertyPageMessages.ExceptionFilterEditor_14);
			return;
			// otherwise, commit the new value if not a duplicate
		} else {
			Object[] filters = fFilterContentProvider.getElements(null);
			for (int i = 0; i < filters.length; i++) {
				Filter filter = (Filter) filters[i];
				if (filter.getName().equals(trimmedValue)) {
					removeNewFilter();
					cleanupEditor();
					return;
				}
			}
			fNewTableItem.setText(trimmedValue);
			fNewFilter.setName(trimmedValue);
			fFilterViewer.refresh();
		}
		cleanupEditor();
	}

	/**
	 * A valid filter is simply one that is a valid Java identifier.
	 * and, as defined in the JDI spec, the regular expressions used for
	 * scoping must be limited to exact matches or patterns that
	 * begin with '*' or end with '*'. Beyond this, a string cannot be validated
	 * as corresponding to an existing type or package (and this is probably not
	 * even desirable).
	 */
	private boolean validateEditorInput(String trimmedValue) {
		char firstChar = trimmedValue.charAt(0);
		if (!Character.isJavaIdentifierStart(firstChar)) {
			if (!(firstChar == '*')) {
				return false;
			}
		}
		int length = trimmedValue.length();
		for (int i = 1; i < length; i++) {
			char c = trimmedValue.charAt(i);
			if (!Character.isJavaIdentifierPart(c)) {
				if (c == '.' && i != (length - 1)) {
					continue;
				}
				if (c == '*' && i == (length - 1)) {
					continue;
				}
				return false;
			}
		}
		return true;
	}

	/**
	 * Cleanup all widgetry & resources used by the in-place editing
	 */
	private void cleanupEditor() {
		if (fEditorText != null) {
			fNewFilter = null;
			fNewTableItem = null;
			fTableEditor.setEditor(null, null, 0);
			fEditorText.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					fEditorText.dispose();
					fEditorText = null;
				}
			});
		}
	}

	private void removeFilters() {
		IStructuredSelection selection = (IStructuredSelection) fFilterViewer.getSelection();
		fFilterContentProvider.removeFilters(selection.toArray());
	}

	private void removeNewFilter() {
		fFilterContentProvider.removeFilters(new Object[] { fNewFilter });
	}

	private void addPackage() {
		Shell shell = fAddPackageButton.getDisplay().getActiveShell();
		ElementListSelectionDialog dialog = null;
		try {
			dialog = JDIDebugUIPlugin.createAllPackagesDialog(shell, null, false);
		} catch (JavaModelException jme) {
			String title = PropertyPageMessages.ExceptionFilterEditor_15;
			String message = PropertyPageMessages.ExceptionFilterEditor_16;
			ExceptionHandler.handle(jme, title, message);
			return;
		}
		if (dialog == null) {
			return;
		}
		dialog.setTitle(PropertyPageMessages.ExceptionFilterEditor_15);
		dialog.setMessage(PropertyPageMessages.ExceptionFilterEditor_18);
		dialog.setMultipleSelection(true);
		if (dialog.open() == IDialogConstants.CANCEL_ID) {
			return;
		}
		Object[] packages = dialog.getResult();
		if (packages != null) {
			for (int i = 0; i < packages.length; i++) {
				IJavaElement pkg = (IJavaElement) packages[i];
				String filter = pkg.getElementName();
				if (filter.length() < 1) {
					filter = DEFAULT_PACKAGE;
				} else {
					filter += ".*"; //$NON-NLS-1$
				}
				Filter f = fFilterContentProvider.addFilter(filter);
				fFilterContentProvider.checkFilter(f, true);
			}
		}
	}

	private void addType() {
		Shell shell = fAddTypeButton.getDisplay().getActiveShell();
		SelectionDialog dialog = null;
		try {
			dialog = JavaUI.createTypeDialog(shell, PlatformUI.getWorkbench().getProgressService(), SearchEngine.createWorkspaceScope(), IJavaElementSearchConstants.CONSIDER_CLASSES, false);
		} catch (JavaModelException jme) {
			String title = PropertyPageMessages.ExceptionFilterEditor_19;
			String message = PropertyPageMessages.ExceptionFilterEditor_20;
			ExceptionHandler.handle(jme, title, message);
			return;
		}

		dialog.setTitle(PropertyPageMessages.ExceptionFilterEditor_19);
		dialog.setMessage(PropertyPageMessages.ExceptionFilterEditor_22);
		if (dialog.open() == IDialogConstants.CANCEL_ID) {
			return;
		}

		Object[] types = dialog.getResult();
		IType type;
		if (types != null) {
			for (int i = 0; i < types.length; i++) {
				type = (IType) types[i];
				Filter f = fFilterContentProvider.addFilter(type.getFullyQualifiedName());
				fFilterContentProvider.checkFilter(f, true);
			}
		}
	}

	/**
	 * Content provider for the table.  Content consists of instances of Filter.
	 */
	protected class FilterContentProvider implements IStructuredContentProvider {

		private CheckboxTableViewer fViewer;
		private List<Filter> fFilters;

		public FilterContentProvider(CheckboxTableViewer viewer) {
			fViewer = viewer;
			populateFilters();
		}

		protected void populateFilters() {
			String[] iFilters = null;
			String[] eFilters = null;
			try {
				iFilters = fBreakpoint.getInclusionFilters();
				eFilters = fBreakpoint.getExclusionFilters();
			} catch (CoreException ce) {
				JDIDebugUIPlugin.log(ce);
				iFilters = new String[] {
				};
				eFilters = new String[] {
				};
			}
			fFilters = new ArrayList<>();
			populateFilters(iFilters, true);
			populateFilters(eFilters, false);

		}

		protected void populateFilters(String[] filters, boolean checked) {
			for (int i = 0; i < filters.length; i++) {
				String name = filters[i];
				if (name.length() == 0) {
					name = DEFAULT_PACKAGE;
				}
				Filter filter = addFilter(name);
				checkFilter(filter, checked);
			}
		}

		public Filter addFilter(String name) {
			Filter filter = new Filter(name, false);
			if (!fFilters.contains(filter)) {
				fFilters.add(filter);
				fViewer.add(filter);
			}
			return filter;
		}

		public void removeFilters(Object[] filters) {
			for (int i = 0; i < filters.length; i++) {
				Filter filter = (Filter) filters[i];
				fFilters.remove(filter);
			}
			fViewer.remove(filters);
		}

		public void toggleFilter(Filter filter) {
			boolean newState = !filter.isChecked();
			filter.setChecked(newState);
			fViewer.setChecked(filter, newState);
		}

		public void checkFilter(Filter filter, boolean checked) {
			filter.setChecked(checked);
			fViewer.setChecked(filter, checked);
		}

		/**
		 * @see IStructuredContentProvider#getElements(Object)
		 */
		@Override
		public Object[] getElements(Object inputElement) {
			return fFilters.toArray();
		}

		/**
		 * @see IContentProvider#inputChanged(Viewer, Object, Object)
		 */
		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

		/**
		 * @see IContentProvider#dispose()
		 */
		@Override
		public void dispose() {
		}
	}

}
