/*******************************************************************************
 * Copyright (c) 2005 The Regents of the University of California. 
 * This material was produced under U.S. Government contract W-7405-ENG-36 
 * for Los Alamos National Laboratory, which is operated by the University 
 * of California for the U.S. Department of Energy. The U.S. Government has 
 * rights to use, reproduce, and distribute this software. NEITHER THE 
 * GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR 
 * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified 
 * to produce derivative works, such modified software should be clearly marked, 
 * so as not to confuse it with the version available from LANL.
 * 
 * Additionally, 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
 * 
 * LA-CC 04-115
 *******************************************************************************/
package org.eclipse.ptp.internal.ui.hover;

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

import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.ptp.ui.PTPUIPlugin;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
/**
 * @author Clement chu
 */
public class IconHoverPresenter implements DefaultInformationControl.IInformationPresenter {
	private static final String LINE_DELIM = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
	//private static final String LINE_INDENTATION = "  ";
	private int fCounter;
	private boolean fEnforceUpperLineLimit;
	/**
	 * Constructor
	 * 
	 * @param enforceUpperLineLimit
	 */
	public IconHoverPresenter(boolean enforceUpperLineLimit) {
		super();
		fEnforceUpperLineLimit = enforceUpperLineLimit;
	}
	/**
	 * Constructor
	 */
	public IconHoverPresenter() {
		this(true);
	}
	/**
	 * Create Reader
	 * 
	 * @param hoverInfo
	 * @param presentation
	 * @return
	 */
	protected Reader createReader(String hoverInfo, TextPresentation presentation) {
		return new IconTextReader(new StringReader(hoverInfo), presentation);
	}
	/**
	 * Adpat text presentation
	 * 
	 * @param presentation
	 * @param offset
	 * @param insertLength
	 */
	protected void adaptTextPresentation(TextPresentation presentation, int offset, int insertLength) {
		int yoursStart = offset;
		int yoursEnd = offset + insertLength - 1;
		yoursEnd = Math.max(yoursStart, yoursEnd);
		Iterator e = presentation.getAllStyleRangeIterator();
		while (e.hasNext()) {
			StyleRange range = (StyleRange) e.next();
			int myStart = range.start;
			int myEnd = range.start + range.length - 1;
			myEnd = Math.max(myStart, myEnd);
			if (myEnd < yoursStart)
				continue;
			if (myStart < yoursStart)
				range.length += insertLength;
			else
				range.start += insertLength;
		}
	}
	/**
	 * Append text
	 * 
	 * @param buffer
	 * @param string
	 * @param presentation
	 */
	private void append(StringBuffer buffer, String string, TextPresentation presentation) {
		int length = string.length();
		buffer.append(string);
		if (presentation != null) {
			adaptTextPresentation(presentation, fCounter, length);
		}
		fCounter += length;
	}
	/**
	 * Get indentation
	 * 
	 * @param line
	 * @return
	 */
	/*
	private String getIndent(String line) {
		int length = line.length();
		int i = 0;
		while (i < length && Character.isWhitespace(line.charAt(i)))
			++i;
		return (i == length ? line : line.substring(0, i)) + LINE_INDENTATION;
	}
	*/
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ptp.internal.ui.hover.DefaultInformationControl.IInformationPresenter#updatePresentation(org.eclipse.swt.widgets.Display, java.lang.String, org.eclipse.jface.text.TextPresentation, int, int)
	 */
	public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
		if (hoverInfo == null)
			return null;
		GC gc = new GC(display);
		try {
			StringBuffer buffer = new StringBuffer();
			int maxNumberOfLines = Math.round(maxHeight / gc.getFontMetrics().getHeight());
			fCounter = 0;
			LineBreakingReader reader = new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth);
			String line = reader.readLine();
			while (line != null) {
				if (fEnforceUpperLineLimit && maxNumberOfLines <= 0)
					break;

				append(buffer, line, null);
				append(buffer, LINE_DELIM, reader.isFormattedLine()?presentation:null);
				line = reader.readLine();
				maxNumberOfLines--;
			}
			// display "..." if the content is over the shell size
			if (line != null && buffer.length() > 0) {
				append(buffer, LINE_DELIM, null);
				append(buffer, "...", null); //$NON-NLS-1$
			}
			return trim(buffer, presentation);
		} catch (IOException e) {
			PTPUIPlugin.log(e);
			return null;
		} finally {
			gc.dispose();
		}
	}
	/**
	 * implemented another method to replace orginial 
	public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
		if (hoverInfo == null)
			return null;
		GC gc = new GC(display);
		try {
			StringBuffer buffer = new StringBuffer();
			int maxNumberOfLines = Math.round(maxHeight / gc.getFontMetrics().getHeight());
			fCounter = 0;
			LineBreakingReader reader = new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth);
			boolean lastLineFormatted = false;
			String lastLineIndent = null;
			String line = reader.readLine(lastLineIndent);
			boolean lineFormatted = reader.isFormattedLine();
			boolean firstLineProcessed = false;
			while (line != null) {
				if (fEnforceUpperLineLimit && maxNumberOfLines <= 0)
					break;
				if (firstLineProcessed) {
					if (!lastLineFormatted)
						append(buffer, LINE_DELIM, null);
					else {
						append(buffer, LINE_DELIM, presentation);
						if (lastLineIndent != null)
							append(buffer, lastLineIndent, presentation);
					}
				}
				append(buffer, line, null);
				firstLineProcessed = true;
				lastLineFormatted = lineFormatted;
				if (!lineFormatted)
					lastLineIndent = null;
				else if (lastLineIndent == null)
					lastLineIndent = getIndent(line);
				line = reader.readLine(lastLineIndent);
				lineFormatted = reader.isFormattedLine();
				maxNumberOfLines--;
			}
			// display "..." if the content is over the shell size
			if (line != null && buffer.length() > 0) {
				append(buffer, LINE_DELIM, lineFormatted ? presentation : null);
				append(buffer, "...", presentation);
			}
			return trim(buffer, presentation);
		} catch (IOException e) {
			PTPUIPlugin.log(e);
			return null;
		} finally {
			gc.dispose();
		}
	}
	 * 
	 */
	
	/**
	 * Trim given buffer
	 * 
	 * @param buffer
	 * @param presentation
	 * @return
	 */
	private String trim(StringBuffer buffer, TextPresentation presentation) {
		int length = buffer.length();
		int end = length - 1;
		while (end >= 0 && Character.isWhitespace(buffer.charAt(end)))
			--end;
		if (end == -1)
			return ""; //$NON-NLS-1$
		if (end < length - 1)
			buffer.delete(end + 1, length);
		else
			end = length;
		int start = 0;
		while (start < end && Character.isWhitespace(buffer.charAt(start)))
			++start;
		buffer.delete(0, start);
		presentation.setResultWindow(new Region(start, buffer.length()));
		return buffer.toString();
	}
}
