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

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

import org.eclipse.jdt.internal.debug.ui.display.DisplayViewerConfiguration;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jdt.ui.text.JavaTextTools;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Font;
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.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;

public class JavaDetailFormattersPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

	static public final String DETAIL_FORMATTER_IS_ENABLED= "1"; //$NON-NLS-1$
	static public final String DETAIL_FORMATTER_IS_DISABLED= "0"; //$NON-NLS-1$

	private CheckboxTableViewer fFormatterListViewer;
	private Button fAddFormatterButton;
	private Button fRemoveFormatterButton;
	private Button fEditFormatterButton;
	private JDISourceViewer fCodeViewer;
	private Label fTableLabel;

	private FormatterListViewerContentProvider fFormatViewerContentProvider;
    private Button fInlineFormattersButton;
    private Button fInlineAllButton;

	public JavaDetailFormattersPreferencePage() {
		super();
		setTitle(DebugUIMessages.JavaDetailFormattersPreferencePage_0);
		setPreferenceStore(JDIDebugUIPlugin.getDefault().getPreferenceStore());
		setDescription(DebugUIMessages.JavaDetailFormattersPreferencePage_Override_default___toString_____for_Variables_and_Expressions_view_details__1);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createContents(Composite parent) {
		noDefaultAndApplyButton();
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.JAVA_DETAIL_FORMATTER_PREFERENCE_PAGE);
        Font font = parent.getFont();
        initializeDialogUnits(parent);

        // top level container
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        container.setLayout(layout);
        GridData gd = new GridData(GridData.FILL_BOTH);
        container.setLayoutData(gd);
        container.setFont(font);

		createDetailFormatsPreferences(container);
        createLabelPreferences(container);

        Dialog.applyDialogFont(container);
        return container;
	}

	/**
	 * @see IWorkbenchPreferencePage#init(IWorkbench)
	 */
	@Override
	public void init(IWorkbench workbench) {
	}

    private void createLabelPreferences(Composite parent) {
        Group group= new Group(parent, SWT.NONE);
        GridData gridData= new GridData(GridData.FILL_HORIZONTAL);
        gridData.horizontalSpan= 2;
        group.setLayoutData(gridData);
        group.setLayout(new GridLayout());
        group.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_1);

        String preference= getPreferenceStore().getString(IJDIPreferencesConstants.PREF_SHOW_DETAILS);

        // Create the 3 detail option radio buttons
        fInlineFormattersButton = new Button(group, SWT.RADIO);
        fInlineFormattersButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_2);
        fInlineFormattersButton.setSelection(preference.equals(IJDIPreferencesConstants.INLINE_FORMATTERS));

        fInlineAllButton = new Button(group, SWT.RADIO);
        fInlineAllButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_3);
        fInlineAllButton.setSelection(preference.equals(IJDIPreferencesConstants.INLINE_ALL));

        Button detailPane = new Button(group, SWT.RADIO);
        detailPane.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_4);
        detailPane.setSelection(preference.equals(IJDIPreferencesConstants.DETAIL_PANE));
    }

	/**
	 * Create a group to contain the detail formatters related widgetry
	 */
	private Control createDetailFormatsPreferences(Composite parent) {
        Font font= parent.getFont();

		//table label
		fTableLabel= new Label(parent, SWT.NONE);
		fTableLabel.setText(DebugUIMessages.JavaDetailFormattersPreferencePage__Types_with_detail_formatters__2);
		GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan = 2;
		fTableLabel.setLayoutData(gd);
		fTableLabel.setFont(font);

		fFormatterListViewer= CheckboxTableViewer.newCheckList(parent, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
		Table table = (Table)fFormatterListViewer.getControl();
		gd = new GridData(GridData.FILL_BOTH);
		//gd.heightHint= convertHeightInCharsToPixels(5);
		gd.widthHint= convertWidthInCharsToPixels(10);
		table.setLayoutData(gd);
		table.setFont(font);
		fFormatViewerContentProvider= new FormatterListViewerContentProvider(fFormatterListViewer);
		fFormatterListViewer.setContentProvider(fFormatViewerContentProvider);
		fFormatterListViewer.setLabelProvider(new LabelProvider() {
			@Override
			public String getText(Object element) {
				if (element instanceof DetailFormatter) {
					return ((DetailFormatter)element).getTypeName();
				}
				return null;
			}
		});
		fFormatterListViewer.addCheckStateListener(new ICheckStateListener() {
			@Override
			public void checkStateChanged(CheckStateChangedEvent event) {
				((DetailFormatter)event.getElement()).setEnabled(event.getChecked());
			}
		});
		fFormatterListViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				updatePage((IStructuredSelection)event.getSelection());
			}
		});
		fFormatterListViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent event) {
				if (!event.getSelection().isEmpty()) {
					editType();
				}
			}
		});
		table.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent event) {
				if (event.character == SWT.DEL && event.stateMask == 0) {
					removeTypes();
				}
			}
		});
		fFormatterListViewer.setInput(this);

		createDetailFormatsButtons(parent);

		Label label = new Label(parent, SWT.NONE);
		label.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_Detail_formatter_code_snippet_defined_for_selected_type__3);
		label.setFont(font);
        gd= new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan= 2;
        label.setLayoutData(gd);
		createSourceViewer(parent);

		fFormatViewerContentProvider.refreshViewer();
		return parent;
	}


	private void createDetailFormatsButtons(Composite container) {
		Font font = container.getFont();

		// button container
		Composite buttonContainer = new Composite(container, SWT.NONE);
		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);

		// Add type button
		fAddFormatterButton = new Button(buttonContainer, SWT.PUSH);
		fAddFormatterButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage_Add__Formatter____5);
		fAddFormatterButton.setToolTipText(DebugUIMessages.JavaDetailFormattersPreferencePage_Allow_you_to_create_a_new_detail_formatter_6);
		fAddFormatterButton.setLayoutData(gd);
		fAddFormatterButton.setFont(font);
		setButtonLayoutData(fAddFormatterButton);
		fAddFormatterButton.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event e) {
				addType();
			}
		});

		// Edit button
		fEditFormatterButton = new Button(buttonContainer, SWT.PUSH);
		fEditFormatterButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage__Edit____9);
		fEditFormatterButton.setToolTipText(DebugUIMessages.JavaDetailFormattersPreferencePage_Edit_the_selected_detail_formatter_10);
		fEditFormatterButton.setFont(font);
		setButtonLayoutData(fEditFormatterButton);
		fEditFormatterButton.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event e) {
				editType();
			}
		});
		fEditFormatterButton.setEnabled(false);

		// Remove button
		fRemoveFormatterButton = new Button(buttonContainer, SWT.PUSH);
		fRemoveFormatterButton.setText(DebugUIMessages.JavaDetailFormattersPreferencePage__Remove_7);
		fRemoveFormatterButton.setToolTipText(DebugUIMessages.JavaDetailFormattersPreferencePage_Remove_all_selected_detail_formatters_8);
		fRemoveFormatterButton.setFont(font);
		setButtonLayoutData(fRemoveFormatterButton);
		fRemoveFormatterButton.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event e) {
				removeTypes();
			}
		});
		fRemoveFormatterButton.setEnabled(false);
	}

	public void createSourceViewer(Composite container) {
		fCodeViewer= new JDISourceViewer(container,  null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.LEFT_TO_RIGHT);

		JavaTextTools tools= JDIDebugUIPlugin.getDefault().getJavaTextTools();
		IDocument document= new Document();
		tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
		fCodeViewer.configure(new DisplayViewerConfiguration());
		fCodeViewer.setEditable(false);
		fCodeViewer.setDocument(document);

		Control control= fCodeViewer.getControl();
		GridData gd= new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan= 2;
		//gd.heightHint= convertHeightInCharsToPixels(5);
		control.setLayoutData(gd);
	}

	private void updatePage(IStructuredSelection selection) {
		fRemoveFormatterButton.setEnabled(!selection.isEmpty());
		fEditFormatterButton.setEnabled(selection.size() == 1);
		updateFormatViewer(selection);
	}

	private void updateFormatViewer(IStructuredSelection selection) {
		if (selection.size() == 1) {
			fCodeViewer.getDocument().set(((DetailFormatter)selection.getFirstElement()).getSnippet());
		} else {
			fCodeViewer.getDocument().set(""); //$NON-NLS-1$
		}
	}

	public void addType() {
		DetailFormatter detailFormat= new DetailFormatter("", "", true); //$NON-NLS-1$ //$NON-NLS-2$
		if (new DetailFormatterDialog(getShell(), detailFormat, fFormatViewerContentProvider.getDefinedTypes(), false).open() == Window.OK) {
			fFormatViewerContentProvider.addDetailFormatter(detailFormat);
		}
	}

	public void removeTypes() {
		Object[] all = fFormatViewerContentProvider.getElements(null);
		IStructuredSelection selection= (IStructuredSelection)fFormatterListViewer.getSelection();
		Object first = selection.getFirstElement();
		int index = -1;
		for (int i = 0; i < all.length; i++) {
			Object object = all[i];
			if (object.equals(first)) {
				index = i;
				break;
			}
		}
		fFormatViewerContentProvider.removeDetailFormatters(selection.toArray());
		all = fFormatViewerContentProvider.getElements(null);
		if (index > all.length - 1) {
			index = all.length - 1;
		}
		if (index >= 0) {
			fFormatterListViewer.setSelection(new StructuredSelection(all[index]));
		}
	}

	public void editType() {
		IStructuredSelection selection= (IStructuredSelection)fFormatterListViewer.getSelection();
		if (new DetailFormatterDialog(getShell(), (DetailFormatter)(selection).getFirstElement(), null, true, true).open() == Window.OK) {
			fFormatterListViewer.refresh();
			fFormatViewerContentProvider.refreshViewer();
			updatePage(selection);
		}
	}

	@Override
	public boolean performOk() {
		if (fFormatViewerContentProvider != null) {
			fFormatViewerContentProvider.saveDetailFormatters();

	        String value= IJDIPreferencesConstants.DETAIL_PANE;
	        if (fInlineAllButton.getSelection()) {
	            value= IJDIPreferencesConstants.INLINE_ALL;
	        } else if (fInlineFormattersButton.getSelection()) {
	            value= IJDIPreferencesConstants.INLINE_FORMATTERS;
	        }
	        JDIDebugUIPlugin.getDefault().getPreferenceStore().setValue(IJDIPreferencesConstants.PREF_SHOW_DETAILS, value);
			fCodeViewer.dispose();
		}
		return true;
	}

	class FormatterListViewerContentProvider implements IStructuredContentProvider {

		private Set<DetailFormatter> fDetailFormattersSet;

		private List<String> fDefinedTypes;

		private CheckboxTableViewer fViewer;

		/**
		 * FormatterListViewerContentProvider constructor.
		 */
		public FormatterListViewerContentProvider(CheckboxTableViewer viewer) {
			fViewer= viewer;
			// load the current formatters
			String[] detailFormattersList= JavaDebugOptionsManager.parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST));
			fDetailFormattersSet= new TreeSet<>();
			fDefinedTypes= new ArrayList<>(detailFormattersList.length / 3);
			for (int i= 0, length= detailFormattersList.length; i < length;) {
				String typeName= detailFormattersList[i++];
				String snippet= detailFormattersList[i++].replace('\u0000', ',');
				boolean enabled= ! DETAIL_FORMATTER_IS_DISABLED.equals(detailFormattersList[i++]);
				DetailFormatter detailFormatter= new DetailFormatter(typeName, snippet, enabled);
				fDetailFormattersSet.add(detailFormatter);
				fDefinedTypes.add(typeName);
			}
		}

		/**
		 * Save the detail formatter list.
		 */
		public void saveDetailFormatters() {
			String[] values= new String[fDetailFormattersSet.size() * 3];
			int i= 0;
			for (Iterator<DetailFormatter> iter= fDetailFormattersSet.iterator(); iter.hasNext();) {
				DetailFormatter detailFormatter= iter.next();
				values[i++]= detailFormatter.getTypeName();
				values[i++]= detailFormatter.getSnippet().replace(',','\u0000');
				values[i++]= detailFormatter.isEnabled() ? DETAIL_FORMATTER_IS_ENABLED : DETAIL_FORMATTER_IS_DISABLED;
			}
			String pref = JavaDebugOptionsManager.serializeList(values);
			getPreferenceStore().setValue(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST, pref);

		}

		/**
		 * Add a detail formatter.
		 */
		public void addDetailFormatter(DetailFormatter detailFormatter) {
			fDetailFormattersSet.add(detailFormatter);
			fDefinedTypes.add(detailFormatter.getTypeName());
			fViewer.refresh();
			refreshViewer();
			IStructuredSelection selection= new StructuredSelection(detailFormatter);
			fViewer.setSelection(selection);
			updatePage(selection);
		}

		/**
		 * Remove a detailFormatter
		 */
		public void removeDetailFormatter(DetailFormatter detailFormatter) {
			fDetailFormattersSet.remove(detailFormatter);
			fDefinedTypes.remove(detailFormatter.getTypeName());
			fViewer.refresh();
			IStructuredSelection selection= new StructuredSelection();
			fViewer.setSelection(selection);
			updatePage(selection);
		}

		/**
		 * Remove detailFormatters
		 */
		public void removeDetailFormatters(Object[] detailFormatters) {
			for (int i= 0, length= detailFormatters.length; i < length; i++) {
				fDetailFormattersSet.remove(detailFormatters[i]);
				fDefinedTypes.remove(((DetailFormatter)detailFormatters[i]).getTypeName());
			}
			fViewer.refresh();
			IStructuredSelection selection= new StructuredSelection();
			fViewer.setSelection(selection);
			updatePage(selection);
		}

		/**
		 * Refresh the formatter list viewer.
		 */
		private void refreshViewer() {
			DetailFormatter[] checkedElementsTmp= new DetailFormatter[fDetailFormattersSet.size()];
			int i= 0;
			for (Iterator<DetailFormatter> iter= fDetailFormattersSet.iterator(); iter.hasNext();) {
				DetailFormatter detailFormatter= iter.next();
				if (detailFormatter.isEnabled()) {
					checkedElementsTmp[i++]= detailFormatter;
				}
			}
			DetailFormatter[] checkedElements= new DetailFormatter[i];
			System.arraycopy(checkedElementsTmp, 0, checkedElements, 0, i);
			fViewer.setAllChecked(false);
			fViewer.setCheckedElements(checkedElements);
		}

		/**
		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
		 */
		@Override
		public Object[] getElements(Object inputElement) {
			return fDetailFormattersSet.toArray();
		}

		public List<String> getDefinedTypes() {
			return fDefinedTypes;
		}

		/**
		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
		 */
		@Override
		public void dispose() {
		}

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

	/* (non-Javadoc)
	 * @see org.eclipse.jface.preference.PreferencePage#performCancel()
	 */
	@Override
	public boolean performCancel() {
		if (fCodeViewer != null) {
			fCodeViewer.dispose();
		}
		return super.performCancel();
	}
}
