/*******************************************************************************
 * 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.PushbackReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.ptp.ui.hover.IIconHoverTag;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;

/**
 * @author Clement chu
 * 
 */
public class IconTextReader extends SubstitutionTextReader {
	private static final String EMPTY_STRING= "";
	private static final Map<String, String> fgEntityLookup;
	private static final Set<String> fgTags;
	
	private Color red_color = Display.getDefault().getSystemColor(SWT.COLOR_RED);
	private Color green_color = Display.getDefault().getSystemColor(SWT.COLOR_GREEN);

	static {
		fgTags= new HashSet<String>();
		fgTags.add(IIconHoverTag.UNDERLINE_TAG);
		fgTags.add(IIconHoverTag.STRIKE_TAG);
		fgTags.add(IIconHoverTag.BOLD_TAG);
		fgTags.add(IIconHoverTag.ITALIC_TAG);
		fgTags.add(IIconHoverTag.P_TAG);
		fgTags.add(IIconHoverTag.KEY_TAG);
		fgTags.add(IIconHoverTag.HIGHLIGHT_TAG);
		fgTags.add(IIconHoverTag.NEXT_LINE_TAG);
		fgTags.add(IIconHoverTag.INDENT_TAG);

		fgEntityLookup= new HashMap<String, String>(7);
		fgEntityLookup.put("lt", "<");
		fgEntityLookup.put("gt", ">");
		fgEntityLookup.put("nbsp", " ");
		fgEntityLookup.put("amp", "&");
		fgEntityLookup.put("circ", "^");
		fgEntityLookup.put("tilde", "~");
		fgEntityLookup.put("quot", "\"");		
	}

	private int fCounter= 0;
	private TextPresentation fTextPresentation;
	private int fStrike= 0;
	private int fUnderline= 0;
	private int fBold= 0;
	private int fItalic= 0;
	private int fKey= 0;
	private int fHighlight = 0;
	private int fStartOffset= -1;
	private boolean fInParagraph= false;

