/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.dnd.internal;

import org.eclipse.gef.SharedCursors;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
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.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * This class will 1. determine it's insertion or update 2. call validator
 * corresponding helper to resolve it.
 * 
 * @author mengbo
 */
public class SourceViewerDragDropHelper {
	private static SourceViewerDragDropHelper _instance;

	public static SourceViewerDragDropHelper getInstance() {
		if (_instance == null) {
			_instance = new SourceViewerDragDropHelper();
		}
		return _instance;
	}

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

	private int getDropOffset(StructuredTextEditor ste, Point pt) {
		StyledText st = ste.getTextViewer().getTextWidget();
		int offset = st.getCaretOffset();
		try {
			offset = st.getOffsetAtLocation(pt);
		} catch (IllegalArgumentException e) {
			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
					 */
					if (ste.getTextViewer() != null
							&& ste.getTextViewer().getDocument() != null) {
						IRegion lineInfo = null;
						try {
							lineInfo = ste.getTextViewer().getDocument()
									.getLineInformationOfOffset(offset);
						} catch (BadLocationException e1) {
                            // ignore exception and fall-through with lineInfo == null
						}
						if (lineInfo != null)
							offset = lineInfo.getOffset()
									+ lineInfo.getLength();
					}

					found = true;
					break;
				} catch (IllegalArgumentException ex) {
					// for trying location, no need to catch.
				}
			}
			if (!found) {
				offset = st.getCharCount();
			}
		}
		return offset;
	}

	public void updateCaret(StructuredTextEditor textEditor, Point location,
			Point caret) {
		TextViewer textViewer = textEditor.getTextViewer();
		if (textViewer != null) {
			Point pt = toControl(textViewer, location);
			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(textEditor, 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.setXORMode(true);
			gc.setLineWidth(size.x);

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

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

			// draw new caret
			if (caret == null) {
				caret = newCaret;
			} else {
				caret.x = newCaret.x;
				caret.y = newCaret.y;
			}
			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 updateCaret(StructuredTextEditor textEditor, Point location) {
		TextViewer textViewer = textEditor.getTextViewer();
		if (textViewer != null) {
			Point pt = toControl(textViewer, location);
			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(textEditor, pt);
			if (offset != st.getCaretOffset()) {
				st.setCaretOffset(offset);
				st.setSelection(offset);
			}
		}
	}

	public int showCaret(StructuredTextEditor textEditor, int location) {
		StyledText text = textEditor.getTextViewer().getTextWidget();
		text.setCursor(SharedCursors.CURSOR_TREE_ADD);
		text.setCaretOffset(location);
		if (!text.isFocusControl()) {
			text.setFocus();
		}
		return text.getCaretOffset();
	}

	protected ModelQuery getModelQuery(Node node) {
		if (node.getNodeType() == Node.DOCUMENT_NODE) {
			return ModelQueryUtil.getModelQuery((Document) node);
		}
        return ModelQueryUtil.getModelQuery(node.getOwnerDocument());
	}

	public IDOMPosition findPosition(int caretPos, Node element) {
		EditValidateUtil.validNode(element);
		IDOMPosition position = EditModelQuery.getInstance().createDomposition(
				((IDOMNode) element).getModel(), caretPos, false);
		return position;
	}

	public void format(TextViewer viewer, Node node) {
		if (node == null) {
			return;
		}
		Node tmp;
		int start, offset;
		if (node.getPreviousSibling() != null) {
			tmp = node.getPreviousSibling();
			start = ((IndexedRegion) tmp).getEndOffset();
		} else {
			tmp = node;
			start = ((IndexedRegion) tmp).getStartOffset();
		}
		if (node.getNextSibling() != null) {
			tmp = node.getNextSibling();
			offset = ((IndexedRegion) tmp).getStartOffset() - start;
		} else {
			tmp = node;
			offset = ((IndexedRegion) tmp).getEndOffset() - start;
		}
		viewer.setSelectedRange(start, offset);
		viewer.doOperation(ISourceViewer.FORMAT);
	}

	public void changeCaret(StructuredTextEditor textEditor, boolean reset) {
		if (reset) {
			StyledText text = textEditor.getTextViewer().getTextWidget();
			text.setCursor(new Cursor(null, SWT.CURSOR_IBEAM));
		}
	}

	public int getValidLocation(StructuredTextEditor textEditor,
			int locationOffset) {
		Node node = getCaretNode(textEditor, locationOffset);
		if (node == null) {
			// empty page?
			return 0;
		}
		if (node.getNodeType() == Node.TEXT_NODE) {
			return locationOffset;
		}
		return calculateCaretLocation(node, locationOffset);
	}

	public int getOffset(StructuredTextEditor textEditor, Point location) {
		StyledText text = textEditor.getTextViewer().getTextWidget();
		return text.getOffsetAtLocation(location);
	}

	// private IStructuredModel getModel(StructuredTextEditor textEditor)
	// {
	// IStructuredModel model = null;
	// if (textEditor.getDocumentProvider() != null)
	// {
	// if (textEditor.getDocumentProvider() instanceof IModelProvider)
	// {
	// model = ((IModelProvider)
	// textEditor.getDocumentProvider()).getModel(textEditor.getEditorInput());
	// }
	// else
	// {
	// IDocument doc =
	// textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
	// if (doc instanceof IDocument)
	// {
	// model =
	// StructuredModelManager.getModelManager().getExistingModelForEdit(doc);
	// if (model == null)
	// {
	// model =
	// StructuredModelManager.getModelManager().getExistingModelForEdit((IDocument)
	// doc);
	// }
	// }
	// }
	// }
	// return model;
	// }

	/**
	 * IExtendedMarkupEditor method
	 */
	public Node getCaretNode(StructuredTextEditor textEditor, int pos) {
        // TODO: getModel is deprecated
		IStructuredModel model = textEditor.getModel();
		// getModel(textEditor);
		if (model == null) {
			return null;
		}
		IndexedRegion inode = model.getIndexedRegion(pos);
		if (inode == null) {
			inode = model.getIndexedRegion(pos - 1);
		}
		return (inode instanceof Node) ? (Node) inode : null;
	}

	/**
	 * Calculate and adjust the location in compare with Node.
	 * 
	 * @param node
	 * @param location
	 * @return
	 */
	public int calculateCaretLocation(Node node, int location) {
		int pos[][] = new int[2][2];
		pos[0][0] = EditModelQuery.getNodeStartIndex(node);
		pos[0][1] = EditModelQuery.getNodeStartNameEndIndex(node);
		pos[1][0] = EditModelQuery.getNodeEndNameStartIndex(node);
		pos[1][1] = EditModelQuery.getNodeEndIndex(node);
		if (pos[0][0] >= location || pos[1][0] == location
				|| pos[1][1] <= location) {
			return location;
		} else if (pos[0][0] <= location && pos[0][1] >= location) {
			if (((pos[0][1] + pos[0][0]) / 2) >= location) {
				return pos[0][0];
			}
            return pos[0][1];
		} else if (pos[1][0] <= location && pos[1][1] >= location) {
			if (((pos[1][1] + pos[1][0]) / 2) >= location) {
				return pos[1][0];
			}
            return pos[1][1];
		}
		return location;
	}
}
