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

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