/*******************************************************************************
 * 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;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.texteditor.MarkerAnnotation;
import org.eclipse.wst.sse.core.util.StringUtils;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.StructuredTextLineBreakingReader;

public class StructuredTextAnnotationHover implements IAnnotationHover, IReleasable {

	/**
	 * Provides a set of convenience methods for creating HTML pages. Taken
	 * from org.eclipse.jdt.internal.ui.text.HTMLPrinter
	 */
	protected class HTMLPrinter {

		public HTMLPrinter() {
		}

		public void addBullet(StringBuffer buffer, String bullet) {
			if (bullet != null) {
				buffer.append("<li>"); //$NON-NLS-1$
				buffer.append(bullet);
				buffer.append("</li>"); //$NON-NLS-1$
			}
		}

		public void addPageEpilog(StringBuffer buffer) {
			buffer.append("</font></body></html>"); //$NON-NLS-1$
		}

		public void addPageProlog(StringBuffer buffer) {
			insertPageProlog(buffer, buffer.length());
		}

		public void addParagraph(StringBuffer buffer, Reader paragraphReader) {
			if (paragraphReader != null)
				addParagraph(buffer, read(paragraphReader));
		}

		public void addParagraph(StringBuffer buffer, String paragraph) {
			if (paragraph != null) {
				buffer.append("<p>"); //$NON-NLS-1$
				buffer.append(paragraph);
			}
		}

		public void addSmallHeader(StringBuffer buffer, String header) {
			if (header != null) {
				buffer.append("<h5>"); //$NON-NLS-1$
				buffer.append(header);
				buffer.append("</h5>"); //$NON-NLS-1$
			}
		}

		public String convertToHTMLContent(String content) {
			content = replace(content, '<', "&lt;"); //$NON-NLS-1$
			return replace(content, '>', "&gt;"); //$NON-NLS-1$
		}

		public void endBulletList(StringBuffer buffer) {
			buffer.append("</ul>"); //$NON-NLS-1$
		}

		public void insertPageProlog(StringBuffer buffer, int position) {
			buffer.insert(position, "<html><body text=\"#000000\" bgcolor=\"#FFFF88\"><font size=-1>"); //$NON-NLS-1$
		}

		public String read(Reader rd) {

			StringBuffer buffer = new StringBuffer();
			char[] readBuffer = new char[2048];

			try {
				int n = rd.read(readBuffer);
				while (n > 0) {
					buffer.append(readBuffer, 0, n);
					n = rd.read(readBuffer);
				}
				return buffer.toString();
			} catch (IOException x) {
			}

			return null;
		}

		private String replace(String text, char c, String s) {

			int previous = 0;
			int current = text.indexOf(c, previous);

			if (current == -1)
				return text;

			StringBuffer buffer = new StringBuffer();
			while (current > -1) {
				buffer.append(text.substring(previous, current));
				buffer.append(s);
				previous = current + 1;
				current = text.indexOf(c, previous);
			}
			buffer.append(text.substring(previous));

			return buffer.toString();
		}

		public void startBulletList(StringBuffer buffer) {
			buffer.append("<ul>"); //$NON-NLS-1$
		}
	}

	private IDebugModelPresentation fDebugModelPresentation;

	protected HTMLPrinter printer = new HTMLPrinter();

	/**
	 * Returns the distance to the ruler line.
	 */
	protected int compareRulerLine(Position position, IDocument document, int line) {

		if (position.getOffset() > -1 && position.getLength() > -1) {
			try {
				int markerLine = document.getLineOfOffset(position.getOffset());
				if (line == markerLine)
					return 1;
				if (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()))
					return 2;
			} catch (BadLocationException x) {
			}
		}

		return 0;
	}

	/*
	 * Formats the message of this hover to fit onto the screen.
	 */
	private String formatHoverText(String text, ISourceViewer sourceViewer) {
		String lineDelim = new String();
		try {
			lineDelim = sourceViewer.getDocument().getLineDelimiter(0);
		} catch (org.eclipse.jface.text.BadLocationException exception) {
			// skip, just use default
		}
		Display display = sourceViewer.getTextWidget().getDisplay();

		// replace special characters in text with html entity (like <, >, &
		// to &lt;, &gt;, &&;)
		text = StringUtils.convertToHTMLContent(text);

		Reader textReader = new StringReader(text);
		GC gc = new GC(display);
		try {
			StringBuffer buf = new StringBuffer();

			StructuredTextLineBreakingReader reader = new StructuredTextLineBreakingReader(textReader, gc, getHoverWidth(display));
			String line = reader.readLine();
			while (line != null) {
				if (buf.length() != 0) {
					buf.append(lineDelim);
				}
				buf.append(line);
				line = reader.readLine();
			}
			return buf.toString();
		} catch (IOException exception) {
			throw new org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException(exception);
		} finally {
			gc.dispose();
		}
	}

	/*
	 * Formats several message as HTML text.
	 */
	private String formatMultipleHoverText(List messages) {

		StringBuffer buffer = new StringBuffer();
		printer.addPageProlog(buffer);
		printer.addParagraph(buffer, SSEUIPlugin.getResourceString("%Multiple_errors")); //$NON-NLS-1$

		printer.startBulletList(buffer);
		Iterator e = messages.iterator();
		while (e.hasNext())
			printer.addBullet(buffer, printer.convertToHTMLContent((String) e.next()));
		printer.endBulletList(buffer);

		printer.addPageEpilog(buffer);
		return buffer.toString();
	}

	/**
	 * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
	 */
	public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
		IMarker marker = getMarker(sourceViewer, lineNumber);
		List messages = new ArrayList(marker == null ? 0 : 1);
		if (marker != null) {
			String text = marker.getAttribute(IMarker.MESSAGE, (String) null);
			if (text != null) {
				messages.add(text);
			} else {
				try {
					if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
						IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
						IBreakpoint[] breakpoints = manager.getBreakpoints();
						for (int i = 0; i < breakpoints.length; i++) {
							IBreakpoint breakpoint = breakpoints[i];
							if (breakpoint.getMarker().equals(marker)) {
								if (fDebugModelPresentation == null) {
									fDebugModelPresentation = DebugUITools.newDebugModelPresentation();
								}
								text = fDebugModelPresentation.getText(breakpoint);
								if (text != null) {
									messages.add(text);
								}
							}
						}
					}
				} catch (CoreException e) {
					Logger.logException(e);
				}
			}
		}
		List temporaryAnnotations = getTemporaryAnnotationsForLine(sourceViewer, lineNumber);
		for (int i = 0; i < temporaryAnnotations.size(); i++) {
			String message = ((Annotation) temporaryAnnotations.get(i)).getText();
			if (message != null) {
				boolean duplicated = false;
				for (int j = 0; j < messages.size(); j++)
					duplicated = duplicated || messages.get(j).equals(message);
				if (!duplicated)
					messages.add(message);
				//				else
				//					System.out.println("duplicated message found: " +
				// StringUtils.escape(message));
			} else
				messages.add(((ITemporaryAnnotation) temporaryAnnotations.get(i)).toString());
		}
		if (messages.size() > 1)
			return formatMultipleHoverText(messages);
		else if (messages.size() > 0)
			return formatHoverText(messages.get(0).toString(), sourceViewer);
		else
			return null;
	}

	private int getHoverWidth(Display display) {
		Rectangle displayBounds = display.getBounds();
		int hoverWidth = displayBounds.width - (display.getCursorLocation().x - displayBounds.x);
		hoverWidth -= 12; // XXX: Add some space to the border, Revisit
		if (hoverWidth < 200) {
			hoverWidth = 200;
		}
		return hoverWidth;
	}

	/**
	 * Returns one marker which includes the ruler's line of activity.
	 */
	protected IMarker getMarker(ISourceViewer viewer, int line) {

		IDocument document = viewer.getDocument();
		IAnnotationModel model = viewer.getAnnotationModel();

		if (model == null)
			return null;

		List exact = new ArrayList();
		List including = new ArrayList();

		Iterator e = model.getAnnotationIterator();
		while (e.hasNext()) {
			Object o = e.next();
			if (o instanceof MarkerAnnotation) {
				MarkerAnnotation a = (MarkerAnnotation) o;
				switch (compareRulerLine(model.getPosition(a), document, line)) {
					case 1 :
						exact.add(a.getMarker());
						break;
					case 2 :
						including.add(a.getMarker());
						break;
				}
			}
		}

		return select(exact, including);
	}

	/**
	 * Returns one marker which includes the ruler's line of activity.
	 */
	protected List getTemporaryAnnotationsForLine(ISourceViewer viewer, int line) {

		IDocument document = viewer.getDocument();
		IAnnotationModel model = viewer.getAnnotationModel();

		if (model == null)
			return null;

		List exact = new ArrayList();
		List including = new ArrayList();

		Iterator e = model.getAnnotationIterator();
		while (e.hasNext()) {
			Object o = e.next();
			if (o instanceof ITemporaryAnnotation) {
				ITemporaryAnnotation a = (ITemporaryAnnotation) o;
				Position position = model.getPosition((Annotation) a);
				if (position == null)
					continue;

				switch (compareRulerLine(position, document, line)) {
					case 1 :
						exact.add(a);
						break;
					case 2 :
						including.add(a);
						break;
				}
			}
		}

		return exact;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.ui.IReleasable#release()
	 */
	public void release() {
		if (fDebugModelPresentation != null) {
			fDebugModelPresentation.dispose();
		}
	}

	/**
	 * Selects one marker from the two lists.
	 */
	protected IMarker select(List firstChoice, List secondChoice) {
		if (!firstChoice.isEmpty())
			return (IMarker) firstChoice.get(0);
		if (!secondChoice.isEmpty())
			return (IMarker) secondChoice.get(0);
		return null;
	}
}
