/*******************************************************************************
 * Copyright (c) 2009, 2017 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
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stefan Dirix (sdirix@eclipsesource.com) - Bug 473847: Minimum E4 Compatibility of Compare
 *******************************************************************************/
package org.eclipse.compare.internal;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareViewerSwitchingPane;
import org.eclipse.compare.Splitter;
import org.eclipse.compare.internal.core.ComparePlugin;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

public class CompareContentViewerSwitchingPane extends CompareViewerSwitchingPane {
	private static final String OPTIMIZED_INFO_IMAGE_NAME = "obj16/message_info.png"; //$NON-NLS-1$
	public static final String OPTIMIZED_ALGORITHM_USED = "OPTIMIZED_ALGORITHM_USED"; //$NON-NLS-1$
	public static final String DISABLE_CAPPING_TEMPORARILY = "DISABLE_CAPPING_TEMPORARILY"; //$NON-NLS-1$

	private CompareEditorInput fCompareEditorInput;

	private ViewerDescriptor fSelectedViewerDescriptor;

	private ToolBar toolBar;
	private CLabel labelOptimized;
	private Link recomputeLink;

	private boolean menuShowing;

	public CompareContentViewerSwitchingPane(Splitter parent, int style,
			CompareEditorInput editorInput) {
		super(parent, style);
		fCompareEditorInput = editorInput;
	}

	private CompareConfiguration getCompareConfiguration() {
		return fCompareEditorInput.getCompareConfiguration();
	}

	@Override
	protected Viewer getViewer(Viewer oldViewer, Object input) {
		if (fSelectedViewerDescriptor != null) {
			ViewerDescriptor[] array = CompareUIPlugin.getDefault().findContentViewerDescriptor(
					oldViewer, input, getCompareConfiguration());
			List<ViewerDescriptor> list = array != null ? Arrays.asList(array) : Collections.emptyList();
			if (list.contains(fSelectedViewerDescriptor)) {
				// use selected viewer only when appropriate for the new input
				fCompareEditorInput
						.setContentViewerDescriptor(fSelectedViewerDescriptor);
				Viewer viewer = fCompareEditorInput.findContentViewer(
						oldViewer, (ICompareInput) input, this);
				return viewer;
			}
			// Fallback to default otherwise
			fSelectedViewerDescriptor = null;
		}
		if (input instanceof ICompareInput) {
			fCompareEditorInput.setContentViewerDescriptor(null);
			Viewer viewer =
					fCompareEditorInput.findContentViewer(oldViewer, (ICompareInput) input, this);
			fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
			return viewer;
		}
		return null;
	}

