/*=============================================================================#
 # Copyright (c) 2000, 2020 IBM Corporation 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.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     IBM Corporation - org.eclipse.jdt: initial API and implementation
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

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

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.participants.CopyProcessor;
import org.eclipse.ltk.core.refactoring.participants.CopyRefactoring;
import org.eclipse.ltk.core.refactoring.participants.MoveProcessor;
import org.eclipse.ltk.core.refactoring.participants.MoveRefactoring;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ltk.ui.refactoring.Messages;
import org.eclipse.statet.ltk.model.core.ElementSet;
import org.eclipse.statet.ltk.model.core.element.SourceElement;
import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.refactoring.core.CommonRefactoringFactory;
import org.eclipse.statet.ltk.refactoring.core.RefactoringAdapter;
import org.eclipse.statet.ltk.refactoring.core.RefactoringDestination;
import org.eclipse.statet.ltk.ui.refactoring.RefactoringExecutionHelper;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorAssociated;


public class ViewerSelectionTransferDropAdapter extends ViewerDropAdapter implements TransferDropTargetListener {
	
	
	private final IAdaptable part;
	
	private final CommonRefactoringFactory refactoring;
	private RefactoringAdapter adapter;
	
	private ElementSet elements;
	
	private MoveProcessor moveProcessor;
	private int canMoveElements;
	private CopyProcessor copyProcessor;
	private int canCopyElements;
	private ISelection selection;
	
	
	public ViewerSelectionTransferDropAdapter(final StructuredViewer viewer,
			final CommonRefactoringFactory refactoring) {
		this(viewer, null, refactoring);
	}
	
	public ViewerSelectionTransferDropAdapter(final StructuredViewer viewer, final IAdaptable part,
			final CommonRefactoringFactory refactoring) {
		super(viewer);
		this.part= part;
		
		this.refactoring= refactoring;
		
		setScrollEnabled(true);
		setExpandEnabled(true);
		setSelectionFeedbackEnabled(false);
		setFeedbackEnabled(false);
	}
	
	//---- TransferDropTargetListener interface ---------------------------------------
	
	
	@Override
	public Transfer getTransfer() {
		return LocalSelectionTransfer.getTransfer();
	}
	
	@Override
	public boolean isEnabled(final DropTargetEvent event) {
		final Object target= event.item != null ? event.item.getData() : null;
		if (target == null) {
			return false;
		}
		return (target instanceof SourceStructElement);
	}
	
	
	//---- Actual DND -----------------------------------------------------------------
	
	@Override
	public void dragEnter(final DropTargetEvent event) {
		clear();
		super.dragEnter(event);
	}
	
	@Override
	public void dragLeave(final DropTargetEvent event) {
		clear();
		super.dragLeave(event);
	}
	
	private void clear() {
		setSelectionFeedbackEnabled(false);
		this.elements= null;
		this.selection= null;
		this.moveProcessor= null;
		this.canMoveElements= 0;
		this.copyProcessor= null;
		this.canCopyElements= 0;
		this.adapter= null;
	}
	
	@Override
	public boolean validateDrop(final Object target, final int operation, final TransferData transferType) {
		final int result= internalDetermineOperation(target, operation,
				DND.DROP_MOVE | DND.DROP_COPY);
		
		if (result == DND.DROP_NONE) {
			setSelectionFeedbackEnabled(false);
			return false;
		}
		else {
			setSelectionFeedbackEnabled(true);
			overrideOperation(result);
			return true;
		}
	}
	
	private int internalDetermineOperation(final Object target, final int operation, final int operations) {
		if (!(target instanceof SourceElement)) {
			return DND.DROP_NONE;
		}
		
		if (!initializeSelection()) {
			return DND.DROP_NONE;
		}
		
		if (this.elements.getResources().size() > 0) { // resources not yet supported
			return DND.DROP_NONE;
		}
		this.elements.removeElementsWithAncestorsOnList();
		
		RefactoringDestination.Position pos;
		switch (getCurrentLocation()) {
		case LOCATION_BEFORE:
			pos= RefactoringDestination.Position.ABOVE;
			break;
		case LOCATION_AFTER:
			pos= RefactoringDestination.Position.BELOW;
			break;
		default:
			pos= RefactoringDestination.Position.INTO;
		}
		final RefactoringDestination destination= new RefactoringDestination(target, pos);
		this.adapter= this.refactoring.createAdapter(destination);
		if (this.adapter == null || !this.adapter.canInsert(this.elements, destination)) {
			return DND.DROP_NONE;
		}
		
		try {
			switch (operation) {
				case DND.DROP_DEFAULT:
					return handleValidateDefault(destination, operations);
				case DND.DROP_COPY:
					return handleValidateCopy(destination);
				case DND.DROP_MOVE:
					return handleValidateMove(destination);
			}
		}
		catch (final CoreException e) {
			if (e.getStatus().getSeverity() == IStatus.ERROR) { 
				StatusManager.getManager().handle(new Status(IStatus.ERROR,
						this.adapter.getPluginIdentifier(), -1,
						"An error occurred when validation the drop location.", e ));
			}
		}
		return DND.DROP_NONE;
	}
	
	protected boolean initializeSelection(){
		if (this.elements != null) {
			return this.elements.isOK();
		}
		final ISelection s= LocalSelectionTransfer.getTransfer().getSelection();
		if (!(s instanceof IStructuredSelection)) {
			return false;
		}
		this.selection= s;
		this.elements= new ElementSet(((IStructuredSelection) s).toArray());
		if (!this.elements.isOK()) {
			return false;
		}
		return true;
	}
	
	protected ISelection getSelection(){
		return this.selection;
	}
	
	@Override
	public boolean performDrop(final Object data) {
		switch(getCurrentOperation()) {
		case DND.DROP_MOVE:
			return handleDropMove();
		case DND.DROP_COPY:
			return handleDropCopy();
		}
		return false;
	}
	
	private int handleValidateDefault(final RefactoringDestination destination,
			final int operations) throws CoreException {
		if ((operations & DND.DROP_MOVE) != 0) {
			final int result= handleValidateMove(destination);
			if (result != DND.DROP_NONE) {
				return result;
			}
		}
		return handleValidateCopy(destination);
	}
	
	
	private int handleValidateMove(final RefactoringDestination destination) throws CoreException {
		if (this.moveProcessor == null) {
			final MoveProcessor processor= this.refactoring.createMoveProcessor(this.elements, destination, this.adapter);
			if (processor != null && processor.isApplicable()) {
				this.moveProcessor= processor;
			}
		}
		return (canMoveElements()) ? DND.DROP_MOVE : DND.DROP_NONE;
	}
	
	private boolean canMoveElements() {
		if (this.canMoveElements == 0) {
			this.canMoveElements= (this.moveProcessor != null) ? 2 : 1;
		}
		return this.canMoveElements == 2;
	}
	
	protected boolean handleDropMove() {
		try {
			execute(new MoveRefactoring(this.moveProcessor));
			return true;
		}
		catch (final InvocationTargetException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR,
							this.adapter.getPluginIdentifier(), -1,
							Messages.MoveElements_error_message, e.getCause() ),
					StatusManager.LOG | StatusManager.SHOW );
			return false;
		}
		catch (final InterruptedException e) {
			return false;
		}
	}
	
	private int handleValidateCopy(final RefactoringDestination destination) throws CoreException {
		if (this.copyProcessor == null) {
			final CopyProcessor processor= this.refactoring.createCopyProcessor(this.elements, destination, this.adapter);
			if (processor != null && processor.isApplicable()) {
				this.copyProcessor= processor;
			}
		}
		return (canCopyElements()) ? DND.DROP_COPY : DND.DROP_NONE;
	}
	
	private boolean canCopyElements() {
		if (this.canCopyElements == 0) {
			this.canCopyElements= (this.copyProcessor != null) ? 2 : 1;
		}
		return this.canCopyElements == 2;
	}
	
	protected boolean handleDropCopy() {
		try {
			execute(new CopyRefactoring(this.copyProcessor));
			return true;
		}
		catch (final InvocationTargetException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR,
							this.adapter.getPluginIdentifier(), -1,
							Messages.CopyElements_error_message, e.getCause() ),
					StatusManager.LOG | StatusManager.SHOW );
			return false;
		}
		catch (final InterruptedException e) {
			return false;
		}
	}
	
	protected void execute(final Refactoring refactoring) throws InterruptedException, InvocationTargetException {
		final IWorkbenchWindow window= UIAccess.getActiveWorkbenchWindow(true);
		final IProgressService context= window.getService(IProgressService.class);
		final RefactoringExecutionHelper helper= new RefactoringExecutionHelper(refactoring, 
				RefactoringCore.getConditionCheckingFailedSeverity(), 
				getShell(), context );
		
		ISourceEditor editor= null;
		if (this.part != null) {
			editor= this.part.getAdapter(ISourceEditor.class);
			if (editor == null) {
				final ISourceEditorAssociated associated= this.part
						.getAdapter(ISourceEditorAssociated.class);
				if (associated != null) {
					editor= associated.getSourceEditor();
				}
			}
		}
		if (editor != null) {
			final SourceUnit su= editor.getSourceUnit();
			if (su != null) {
				helper.enableInsertPosition(su);
			}
		}
		helper.perform(false, false);
		if (editor != null) {
			final Position position= helper.getInsertPosition();
			if (position != null) {
				editor.selectAndReveal(position.getOffset(), 0);
			}
		}
	}
	
	private Shell getShell() {
		return getViewer().getControl().getShell();
	}
	
	@Override
	protected int getCurrentLocation() {
		if (getFeedbackEnabled()) {
			return super.getCurrentLocation();
		}
		else {
			return LOCATION_ON;
		}
	}
	
}
