/*******************************************************************************
 * Copyright (c) 2000, 2008 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
 *******************************************************************************/
package org.eclipse.ant.internal.ui.editor.text;

import java.util.Iterator;
import java.util.StringTokenizer;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.AbstractFileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PatternSet;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.ant.internal.ui.debug.model.AntProperty;
import org.eclipse.ant.internal.ui.debug.model.AntStackFrame;
import org.eclipse.ant.internal.ui.debug.model.AntValue;
import org.eclipse.ant.internal.ui.editor.AntEditor;
import org.eclipse.ant.internal.ui.editor.AntEditorSourceViewerConfiguration;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntPropertyNode;
import org.eclipse.ant.internal.ui.model.IAntModel;

import org.eclipse.core.runtime.IAdaptable;

import org.eclipse.jface.internal.text.html.HTMLPrinter;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextHoverExtension;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;

import org.eclipse.ui.editors.text.EditorsUI;

import org.eclipse.debug.ui.DebugUITools;


public class XMLTextHover implements ITextHover, ITextHoverExtension, IInformationProviderExtension2 {

	private AntEditor fEditor;
	
	public XMLTextHover(AntEditor editor) {
		super();
		fEditor = editor;
	}
	
	/*
	 * Formats a message as HTML text.
	 * Expects the message to already be properly escaped
	 */
	private String formatMessage(String message) {
		StringBuffer buffer= new StringBuffer();
		HTMLPrinter.addPageProlog(buffer);
		HTMLPrinter.addParagraph(buffer, message);
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}
	
	/*
	 * Formats a message as HTML text.
	 */
	private String formatPathMessage(String[] list) {
		StringBuffer buffer= new StringBuffer();
		HTMLPrinter.addPageProlog(buffer);
		HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_4);
		HTMLPrinter.startBulletList(buffer);
		for (int i = 0; i < list.length; i++) {
			HTMLPrinter.addBullet(buffer, list[i]);
		}
		HTMLPrinter.endBulletList(buffer);
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
	 */
	public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
		
		if (!(textViewer instanceof ISourceViewer)) {
			return null;
		}
		
		ISourceViewer sourceViewer= (ISourceViewer) textViewer;
		IAnnotationModel model= sourceViewer.getAnnotationModel();
		
		if (model != null) {
			String message= getAnnotationModelHoverMessage(model, hoverRegion);
			if (message != null) {
				return message;
			}
		}
        
		AntModel antModel= fEditor.getAntModel();
		if (antModel == null) { //the ant model has not been created yet
			return null;
		}
		