	@Override
	protected Control createTopLeft(Composite p) {
		final Composite composite = new Composite(p, SWT.NONE) {
			@Override
			public Point computeSize(int wHint, int hHint, boolean changed) {
				return super.computeSize(wHint, Math.max(24, hHint), changed);
			}
		};

		RowLayout layout = new RowLayout();
		layout.marginTop = 0;
		layout.center = true;
		layout.wrap = false;
		composite.setLayout(layout);

		CLabel cl = new CLabel(composite, SWT.NONE);
		cl.setText(null);

		toolBar = new ToolBar(composite, SWT.FLAT);
		toolBar.setVisible(false); // hide by default
		final ToolItem toolItem = new ToolItem(toolBar, SWT.PUSH, 0);
		Utilities.setMenuImage(toolItem);
		toolItem.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_switchButtonTooltip);
		toolItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				showMenu();
			}
		});
		toolBar.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				showMenu();
			}
		});

		labelOptimized = new CLabel(composite, SWT.NONE);
		labelOptimized.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_optimizedTooltip);
		labelOptimized.setImage(CompareUIPlugin.getImageDescriptor(
				OPTIMIZED_INFO_IMAGE_NAME).createImage());
		labelOptimized.setVisible(false); // hide by default
		labelOptimized.addDisposeListener(e -> {
			Image img = labelOptimized.getImage();
			if ((img != null) && (!img.isDisposed())) {
				img.dispose();
			}
		});

		recomputeLink = new Link(composite, SWT.NONE);
		recomputeLink.setText(CompareMessages.CompareContentViewerSwitchingPane_optimizedLinkLabel);
		recomputeLink.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_optimizedTooltip);
		recomputeLink.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				/*
				 * Disable capping temporarily, refresh, restore global state.
				 * The global state is bad, but fixing that would require lots of changes and new APIs.
				 */
				IPreferenceStore preferenceStore = CompareUIPlugin.getDefault().getPreferenceStore();
				boolean wasDisabled = preferenceStore.getBoolean(ComparePreferencePage.CAPPING_DISABLED);
				ComparePlugin.getDefault().setCappingDisabled(true);
				preferenceStore.setValue(ComparePreferencePage.CAPPING_DISABLED, true);
				try {
					getCompareConfiguration().setProperty(DISABLE_CAPPING_TEMPORARILY, Boolean.TRUE);
				} finally {
					if (!wasDisabled) {
						ComparePlugin.getDefault().setCappingDisabled(false);
						preferenceStore.setValue(ComparePreferencePage.CAPPING_DISABLED, false);
					}
				}
			}
		});
		recomputeLink.setVisible(false);

		return composite;
	}

	@Override
	protected boolean inputChanged(Object input) {
		return getInput() != input
				|| fCompareEditorInput.getContentViewerDescriptor() != fSelectedViewerDescriptor;
	}

	@Override
	public void setInput(Object input) {
		super.setInput(input);
		if (getViewer() == null || !Utilities.okToUse(getViewer().getControl()))
			return;
		ViewerDescriptor[] vd = CompareUIPlugin.getDefault()
				.findContentViewerDescriptor(getViewer(), getInput(), getCompareConfiguration());
		toolBar.setVisible(vd != null && vd.length > 1);
		CompareConfiguration cc = getCompareConfiguration();
		Boolean isOptimized = (Boolean) cc.getProperty(OPTIMIZED_ALGORITHM_USED);
		boolean optimizedVisible = isOptimized != null && isOptimized.booleanValue();
		labelOptimized.setVisible(optimizedVisible);
		recomputeLink.setVisible(optimizedVisible);
	}

	private void showMenu() {
		if (menuShowing)
			return;
		menuShowing= true;

		ViewerDescriptor[] vd = CompareUIPlugin.getDefault()
				.findContentViewerDescriptor(getViewer(), getInput(),getCompareConfiguration());

		// 1. Create
		final Menu menu = new Menu(getShell(), SWT.POP_UP);

		// Add default
		String label = CompareMessages.CompareContentViewerSwitchingPane_defaultViewer;
		MenuItem defaultItem = new MenuItem(menu, SWT.RADIO);
		defaultItem.setText(label);
		defaultItem.addSelectionListener(createSelectionListener(null));
		defaultItem.setSelection(fSelectedViewerDescriptor == null);

		new MenuItem(menu, SWT.SEPARATOR);

		// Add others
		for (ViewerDescriptor vdi : vd) {
			label = vdi.getLabel();
			if (label == null || label.isEmpty()) {
				String l = CompareUIPlugin.getDefault().findContentTypeNameOrType((ICompareInput) getInput(),
						vdi, getCompareConfiguration());
				if (l == null)
					continue;  // Couldn't figure out the label, skip the viewer
				label = NLS.bind(CompareMessages.CompareContentViewerSwitchingPane_discoveredLabel, l);
			}
			MenuItem item = new MenuItem(menu, SWT.RADIO);
			item.setText(label);
			item.addSelectionListener(createSelectionListener(vdi));
			item.setSelection(vdi == fSelectedViewerDescriptor);
		}

		// 2. Show
		Rectangle bounds = toolBar.getItem(0).getBounds();
		Point topLeft = new Point(bounds.x, bounds.y + bounds.height);
		topLeft = toolBar.toDisplay(topLeft);
		menu.setLocation(topLeft.x, topLeft.y);
		menu.setVisible(true);

		// 3. Dispose on close
		menu.addMenuListener(new MenuAdapter() {
			@Override
			public void menuHidden(MenuEvent e) {
				menuShowing= false;
				e.display.asyncExec(() -> menu.dispose());
			}
		});
	}

	private SelectionListener createSelectionListener(final ViewerDescriptor vd) {
		return new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				MenuItem mi = (MenuItem) e.widget;
				if (mi.getSelection()) {
					Viewer oldViewer = getViewer();
					fSelectedViewerDescriptor = vd;
					CompareContentViewerSwitchingPane.this.setInput(oldViewer.getInput());
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// Nothing to do
			}
		};
	}

	@Override
	public void setText(String text) {
		Composite c = (Composite) getTopLeft();
		for (Control child : c.getChildren()) {
			if (child instanceof CLabel) {
				CLabel label = (CLabel) child;
				if (label != null && !label.isDisposed()) {
					label.setText(text);
					c.layout();
				}
				return;
			}
		}
	}

	@Override
	public void setImage(Image image) {
		Composite c = (Composite) getTopLeft();
		for (Control child : c.getChildren()) {
			if (child instanceof CLabel) {
				CLabel label = (CLabel) child;
				if (label != null && !label.isDisposed())
					label.setImage(image);
				return;
			}
		}
	}

	@Override
	public void addMouseListener(MouseListener listener) {
		Composite c = (Composite) getTopLeft();
		for (Control child : c.getChildren()) {
			if (child instanceof CLabel) {
				CLabel label = (CLabel) child;
				label.addMouseListener(listener);
			}
		}
	}
}
