/*=============================================================================#
 # Copyright (c) 2008, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.refactoring;

import java.util.List;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;

import org.eclipse.statet.ecommons.ui.util.DNDUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.refactoring.core.CommonRefactoringFactory;


/**
 * Command handler copying names of selected elements.
 */
public class CopyNamesHandler extends AbstractElementsHandler {
	
	
	public CopyNamesHandler(final CommonRefactoringFactory refactoring) {
		super(refactoring);
	}
	
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setEnabled(final Object context) {
		final ISelection selection= WorkbenchUIUtils.getCurrentSelection(context);
		if (selection != null) {
			setBaseEnabled(!selection.isEmpty());
		}
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public Object execute(final ExecutionEvent event) throws ExecutionException {
		final ISelection selection= WorkbenchUIUtils.getCurrentSelection(event.getApplicationContext());
		if (selection == null || selection.isEmpty()) {
			return null;
		}
		if (selection instanceof IStructuredSelection) {
			final List elements= ((IStructuredSelection) selection).toList();
			final StringBuilder sb= new StringBuilder(elements.size() * 20);
			final String br= System.getProperty("line.separator"); //$NON-NLS-1$
			for (int i= 0; ; ) {
				final String name= getName(elements.get(i++));
				if (name == null) {
					return null;
				}
				sb.append(name);
				if (i < elements.size()) {
					sb.append(br);
				}
				else {
					break;
				}
			}
			
			doCopyToClipboard(event, sb.toString());
		}
		return null;
	}
	
	protected String getName(final Object o) {
		if (o instanceof IModelElement) {
			return ((IModelElement) o).getElementName().getDisplayName();
		}
		return null;
	}
	
	private void doCopyToClipboard(final ExecutionEvent event, final String names) {
		final Clipboard clipboard= new Clipboard(UIAccess.getDisplay());
		try {
			DNDUtils.setContent(clipboard, 
					new Object[] { names }, 
					new Transfer[] { TextTransfer.getInstance() });
		}
		finally {
			if (clipboard != null && !clipboard.isDisposed()) {
				clipboard.dispose();
			}
		}
	}
	
}