		return getAntModelHoverMessage(antModel, hoverRegion, textViewer);
		
	}
	
	private String getAntModelHoverMessage(AntModel antModel, IRegion hoverRegion, ITextViewer textViewer){
		try {
			IDocument document= textViewer.getDocument();
			int offset= hoverRegion.getOffset();
			int length= hoverRegion.getLength();
			String text= document.get(offset, length);
			String value;
			AntElementNode node= antModel.getNode(offset, false);
			if (document.get(offset - 2, 2).equals("${") || node instanceof AntPropertyNode) { //$NON-NLS-1$
                AntStackFrame frame= getFrame();
                if (frame != null) {//active Ant debug session
                    AntProperty property= frame.findProperty(text);
                    if (property != null) {
                        return ((AntValue)property.getValue()).getValueString();
                    }
                }
				value= antModel.getPropertyValue(text);
				if (value != null) {
					return formatMessage(HTMLPrinter.convertToHTMLContent(value));
				}
			}
			value= antModel.getTargetDescription(text);
			if (value != null) {
				return formatMessage(HTMLPrinter.convertToHTMLContent(value));
			}
			Object referencedObject= antModel.getReferenceObject(text);
			if (referencedObject != null) {
				if (referencedObject instanceof Path) {
					return formatPathMessage(((Path)referencedObject).list());
				} else if (referencedObject instanceof PatternSet) {
					return formatPatternSetMessage((PatternSet) referencedObject);
				} else if (referencedObject instanceof AbstractFileSet) {
					return formatFileSetMessage((AbstractFileSet)referencedObject);
				}
			}
		} catch (BadLocationException e) {
		} catch (BuildException be) {
			return be.getMessage();
		}
		
		return null;
	}
	
	private String getAnnotationModelHoverMessage(IAnnotationModel model, IRegion hoverRegion) {
		Iterator e= model.getAnnotationIterator();
		while (e.hasNext()) {
			Annotation a= (Annotation) e.next();
			if (a instanceof XMLProblemAnnotation) {
				Position p= model.getPosition(a);
				if (p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
					String msg= a.getText();
					if (msg != null && msg.trim().length() > 0) {
						return formatMessage(msg);
					}
				}
			}
		}
		return null;
	}
	
	private String formatFileSetMessage(AbstractFileSet set) {
		FileScanner fileScanner= new FileScanner();
		IAntModel antModel= fEditor.getAntModel();
		Project project= antModel.getProjectNode().getProject();
		set.setupDirectoryScanner(fileScanner, project);
		String[] excludedPatterns= fileScanner.getExcludesPatterns();
		String[] includesPatterns= fileScanner.getIncludePatterns();
		return formatSetMessage(includesPatterns, excludedPatterns);
	}

	private String formatPatternSetMessage(PatternSet set) {
		IAntModel antModel= fEditor.getAntModel();
		Project project= antModel.getProjectNode().getProject();
		String[] includes= set.getIncludePatterns(project);
		String[] excludes= set.getExcludePatterns(project);
		return formatSetMessage(includes, excludes);
	}

	private String formatSetMessage(String[] includes, String[] excludes) {
		StringBuffer buffer= new StringBuffer();
		HTMLPrinter.addPageProlog(buffer);
		if (includes != null && includes.length > 0) {
			HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_5);
			for (int i = 0; i < includes.length; i++) {
				HTMLPrinter.addBullet(buffer, includes[i]);
			}
		}
		HTMLPrinter.addParagraph(buffer, ""); //$NON-NLS-1$
		HTMLPrinter.addParagraph(buffer, ""); //$NON-NLS-1$
		if (excludes != null && excludes.length > 0) {
			HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_6);
			for (int i = 0; i < excludes.length; i++) {
				HTMLPrinter.addBullet(buffer, excludes[i]);
			}
		}
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
	 */
	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
		if (textViewer != null) {
			return getRegion(textViewer, offset);
		}
		return null;
	}

	public static IRegion getRegion(ITextViewer textViewer, int offset) {
		IDocument document= textViewer.getDocument();
		
		int start= -1;
		int end= -1;
	    IRegion region= null;
		try {
			int pos= offset;
			char c;
            
            if (document.getChar(pos) == '"') {
                pos--;
            }
			while (pos >= 0) {
				c= document.getChar(pos);
				if (c != '.' && c != '-' && c != '/' &&  c != '\\' && c != ' ' && c != ')' && c != '('&& c != ':' && !Character.isJavaIdentifierPart(c) && pos != offset)
					break;
				--pos;
			}
			
			start= pos;
			
			pos= offset;
			int length= document.getLength();
			
			while (pos < length) {
				c= document.getChar(pos);
				if (c != '.' && c != '-' && c != '/' &&  c != '\\' && c != ' ' && c != ')' && c != '('&& c != ':' && !Character.isJavaIdentifierPart(c))
					break;
                if (c == '/' && (document.getLength() - 1) > (pos + 1) && document.getChar(pos + 1) == '>') {
                   //e.g. <name/>
                    break;
                }
				++pos;
			}
			
			end= pos;
			
		} catch (BadLocationException x) {
		}
		
		if (start > -1 && end > -1) {
			if (start == offset && end == offset) {
				return new Region(offset, 0);
			} else if (start == offset) {
				return new Region(start, end - start);
			} else {
                try { //correct for spaces at beginning or end
                    while(document.getChar(start + 1) == ' ') {
                        start++;
                    }
                    while(document.getChar(end - 1) == ' ') {
                        end--;
                    }
                } catch (BadLocationException e) {
                }
                region= new Region(start + 1, end - start - 1);
            }
        }
        
        if (region != null) {
            try {
                char c= document.getChar(region.getOffset() - 1);
				if (c == '"') {
					if (document.get(offset, region.getLength()).indexOf(',') != -1) {
						region = cleanRegionForNonProperty(offset, document, region);
					}
				} else if (c != '{') {
                	region = cleanRegionForNonProperty(offset, document, region);
                }
            } catch (BadLocationException e) {
            }
        }
            
		return region;
	}

	private static IRegion cleanRegionForNonProperty(int offset, IDocument document, IRegion region) throws BadLocationException {
		//do not allow spaces in region that is not a property
		String text= document.get(region.getOffset(), region.getLength());
		if (text.startsWith("/")) { //$NON-NLS-1$
			text= text.substring(1);
			region= new Region(region.getOffset() + 1, region.getLength() - 1);
		}
		StringTokenizer tokenizer= new StringTokenizer(text, " "); //$NON-NLS-1$
		if (tokenizer.countTokens() != 1) {
		    while(tokenizer.hasMoreTokens()) {
		        String token= tokenizer.nextToken();
		        int index= text.indexOf(token);
		        if (region.getOffset() + index <= offset && region.getOffset() + index + token.length() >= offset) {
		            region= new Region(region.getOffset() + index, token.length());
		            break;
		        }
		    }
		}
		
		return region;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
	 */
	public IInformationControlCreator getHoverControlCreator() {
		return new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell parent) {
				return new DefaultInformationControl(parent, EditorsUI.getTooltipAffordanceString());
			}
		};
	}
    
    /**
     * Returns the stack frame in which to search for properties, or <code>null</code>
     * if none.
     * 
     * @return the stack frame in which to search for properties, or <code>null</code>
     * if none
     */
    private AntStackFrame getFrame() {
        IAdaptable adaptable = DebugUITools.getDebugContext();
        if (adaptable != null) {
            return (AntStackFrame)adaptable.getAdapter(AntStackFrame.class);
        }
        return null;
    }

	/*
	 * @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
	 * @since 3.3
	 */
	public IInformationControlCreator getInformationPresenterControlCreator() {
		return AntEditorSourceViewerConfiguration.getInformationPresenterControlCreator();
	}
}