/*******************************************************************************
 * Copyright (c) 2001, 2007 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.xml.ui.internal.dnd;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.wst.common.ui.internal.dnd.DefaultDragAndDropCommand;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.ui.internal.Logger;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class DragNodeCommand extends DefaultDragAndDropCommand {
	private List fSelections;
	private TreeViewer fTreeViewer;

	public DragNodeCommand(Object target, float location, int operations, int operation, Collection sources, TreeViewer treeViewer) {
		super(target, location, operations, operation, sources);
		fTreeViewer = treeViewer;
		fSelections = new ArrayList();
	}

	private void beginModelChange(Node node, boolean batchUpdate) {
		IStructuredModel structuredModel = getStructuredModel(node);
		if (structuredModel != null) {
			String undoDesc = new String();
			if (getOperation() == DND.DROP_MOVE) {
				undoDesc = XMLUIMessages.DragNodeCommand_0;
			}
			else if (getOperation() == DND.DROP_COPY) {
				undoDesc = XMLUIMessages.DragNodeCommand_1;
			}

			structuredModel.beginRecording(this, undoDesc);
			if (batchUpdate) {
				// structuredModel.aboutToChangeModel();
			}
		}
	}

	public boolean canExecute() {
		return executeHelper(true);
	}

	private boolean doModify(Node source, Node parentNode, Node refChild, boolean testOnly) {
		boolean result = false;
		if (source.getNodeType() == Node.ATTRIBUTE_NODE) {
			Attr sourceAttribute = (Attr) source;
			Element sourceAttributeOwnerElement = sourceAttribute.getOwnerElement();
			if ((parentNode.getNodeType() == Node.ELEMENT_NODE) && (sourceAttributeOwnerElement != parentNode)) {
				result = true;
				if (!testOnly) {
					try {
						if (getOperation() == DND.DROP_MOVE) {
							Element targetElement = (Element) parentNode;
							sourceAttributeOwnerElement.removeAttributeNode(sourceAttribute);
							targetElement.getAttributes().setNamedItem(sourceAttribute);
							fSelections.add(sourceAttribute);
							}
						else if (getOperation() == DND.DROP_COPY) {
							Attr cloneAttribute = (Attr) sourceAttribute.cloneNode(false);
							Element targetElement = (Element) parentNode;
							targetElement.getAttributes().setNamedItem(cloneAttribute);
							fSelections.add(cloneAttribute);
						}
					}
					catch (Exception e) {
						Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
					}
				}
			}
		}
		else {
			if (((parentNode.getNodeType() == Node.ELEMENT_NODE) || (parentNode.getNodeType() == Node.DOCUMENT_NODE)) && !(refChild instanceof Attr)) {
				result = true;

				if (!testOnly) {
					try {
						if (isAncestor(source, parentNode)) {
							// System.out.println("can not perform this drag drop
							// operation.... todo... pop up dialog");
						}
						else {
							// defect 221055 this test is required or else the
							// node will
							// be removed from the tree and the insert will fail
							if (source != refChild) {
								if (getOperation() == DND.DROP_MOVE) {
									Node oldParent = source.getParentNode();
									Node oldSibling = source.getNextSibling();
									oldParent.removeChild(source);
									try {
										parentNode.insertBefore(source, refChild);
									} catch (DOMException e) {
										// bug151692 - if unable to move node to new location, reinsert back to old location
										oldParent.insertBefore(source, oldSibling);
									}
									fSelections.add(source);
								}
								else if (getOperation() == DND.DROP_COPY) {
									Node nodeClone = source.cloneNode(true);
									parentNode.insertBefore(nodeClone, refChild);
									fSelections.add(nodeClone);
								}
							}
						}
					}
					catch (Exception e) {
						Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
					}
				}
			}
		}
		return result;
	}

	private void endModelChange(Node node, boolean batchUpdate) {
		IStructuredModel structuredModel = getStructuredModel(node);
		if (structuredModel != null) {
			structuredModel.endRecording(this);
			if (batchUpdate) {
				// structuredModel.changedModel();
			}
		}
	}

	public void execute() {
		executeHelper(false);

		// Make our selection if the treeViewer != null
		if (fTreeViewer != null) {
			StructuredSelection structuredSelection = new StructuredSelection(fSelections);
			fTreeViewer.setSelection(structuredSelection);
		}
	}

	private boolean executeHelper(boolean testOnly) {
		boolean result = true;
		if (target instanceof Node) {
			Node targetNode = (Node) target;
			Node parentNode = getParentForDropPosition(targetNode);
			Node refChild = getRefChild(targetNode);

			Vector sourcesList = new Vector();
			sourcesList.addAll(sources);

			removeMemberDescendants(sourcesList);
			boolean performBatchUpdate = sourcesList.size() > 5;

			if (!testOnly) {
				beginModelChange(targetNode, performBatchUpdate);
			}
			for (Iterator i = sourcesList.iterator(); i.hasNext();) {
				Object source = i.next();
				if (source instanceof Node) {
					if (!((refChild == null) && (targetNode instanceof Attr))) {
						result = doModify((Node) source, parentNode, refChild, testOnly);
					}
					else {
						result = false;
					}
					if (!result) {
						break;
					}
				}
			}
			if (!testOnly) {
				endModelChange(targetNode, performBatchUpdate);
			}
		}
		else {
			result = false;
		}
		return result;
	}


	public int getFeedback() {
		int result = DND.FEEDBACK_SELECT;
		if (location > 0.75) {
			result = DND.FEEDBACK_INSERT_AFTER;
		}
		else if (location < 0.25) {
			result = DND.FEEDBACK_INSERT_BEFORE;
		}
		return result;
	}

	private Node getParentForDropPosition(Node node) {
		Node result = null;

		int feedback = getFeedback();
		if (feedback == DND.FEEDBACK_SELECT) {
			result = node;
		}
		else {
			result = getParentOrOwner(node);
		}
		return result;
	}


	private Node getParentOrOwner(Node node) {
		return (node.getNodeType() == Node.ATTRIBUTE_NODE) ? ((Attr) node).getOwnerElement() : node.getParentNode();
	}


	private Node getRefChild(Node node) {
		Node result = null;

		int feedback = getFeedback();

		if (feedback == DND.FEEDBACK_INSERT_BEFORE) {
			result = node;
		}
		else if (feedback == DND.FEEDBACK_INSERT_AFTER) {
			result = node.getNextSibling();
		}
		return result;
	}

	private IStructuredModel getStructuredModel(Node node) {
		IStructuredModel result = null;
		if (node instanceof IDOMNode) {
			result = ((IDOMNode) node).getModel();
		}
		return result;
	}

	// returns true if a is an ancestore of b
	//
	private boolean isAncestor(Node a, Node b) {
		boolean result = false;
		for (Node parent = b; parent != null; parent = parent.getParentNode()) {
			if (parent == a) {
				result = true;
				break;
			}
		}
		return result;
	}


	/**
	 * This method removes members of the list that have ancestors that are
	 * also members of the list.
	 */
	private void removeMemberDescendants(List list) {
		Hashtable table = new Hashtable();
		for (Iterator i = list.iterator(); i.hasNext();) {
			Object node = i.next();
			table.put(node, node);
		}

		for (int i = list.size() - 1; i >= 0; i--) {
			Node node = (Node) list.get(i);
			for (Node parent = getParentOrOwner(node); parent != null; parent = getParentOrOwner(parent)) {
				if (table.get(parent) != null) {
					list.remove(i);
					break;
				}
			}
		}
	}
}
