/**********************************************************************
 * Copyright (c) 2002,2003 QNX Software Systems and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 *
 * Contributors:
 * QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.ui.text.makefile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.cdt.make.core.makefile.IMacroDefinition;
import org.eclipse.cdt.make.core.makefile.IMakefile;
import org.eclipse.cdt.make.core.makefile.IRule;
import org.eclipse.cdt.make.core.makefile.IDirective;
import org.eclipse.cdt.make.internal.ui.MakeUIImages;
import org.eclipse.cdt.make.internal.ui.MakeUIPlugin;
import org.eclipse.cdt.make.internal.ui.text.CompletionProposalComparator;
import org.eclipse.cdt.make.internal.ui.text.WordPartDetector;
import org.eclipse.cdt.make.ui.IWorkingCopyManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ContextInformation;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorPart;

/**
 * MakefileCompletionProcessor
 */
public class MakefileCompletionProcessor implements IContentAssistProcessor {

	/**
	 * Simple content assist tip closer. The tip is valid in a range
	 * of 5 characters around its popup location.
	 */
	protected static class Validator implements IContextInformationValidator, IContextInformationPresenter {

		protected int fInstallOffset;

		/*
		 * @see IContextInformationValidator#isContextInformationValid(int)
		 */
		public boolean isContextInformationValid(int offset) {
			return Math.abs(fInstallOffset - offset) < 5;
		}

		/*
		 * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
		 */
		public void install(IContextInformation info, ITextViewer viewer, int offset) {
			fInstallOffset = offset;
		}

		/*
		 * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int, TextPresentation)
		 */
		public boolean updatePresentation(int documentPosition, TextPresentation presentation) {
			return false;
		}
	}

	public class DirectiveComparator implements Comparator {

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			String name1;
			String name2;

			if (o1 instanceof IMacroDefinition) {
				name1 = ((IMacroDefinition)o1).getName();
			} else if (o1 instanceof IRule) {
				name1 = ((IRule)o1).getTarget().toString();
			} else {
				name1 ="";
			}

			if (o2 instanceof IMacroDefinition) {
				name2 = ((IMacroDefinition)o1).getName();
			} else if (o2 instanceof IRule) {
				name2 = ((IRule)o1).getTarget().toString();
			} else {
				name2 ="";
			}

			//return String.CASE_INSENSITIVE_ORDER.compare(name1, name2);
			return name1.compareToIgnoreCase(name2);
		}
		
	}
	protected IContextInformationValidator fValidator = new Validator();
	protected Image imageMacro = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_MACRO);
	protected Image imageTarget = MakeUIImages.getImage(MakeUIImages.IMG_OBJS_MAKEFILE_TARGET_RULE);

	protected CompletionProposalComparator comparator = new CompletionProposalComparator();
	protected IEditorPart fEditor;
	protected IWorkingCopyManager fManager;

	public MakefileCompletionProcessor(IEditorPart editor) {
		fEditor = editor;
		fManager =  MakeUIPlugin.getDefault().getWorkingCopyManager();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
	 */
	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
		boolean macro = inMacro(viewer, documentOffset);
		IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput());
		IDirective[] statements = null;
		if (macro) {
			IDirective[] m1 = makefile.getMacroDefinitions();
			IDirective[] m2 = makefile.getBuiltinMacroDefinitions();
			statements = new IDirective[m1.length + m2.length];
			System.arraycopy(m1, 0, statements, 0, m1.length);
			System.arraycopy(m2, 0, statements, m1.length, m2.length);
		} else {
			statements = makefile.getTargetRules();
		}

		ArrayList proposalList = new ArrayList(statements.length);
		WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset);

		// iterate over all the different categories
		for (int i = 0; i < statements.length; i++) {
			String name = null;
			Image image = null;
			String infoString = "";//getContentInfoString(name);
			if (statements[i] instanceof IMacroDefinition) {
				name = ((IMacroDefinition) statements[i]).getName();
				image = imageMacro;
				infoString = ((IMacroDefinition)statements[i]).getValue().toString();
			} else if (statements[i] instanceof IRule) {
				name = ((IRule) statements[i]).getTarget().toString();
				image = imageTarget;
				infoString = name;
			}
			if (name != null && name.startsWith(wordPart.getString())) {
				IContextInformation info = new ContextInformation(name, infoString);
				String displayString = (name.equals(infoString) ? name : name + " - " + infoString);
				ICompletionProposal result =
					new CompletionProposal(
						name,
						wordPart.getOffset(),
						wordPart.getString().length(),
						name.length(),
						image,
						displayString,
						info,
						infoString);
				proposalList.add(result);
			}
		}
		ICompletionProposal[] proposals = (ICompletionProposal[]) proposalList.toArray(new ICompletionProposal[0]);
		Arrays.sort(proposals, comparator);
		return proposals;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
	 */
	public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
		WordPartDetector wordPart = new WordPartDetector(viewer, documentOffset);
		boolean macro = inMacro(viewer, documentOffset);
		IMakefile makefile = fManager.getWorkingCopy(fEditor.getEditorInput());
		ArrayList contextList = new ArrayList();
		if (macro) {
			IDirective[] statements = makefile.getMacroDefinitions();
			for (int i = 0; i < statements.length; i++) {
				if (statements[i] instanceof IMacroDefinition) {
					String name = ((IMacroDefinition) statements[i]).getName();
					if (name != null && name.equals(wordPart.getString())) {
						String value = ((IMacroDefinition) statements[i]).getValue().toString();
						if (value != null && value.length() > 0) {
							contextList.add(value);
						}
					}
				}
			}
			statements = makefile.getBuiltinMacroDefinitions();
			for (int i = 0; i < statements.length; i++) {
				if (statements[i] instanceof IMacroDefinition) {
					String name = ((IMacroDefinition) statements[i]).getName();
					if (name != null && name.equals(wordPart.getString())) {
						String value = ((IMacroDefinition) statements[i]).getValue().toString();
						if (value != null && value.length() > 0) {
							contextList.add(value);
						}
					}
				}
			}
		}

		IContextInformation[] result = new IContextInformation[contextList.size()];
		for (int i = 0; i < result.length; i++) {
			String context = (String)contextList.get(i);
			result[i] = new ContextInformation(imageMacro, wordPart.getString(), context);
		}
		return result;

	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
	 */
	public char[] getCompletionProposalAutoActivationCharacters() {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
	 */
	public char[] getContextInformationAutoActivationCharacters() {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
	 */
	public String getErrorMessage() {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
	 */
	public IContextInformationValidator getContextInformationValidator() {
		return fValidator;
	}

	private boolean inMacro(ITextViewer viewer, int offset) {
		boolean isMacro = false;
		IDocument document = viewer.getDocument();
		// Try to figure out if we are in a Macro.
		try {
			for (int index = offset - 1; index >= 0; index--) {
				char c;
				c = document.getChar(index);
				if (c == '$') {
					isMacro = true;
					break;
				} else if (Character.isWhitespace(c)) {
					break;
				}
			}
		} catch (BadLocationException e) {
		}
		return isMacro;
	}

}
