/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal;

import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Caret;
import org.eclipse.ui.IEditorPart;
import org.eclipse.wst.sse.ui.internal.TransferBuilder.TransferProxyForDelayLoading;

/**
 * ExtendedEditorDropTargetAdapter
 */
public class ExtendedEditorDropTargetAdapter extends DropTargetAdapter {

	private Point caret = null;
	private String[] editorIds;
	private int orgOffset = 0;
	private IEditorPart targetEditor = null;
	private ITextViewer textViewer = null;

	private Transfer[] transfers = null;

	private boolean useProxy;

	/**
	 * @deprecated use ExtendedEditorDropTargetAdapter(boolean useProxy) for
	 *             the performance
	 */
	public ExtendedEditorDropTargetAdapter() {
		this(false);
	}

	public ExtendedEditorDropTargetAdapter(boolean useProxy) {
		super();
		this.useProxy = useProxy;
	}

	protected boolean doDrop(Transfer transfer, DropTargetEvent event) {
		TransferBuilder tb = new TransferBuilder(useProxy);

		IDropAction[] as = null;
		if (editorIds != null && editorIds.length > 0)
			as = tb.getDropActions(editorIds, transfer);
		else
			as = tb.getDropActions(getTargetEditor().getClass().getName(), transfer);

		for (int i = 0; i < as.length; ++i) {
			IDropAction da = as[i];
			Transfer actualTransfer;
			if (transfer instanceof TransferProxyForDelayLoading) {
				actualTransfer = ((TransferProxyForDelayLoading) transfer).getTransferClass();
			}
			else {
				actualTransfer = transfer;
			}
			if (actualTransfer instanceof FileTransfer) {
				if (event.data == null) {
					Logger.log(Logger.ERROR, "No data in DropTargetEvent from " + event.widget); //$NON-NLS-1$
					return false;
				}
				String[] strs = (String[]) event.data;
				boolean[] bs = new boolean[strs.length];
				int c = 0;
				for (int j = 0; j < strs.length; ++j) {
					bs[j] = false;
					if (da.isSupportedData(strs[j])) {
						event.data = new String[]{strs[j]};
						if (!da.run(event, targetEditor)) {
							bs[j] = true;
							c++;
						}
					}
					else {
						bs[j] = true;
						c++;
					}
				}
				if (c == 0) {
					return true;
				}

				int k = 0;
				String[] rests = new String[c];
				for (int j = 0; j < strs.length; ++j) {
					if (bs[j])
						rests[k++] = strs[j];
				}
				event.data = rests;
			}
			else if (da.isSupportedData(event.data)) {
				if (da.run(event, targetEditor)) {
					return true;
				}
			}
		}

		return false;
	}

	/**
	 */
	public void dragEnter(DropTargetEvent event) {
		caret = null;
		TransferData data = null;
		Transfer[] ts = getTransfers();
		for (int i = 0; i < ts.length; i++) {
			for (int j = 0; j < event.dataTypes.length; j++) {
				if (ts[i].isSupportedType(event.dataTypes[j])) {
					data = event.dataTypes[j];
					break;
				}
			}
			if (data != null) {
				event.currentDataType = data;
				break;
			}
		}

		if (textViewer != null) {
			orgOffset = textViewer.getTextWidget().getCaretOffset();
		}
	}

	public void dragLeave(DropTargetEvent event) {
		if (textViewer != null) {
			StyledText st = textViewer.getTextWidget();
			st.setCaretOffset(orgOffset);
			st.redraw();
			st.update();
		}
	}

	/**
	 */
	public void dragOver(DropTargetEvent event) {
		event.operations &= ~DND.DROP_MOVE;
		event.detail = DND.DROP_COPY;

		if (textViewer != null) {
			Point pt = toControl(new Point(event.x, event.y));
			StyledText st = textViewer.getTextWidget();

			// auto scroll
			Rectangle ca = st.getClientArea();
			int margin = st.getLineHeight();

			if (pt.y < margin) { // up
				st.invokeAction(ST.LINE_UP);
			}
			else if (pt.y > ca.height - margin) { // down
				st.invokeAction(ST.LINE_DOWN);
			}

			// draw insertion point
			int offset = getDropOffset(st, pt);
			if (offset != st.getCaretOffset()) {
				st.setCaretOffset(offset);
				st.setSelection(offset);
			}

			Point newCaret = st.getLocationAtOffset(offset);
			if (newCaret.equals(caret))
				return;

			Caret ct = st.getCaret();
			Point size = ct.getSize();

			GC gc = new GC(st);
			gc.setLineWidth(size.x);

			// erase old caret
			if (caret != null) {
				Color originalForeground = gc.getForeground();
				gc.setForeground(st.getBackground());
				gc.drawRectangle(caret.x, caret.y, size.x, size.y);
				gc.setForeground(originalForeground);
			}

			st.redraw();
			st.update();

			// draw new caret
			caret = newCaret;
			if (ct.getImage() != null)
				gc.drawImage(ct.getImage(), caret.x, caret.y);
			else {
				gc.drawLine(caret.x, caret.y, caret.x, caret.y + size.y);
			}

			gc.dispose();
		}
	}