	/** Constructor
	 * @param reader
	 * @param presentation
	 */
	public IconTextReader(Reader reader, TextPresentation presentation) {
		super(new PushbackReader(reader));
		fTextPresentation= presentation;
	}
	/* (non-Javadoc)
	 * @see java.io.Reader#read()
	 */
	public int read() throws IOException {
		int c= super.read();
		if (c != -1)
			++ fCounter;
		return c;
	}
	/** Start bold
	 * 
	 */
	protected void startBold() {
		if (fBold == 0)
			fStartOffset= fCounter;
		++ fBold;
	}
	/** Stop bold
	 * 
	 */
	protected void stopBold() {
		-- fBold;
		if (fBold == 0) {
			fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.BOLD));
			fStartOffset= -1;
		}
	}

	/** start underline
	 * 
	 */
	protected void startUnderLine() {
		if (fUnderline == 0)
			fStartOffset= fCounter;
		++ fUnderline;
	}
	/** stop underline
	 * 
	 */
	protected void stopUnderLine() {
		-- fUnderline;
		if (fUnderline == 0) {
			StyleRange styleRange = new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.NORMAL);
			styleRange.underline = true;
			fTextPresentation.addStyleRange(styleRange);
			fStartOffset= -1;
		}
	}

	/** start strike
	 * 
	 */
	protected void startStrike() {
		if (fStrike == 0)
			fStartOffset= fCounter;
		++ fStrike;
	}
	/** stop strike
	 * 
	 */
	protected void stopStrike() {
		-- fStrike;
		if (fStrike == 0) {
			StyleRange styleRange = new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.NORMAL);
			styleRange.strikeout = true;
			fTextPresentation.addStyleRange(styleRange);
			fStartOffset= -1;
		}
	}
	
	/** start italic
	 * 
	 */
	protected void startItalic() {
		if (fItalic == 0)
			fStartOffset= fCounter;
		++ fItalic;
	}
	/** stop italic
	 * 
	 */
	protected void stopItalic() {
		-- fItalic;
		if (fItalic == 0) {
			fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, SWT.ITALIC));
			fStartOffset= -1;
		}
	}
	
	/** start key
	 * 
	 */
	protected void startKey() {
		if (fKey == 0)
			fStartOffset= fCounter;
		++ fKey;
	}
	/** stop key
	 * 
	 */
	protected void stopKey() {
		-- fKey;
		if (fKey == 0) {
			fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, red_color, null, SWT.NORMAL));
			fStartOffset= -1;
		}
	}

	/** start highlight
	 * 
	 */
	protected void startHighlight() {
		if (fHighlight == 0)
			fStartOffset= fCounter;
		++ fHighlight;
	}
	/** stop highlight
	 * 
	 */
	protected void stopHighlight() {
		-- fHighlight;
		if (fHighlight == 0) {
			fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, green_color, SWT.NORMAL));
			fStartOffset= -1;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.internal.ui.hover.SubstitutionTextReader#computeSubstitution(int)
	 */
	protected String computeSubstitution(int c) throws IOException {
		if (c == '<')
			return  processTag();
		else if (c == '&')
			return processEntity();

		return null;
	}

	/** To formatted text
	 * @param html original text
	 * @return formatted text
	 */
	private String toText(String html) {
		if (html == null || html.length() == 0)
			return EMPTY_STRING;

		String tag= html;
		boolean isClosing = false;
		if (tag.charAt(0) == IIconHoverTag.CLOSED_TAG) {
			tag= tag.substring(1);
			isClosing = true;
		}
		if (!fgTags.contains(tag)) {
			return EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.INDENT_TAG)) {
			return "\t" + EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.NEXT_LINE_TAG)) {
			return LINE_DELIM;
		}

		if (tag.equals(IIconHoverTag.BOLD_TAG)) {
			if (isClosing)
				stopBold();
			else
				startBold();

			return EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.UNDERLINE_TAG)) {
			if (isClosing)
				stopUnderLine();
			else
				startUnderLine();

			return EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.STRIKE_TAG)) {
			if (isClosing)
				stopStrike();
			else
				startStrike();

			return EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.ITALIC_TAG)) {
			if (isClosing)
				stopItalic();
			else
				startItalic();

			return EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.KEY_TAG)) {
			if (isClosing)
				stopKey();
			else
				startKey();

			return EMPTY_STRING;
		}

		if (tag.equals(IIconHoverTag.HIGHLIGHT_TAG)) {
			if (isClosing)
				stopHighlight();
			else
				startHighlight();

			return EMPTY_STRING;
		}
		
		if (tag.equals(IIconHoverTag.P_TAG)) {
			if (isClosing) {
				boolean inParagraph= fInParagraph;
				fInParagraph= false;
				return inParagraph ? EMPTY_STRING : LINE_DELIM;
			}
			else {
				fInParagraph= true;
				return LINE_DELIM;
			}
		}
		return EMPTY_STRING;
	}

	/** Get process tag
	 * @return
	 * @throws IOException
	 */
	private String processTag() throws IOException {
		StringBuffer buf= new StringBuffer();
		int ch= nextChar();
		while (ch != -1 && ch != IIconHoverTag.END_TAG) {
			buf.append(Character.toLowerCase((char) ch));
			ch= nextChar();
			if (ch == '"'){
				buf.append(Character.toLowerCase((char) ch));
				ch= nextChar();
				while (ch != -1 && ch != '"'){
					buf.append(Character.toLowerCase((char) ch));
					ch= nextChar();
				}
			}
			if (ch == IIconHoverTag.START_TAG){
				unread(ch);
				return IIconHoverTag.START_TAG + buf.toString();
			}
		}
		if (ch == -1)
			return null;
			
		return toText(buf.toString());
	}

	/** unread
	 * @param ch
	 * @throws IOException
	 */
	private void unread(int ch) throws IOException {
		((PushbackReader) getReader()).unread(ch);
	}

	/** entity to text
	 * @param symbol
	 * @return
	 */
	protected String entity2Text(String symbol) {
		if (symbol.length() > 1 && symbol.charAt(0) == '#') {
			int ch;
			try {
				if (symbol.charAt(1) == 'x') {
					ch= Integer.parseInt(symbol.substring(2), 16);
				} else {
					ch= Integer.parseInt(symbol.substring(1), 10);
				}
				return EMPTY_STRING + (char)ch;
			} catch (NumberFormatException e) {
			}
		} else {
			String str= (String) fgEntityLookup.get(symbol);
			if (str != null) {
				return str;
			}
		}
		return "&" + symbol; // not found
	}

	/** Get process entity
	 * @return
	 * @throws IOException
	 */
	private String processEntity() throws IOException {
		StringBuffer buf= new StringBuffer();
		int ch= nextChar();
		while (Character.isLetterOrDigit((char)ch) || ch == '#') {
			buf.append((char) ch);
			ch= nextChar();
		}

		if (ch == ';')
			return entity2Text(buf.toString());

		buf.insert(0, '&');
		if (ch != -1)
			buf.append((char) ch);
		return buf.toString();
	}
}
