/*******************************************************************************
 * Copyright (c) 2014, 2018 TwelveTone LLC 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:
 * Steven Spungin <steven@spungin.tv> - initial API and implementation
 * Olivier Prouvost <olivier.prouvost@opcoach.com> - Bug 466731
 *******************************************************************************/

package org.eclipse.e4.tools.emf.ui.internal.common;

import java.util.List;

import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
import org.eclipse.e4.tools.emf.ui.internal.Messages;
import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Table;

/**
 * <p>
 * A composite widget containing a combo for picking items, a list with
 * selectable items, and action buttons for modifying the list.
 * </p>
 *
 */
public abstract class AbstractPickList extends Composite {

	public enum PickListFeatures {
		NO_ORDER, NO_PICKER, NO_GROUP
	}

	protected ComboViewer picker;
	protected TableViewer viewer;

	private final Composite composite;
	private final Composite toolBar;

	protected final Button tiAdd;
	protected final Button tiRemove;
	protected final Button tiUp;
	protected final Button tiDown;

	@Deprecated
	public AbstractPickList(Composite parent, int style, List<PickListFeatures> listFeatures, Messages messages,
			AbstractComponentEditor componentEditor) {
		this(parent, style, listFeatures, componentEditor);
	}

	public AbstractPickList(Composite parent, int style, List<PickListFeatures> listFeatures,
			AbstractComponentEditor componentEditor) {

		super(parent, style);

		// TODO remove dependency AbstractComponentEditor. They
		// are only needed for labels and icons.

		setLayout(new FillLayout());

		if (listFeatures != null && listFeatures.contains(PickListFeatures.NO_GROUP)) {
			composite = new Composite(this, SWT.NONE);
		} else {
			composite = new Group(this, SWT.NONE);
		}

		GridLayout layout = new GridLayout(1, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.marginRight = 0;
		layout.marginLeft = 0;
		layout.horizontalSpacing = 0;
		layout.verticalSpacing = 0;
		composite.setLayout(layout);

		Composite comp = new Composite(composite, SWT.NONE);

		layout = new GridLayout(2, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.marginRight = 0;
		layout.marginLeft = 0;
		layout.horizontalSpacing = 0;
		layout.verticalSpacing = 0;
		comp.setLayout(layout);
		comp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));

		picker = new ComboViewer(comp, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);
		final Combo control = picker.getCombo();
		GridData gdpicker = new GridData(SWT.FILL, SWT.CENTER, true, false);
		gdpicker.minimumWidth = 180;
		gdpicker.grabExcessHorizontalSpace = true;
		control.setLayoutData(gdpicker);

		toolBar = new Composite(comp, SWT.NONE);
		layout = new GridLayout(5, true);
		if (listFeatures != null && listFeatures.contains(PickListFeatures.NO_PICKER)) {
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			layout.marginRight = 0;
			layout.marginLeft = 0;
		}
		layout.horizontalSpacing = 2;
		layout.verticalSpacing = 0;
		toolBar.setLayout(layout);
		toolBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
		toolBar.setFont(composite.getFont());

		picker.addOpenListener(event -> addPressed());

		tiAdd = new Button(toolBar, SWT.PUSH);
		tiAdd.setToolTipText(Messages.ModelTooling_Common_AddEllipsis);
		tiAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		tiAdd.setImage(componentEditor.createImage(ResourceProvider.IMG_Obj16_table_add));
		tiAdd.setFont(getButtonFont());
		tiAdd.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				addPressed();
			}
		});

		tiRemove = new Button(toolBar, SWT.PUSH);
		tiRemove.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		tiRemove.setToolTipText(Messages.ModelTooling_Common_Remove);
		tiRemove.setImage(componentEditor.createImage(ResourceProvider.IMG_Obj16_table_delete));
		tiRemove.setFont(getButtonFont());
		tiRemove.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				removePressed();
			}
		});

		tiDown = new Button(toolBar, SWT.PUSH);
		tiDown.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		tiDown.setToolTipText(Messages.ModelTooling_Common_Down);
		tiDown.setImage(componentEditor.createImage(ResourceProvider.IMG_Obj16_arrow_down));
		tiDown.setFont(getButtonFont());
		tiDown.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				moveDownPressed();
				boolean enable = viewer.getTable().getSelectionIndex() + 1 < getItemCount();
				if (tiDown.isEnabled() != enable) {
					tiDown.setEnabled(enable);
				}
				if (enable == false && !tiUp.isEnabled()) {
					tiUp.setEnabled(true);
				}
				tiDown.setFocus();
			}
		});

		tiUp = new Button(toolBar, SWT.PUSH);
		tiUp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		tiUp.setToolTipText(Messages.ModelTooling_Common_Up);
		tiUp.setImage(componentEditor.createImage(ResourceProvider.IMG_Obj16_arrow_up));
		tiUp.setFont(getButtonFont());
		tiUp.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				moveUpPressed();
				boolean enable = viewer.getTable().getSelectionIndex() > 0;
				if (tiUp.isEnabled() != enable) {
					tiUp.setEnabled(enable);
				}
				if (enable == false && !tiDown.isEnabled()) {
					tiDown.setEnabled(true);
				}
				tiUp.setFocus();
			}
		});

		viewer = new TableViewer(composite);
		viewer.getControl().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
		viewer.addSelectionChangedListener(event -> updateUiState());
		updateUiState();

		if (listFeatures != null) {
			if (listFeatures.contains(PickListFeatures.NO_ORDER)) {
				tiDown.dispose();
				tiUp.dispose();
			}
			if (listFeatures.contains(PickListFeatures.NO_PICKER)) {
				((GridData) picker.getControl().getLayoutData()).exclude = true;
				picker.getControl().setVisible(false);
				pack();
			}
		}

	}

	protected Font getButtonFont() {
		return toolBar.getFont();
	}

	protected void addPressed() {
	}

	protected abstract int getItemCount();

	public TableViewer getList() {
		return viewer;
	}

	public void setInput(Object input) {
		getPicker().setInput(input);

	}

	public IStructuredSelection getSelection() {
		return getPicker().getStructuredSelection();
	}

	public void setSelection(ISelection selection) {
		getPicker().setSelection(selection);
	}

	public void setContentProvider(IContentProvider contentProvider) {
		getPicker().setContentProvider(contentProvider);
	}

	public void setLabelProvider(ILabelProvider labelProvider) {
		getPicker().setLabelProvider(labelProvider);
	}

	private ComboViewer getPicker() {
		return picker;
	}

	public void setComparator(ViewerComparator comparator) {
		getPicker().setComparator(comparator);
	}

	protected Composite getToolBar() {
		return toolBar;
	}

	protected void moveDownPressed() {
	}

	protected void moveUpPressed() {
	}

	protected void removePressed() {
	}

	public void setText(String text) {
		if (composite instanceof Group) {
			((Group) composite).setText(text);
		}
	}

	public void updateUiState() {
		TableViewer tableViewer = getList();
		Table table = tableViewer.getTable();
		int itemCount = getItemCount();
		int selectionCount = table.getSelectionCount();
		int selectionIndex = table.getSelectionIndex();

		if (tiRemove.isEnabled() != selectionCount > 0) {
			tiRemove.setEnabled(selectionCount > 0);
		}

		// supports only single selection
		boolean enableButtons = selectionCount > 0 && itemCount > 1 && selectionCount == 1;

		// disable if last entry is selected
		boolean enableDown = (enableButtons) ? selectionIndex + 1 < itemCount : false;
		if (!tiDown.isDisposed() && tiDown.isEnabled() != enableDown) {
			tiDown.setEnabled(enableDown);
		}

		// disable if first entry is selected
		boolean enableUp = (enableButtons) ? selectionIndex > 0 : false;
		if (!tiUp.isDisposed() && tiUp.isEnabled() != enableUp) {
			tiUp.setEnabled(enableUp);
		}
	}
}