	/**
	 */
	public void drop(DropTargetEvent event) {
		if (event.operations == DND.DROP_NONE)
			return;

		if (textViewer != null) {
			Point pt = toControl(new Point(event.x, event.y));
			StyledText st = textViewer.getTextWidget();

			int offset = getDropOffset(st, pt);
			if (offset != st.getCaretOffset()) {
				st.setCaretOffset(offset);
			}

			// ISelectionProvider sp = textViewer.getSelectionProvider();
			// ISelection sel = new TextSelection(offset, 0);
			// sp.setSelection(sel);
			// BUG145392 - need to account for folded regions
			if (textViewer instanceof ITextViewerExtension5) {
				offset = ((ITextViewerExtension5) textViewer).widgetOffset2ModelOffset(offset);
			}
			textViewer.setSelectedRange(offset, 0);
		}

		Transfer[] ts = getTransfers();
		for (int i = 0; i < ts.length; i++) {
			if (ts[i].isSupportedType(event.currentDataType)) {
				if (doDrop(ts[i], event)) {
					break;
				}
			}
		}
	}

	protected int getDropOffset(DropTargetEvent event) {
		Point pt = getTextViewer().getTextWidget().toControl(new Point(event.x, event.y));
		StyledText st = textViewer.getTextWidget();
		return getDropOffset(st, pt);
	}

	private int getDropOffset(StyledText st, Point pt) {
		int offset = st.getCaretOffset();
		try {
			offset = st.getOffsetAtLocation(pt);
		}
		catch (IllegalArgumentException e) {
			// This is normal case if mouse cursor is on outside of valid
			// text.
			boolean found = false;
			Point p = new Point((pt.x > 0 ? pt.x : 0), pt.y);
			// search nearest character
			for (; p.x > -1; p.x--) {
				try {
					offset = st.getOffsetAtLocation(p);

					/*
					 * Now that a valid offset has been found, try to place at
					 * the end of the line
					 */
					/*
					 * partial line folding invalidates any "move to EOL"
					 * action we might take
					 */
					// if (textViewer != null && textViewer.getDocument() !=
					// null) {
					// IRegion lineInfo = null;
					// try {
					// if (textViewer instanceof ITextViewerExtension5) {
					// lineInfo =
					// textViewer.getDocument().getLineInformationOfOffset(((ITextViewerExtension5)textViewer).widgetOffset2ModelOffset(offset));
					// }
					// else {
					// lineInfo =
					// textViewer.getDocument().getLineInformationOfOffset(offset);
					// }
					// } catch (BadLocationException e1) {
					// }
					// if (lineInfo != null)
					// offset = lineInfo.getOffset() + lineInfo.getLength();
					// }
					found = true;
					break;
				}
				catch (IllegalArgumentException ex) {
				}
			}

			if (!found) {
				offset = st.getCharCount();
			}
		}
		return offset;
	}

	public IEditorPart getTargetEditor() {
		return targetEditor;
	}

	public ITextViewer getTextViewer() {
		return textViewer;
	}

	/**
	 * @return org.eclipse.swt.dnd.Transfer[]
	 */
	public Transfer[] getTransfers() {
		if (transfers == null) {
			TransferBuilder tb = new TransferBuilder(useProxy);
			if (editorIds == null || editorIds.length == 0)
				transfers = tb.getDropTargetTransfers(getTargetEditor().getClass().getName());
			else
				transfers = tb.getDropTargetTransfers(editorIds);
		}
		return transfers;
	}

	/**
	 */
	public void setTargetEditor(IEditorPart targetEditor) {
		this.targetEditor = targetEditor;
	}

	public void setTargetIDs(String[] ids) {
		editorIds = ids;
	}

	public void setTextViewer(ITextViewer textViewer) {
		this.textViewer = textViewer;
	}

	private Point toControl(Point point) {
		return (textViewer != null ? textViewer.getTextWidget().toControl(point) : point);
	}
}
